Skip to content

Commit

Permalink
Misc Issues (#783)
Browse files Browse the repository at this point in the history
- renamed smooth segment to chain segment
- addressed several minor issues

#777
#779
#754 
#749 
#782 
#781 
#776
  • Loading branch information
erincatto authored Aug 31, 2024
1 parent 9314f30 commit 5fdbbc8
Show file tree
Hide file tree
Showing 19 changed files with 202 additions and 160 deletions.
8 changes: 7 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
cmake_dependent_option(BOX2D_AVX2 "Enable AVX2" OFF "BOX2D_ENABLE_SIMD" OFF)
endif()


if(PROJECT_IS_TOP_LEVEL)
# Needed for samples.exe to find box2d.dll
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
Expand All @@ -67,6 +66,13 @@ if(PROJECT_IS_TOP_LEVEL)
option(BOX2D_VALIDATE "Enable heavy validation" ON)
option(BOX2D_UNIT_TESTS "Build the Box2D unit tests" ON)

include(GNUInstallDirs)

install(
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/box2d"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

if(MSVC AND WIN32)
# Enable edit and continue only in debug due to perf hit in release
# add_link_options($<$<CONFIG:Debug>:/INCREMENTAL>)
Expand Down
18 changes: 9 additions & 9 deletions docs/collision.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ If edge1 did not exist this collision would seem fine. With edge1
present, the internal collision seems like a bug. But normally when
Box2D collides two shapes, it views them in isolation.
`b2SmoothSegment` provides a mechanism for eliminating ghost
`b2ChainSegment` provides a mechanism for eliminating ghost
collisions by storing the adjacent *ghost* vertices. Box2D uses these
ghost vertices to prevent internal collisions.
Expand All @@ -171,21 +171,21 @@ one-sided collision. The front face is to the right when looking from the first
vertex towards the second vertex. This matches the counter-clockwise winding order
used by polygons.
### Smooth segment
Smooth segments use a concept called *ghost vertices* that Box2D can use to eliminate ghost
### Chain segment
Chain segments use a concept called *ghost vertices* that Box2D can use to eliminate ghost
collisions.
```c
b2SmoothSegment smoothSegment = {0};
smoothSegment.ghost1 = (b2Vec2){1.7f, 0.0f};
smoothSegment.segment = (b2Segment){{1.0f, 0.25f}, {0.0f, 0.0f}};
smoothSegment.ghost2 = (b2Vec2){-1.7f, 0.4f};
b2ChainSegment chainSegment = {0};
chainSegment.ghost1 = (b2Vec2){1.7f, 0.0f};
chainSegment.segment = (b2Segment){{1.0f, 0.25f}, {0.0f, 0.0f}};
chainSegment.ghost2 = (b2Vec2){-1.7f, 0.4f};
```

These ghost vertices must align with vertices of neighboring smooth segments, making them
These ghost vertices must align with vertices of neighboring chain segments, making them
tedious and error-prone to setup.

Smooth segments are not created directly. Instead, you can create chains of smooth
Chain segments are not created directly. Instead, you can create chains of line
segments. See `b2ChainDef` and `b2CreateChain()`.

## Geometric Queries
Expand Down
4 changes: 2 additions & 2 deletions docs/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ chainDef.loop = true;
b2ChainId chainId = b2CreateChain(bodyId, &chainDef);
```

Since chains are their own concept now, they get their own identifier, `b2ChainId`. You can view chains as macro objects, they create many `b2SmoothSegment` shapes internally. Normally you don't interact with these. However they are returned from queries. You can use `b2Shape_GetParentChain()` to get the `b2ChainId` for a smooth segment that you get from a query.
Since chains are their own concept now, they get their own identifier, `b2ChainId`. You can view chains as macro objects, they create many `b2ChainSegment` shapes internally. Normally you don't interact with these. However they are returned from queries. You can use `b2Shape_GetParentChain()` to get the `b2ChainId` for a chain segment that you get from a query.

> DO NOT destroy or modify a `b2SmoothSegment` that belongs to a chain shape directly
> DO NOT destroy or modify a `b2ChainSegment` that belongs to a chain shape directly
### Creating a joint
Joints are very similar in v3.0. The lack of C member functions changes initialization.
Expand Down
24 changes: 11 additions & 13 deletions docs/simulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -860,16 +860,15 @@ problems. Make sure all your points are more than than about a centimeter apart.
![Self Intersection is Bad](images/self_intersect.svg)
Each segment in the chain is created as a `b2SmoothSegment` shape on the body. If you have the
shape id for a smooth segment shape, you can get the owning chain id. This will return `b2_nullChainId`
if the shape is not a smooth segment.
Each segment in the chain is created as a `b2ChainSegment` shape on the body. If you have the
shape id for a chain segment shape, you can get the owning chain id. This will return `b2_nullChainId`
if the shape is not a chain segment.
```c
b2ChainId chainId = b2SHape_GetParentChain(myShapeId);
```

You cannot create a smooth segment shape directly.

You cannot create a chain segment shape directly.

### Sensors
Sometimes game logic needs to know when two shapes overlap yet there
Expand Down Expand Up @@ -1181,7 +1180,7 @@ or disable a joint.
You can specify user data for any joint type and you can provide a flag
to prevent the attached bodies from colliding with each other. This is
the default behavior and you must set the `collideConnected`
Boolean to allow collision between to connected bodies.
Boolean to allow collision between two connected bodies.

Many joint definitions require that you provide some geometric data.
Often a joint will be defined by anchor points. These are points fixed
Expand Down Expand Up @@ -1493,13 +1492,6 @@ when multiple dynamic bodies interact. You can make this as large as you
like. The frequency and damping ratio are used to create a spring/damper
effect similar to the distance joint.
### Wheel Joint
The wheel joint restricts a point on bodyB to a line on bodyA. The wheel
joint also provides a suspension spring and a motor. See the `Driving` sample
for details.
![Wheel Joint](images/wheel_joint.svg)
### Weld Joint
The weld joint attempts to constrain all relative motion between two
bodies. See the `Cantilever` sample to see how the weld joint
Expand All @@ -1522,6 +1514,12 @@ proportional the maximum motor force and torque. See `b2MotorJointDef` and
the `MotorJoint` sample for details.
### Wheel Joint
The wheel joint restricts a point on bodyB to a line on bodyA. The wheel
joint also provides a suspension spring and a motor. See the `Driving` sample
for details.
![Wheel Joint](images/wheel_joint.svg)
The wheel joint is designed specifically for vehicles. It provides a translation
and rotation. The translation has a spring and damper to simulate the vehicle
suspension. The rotation allows the wheel to rotate. You can specify an rotational
Expand Down
6 changes: 3 additions & 3 deletions include/box2d/box2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,9 +529,9 @@ B2_API b2Circle b2Shape_GetCircle( b2ShapeId shapeId );
/// Get a copy of the shape's line segment. Asserts the type is correct.
B2_API b2Segment b2Shape_GetSegment( b2ShapeId shapeId );

/// Get a copy of the shape's smooth line segment. These come from chain shapes.
/// Get a copy of the shape's chain segment. These come from chain shapes.
/// Asserts the type is correct.
B2_API b2SmoothSegment b2Shape_GetSmoothSegment( b2ShapeId shapeId );
B2_API b2ChainSegment b2Shape_GetChainSegment( b2ShapeId shapeId );

/// Get a copy of the shape's capsule. Asserts the type is correct.
B2_API b2Capsule b2Shape_GetCapsule( b2ShapeId shapeId );
Expand All @@ -557,7 +557,7 @@ B2_API void b2Shape_SetSegment( b2ShapeId shapeId, const b2Segment* segment );
/// @see b2Body_ApplyMassFromShapes
B2_API void b2Shape_SetPolygon( b2ShapeId shapeId, const b2Polygon* polygon );

/// Get the parent chain id if the shape type is b2_smoothSegmentShape, otherwise
/// Get the parent chain id if the shape type is a chain segment, otherwise
/// returns b2_nullChainId.
B2_API b2ChainId b2Shape_GetParentChain( b2ShapeId shapeId );

Expand Down
20 changes: 10 additions & 10 deletions include/box2d/collision.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ typedef struct b2Capsule b2Capsule;
typedef struct b2DistanceCache b2DistanceCache;
typedef struct b2Polygon b2Polygon;
typedef struct b2Segment b2Segment;
typedef struct b2SmoothSegment b2SmoothSegment;
typedef struct b2ChainSegment b2ChainSegment;

typedef struct b2Hull b2Hull;

Expand Down Expand Up @@ -153,10 +153,10 @@ typedef struct b2Segment
b2Vec2 point2;
} b2Segment;

/// A smooth line segment with one-sided collision. Only collides on the right side.
/// A line segment with one-sided collision. Only collides on the right side.
/// Several of these are generated for a chain shape.
/// ghost1 -> point1 -> point2 -> ghost2
typedef struct b2SmoothSegment
typedef struct b2ChainSegment
{
/// The tail ghost vertex
b2Vec2 ghost1;
Expand All @@ -169,7 +169,7 @@ typedef struct b2SmoothSegment

/// The owning chain shape index (internal usage only)
int32_t chainId;
} b2SmoothSegment;
} b2ChainSegment;

/// Validate ray cast input data (NaN, etc)
B2_API bool b2IsValidRay( const b2RayCastInput* input );
Expand Down Expand Up @@ -554,16 +554,16 @@ B2_API b2Manifold b2CollidePolygons( const b2Polygon* polygonA, b2Transform xfA,
B2_API b2Manifold b2CollideSegmentAndPolygon( const b2Segment* segmentA, b2Transform xfA, const b2Polygon* polygonB,
b2Transform xfB );

/// Compute the contact manifold between a smooth segment and a circle
B2_API b2Manifold b2CollideSmoothSegmentAndCircle( const b2SmoothSegment* smoothSegmentA, b2Transform xfA,
/// Compute the contact manifold between a chain segment and a circle
B2_API b2Manifold b2CollideChainSegmentAndCircle( const b2ChainSegment* segmentA, b2Transform xfA,
const b2Circle* circleB, b2Transform xfB );

/// Compute the contact manifold between an segment and a capsule
B2_API b2Manifold b2CollideSmoothSegmentAndCapsule( const b2SmoothSegment* smoothSegmentA, b2Transform xfA,
/// Compute the contact manifold between a chain segment and a capsule
B2_API b2Manifold b2CollideChainSegmentAndCapsule( const b2ChainSegment* segmentA, b2Transform xfA,
const b2Capsule* capsuleB, b2Transform xfB, b2DistanceCache* cache );

/// Compute the contact manifold between a smooth segment and a rounded polygon
B2_API b2Manifold b2CollideSmoothSegmentAndPolygon( const b2SmoothSegment* smoothSegmentA, b2Transform xfA,
/// Compute the contact manifold between a chain segment and a rounded polygon
B2_API b2Manifold b2CollideChainSegmentAndPolygon( const b2ChainSegment* segmentA, b2Transform xfA,
const b2Polygon* polygonB, b2Transform xfB, b2DistanceCache* cache );

/**@}*/
Expand Down
8 changes: 4 additions & 4 deletions include/box2d/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,8 @@ typedef enum b2ShapeType
/// A convex polygon
b2_polygonShape,

/// A smooth segment owned by a chain shape
b2_smoothSegmentShape,
/// A line segment owned by a chain shape
b2_chainSegmentShape,

/// The number of shape types
b2_shapeTypeCount
Expand Down Expand Up @@ -356,7 +356,7 @@ typedef struct b2ShapeDef
/// @ingroup shape
B2_API b2ShapeDef b2DefaultShapeDef( void );

/// Used to create a chain of edges. This is designed to eliminate ghost collisions with some limitations.
/// Used to create a chain of line segments. This is designed to eliminate ghost collisions with some limitations.
/// - chains are one-sided
/// - chains have no mass and should be used on static bodies
/// - chains have a counter-clockwise winding order
Expand All @@ -366,7 +366,7 @@ B2_API b2ShapeDef b2DefaultShapeDef( void );
/// - a chain shape should not self intersect (this is not validated)
/// - an open chain shape has NO COLLISION on the first and final edge
/// - you may overlap two open chains on their first three and/or last three points to get smooth collision
/// - a chain shape creates multiple smooth edges shapes on the body
/// - a chain shape creates multiple line segment shapes on the body
/// https://en.wikipedia.org/wiki/Polygonal_chain
/// Must be initialized using b2DefaultChainDef().
/// @warning Do not use chain shapes unless you understand the limitations. This is an advanced feature.
Expand Down
1 change: 1 addition & 0 deletions samples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ add_library(imgui STATIC
${IMGUI_DIR}/backends/imgui_impl_glfw.cpp
${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp
)

target_link_libraries(imgui PUBLIC glfw glad)
target_include_directories(imgui PUBLIC ${IMGUI_DIR} ${IMGUI_DIR}/backends)
target_compile_definitions(imgui PUBLIC IMGUI_DISABLE_OBSOLETE_FUNCTIONS)
Expand Down
6 changes: 2 additions & 4 deletions samples/sample_bodies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ static int sampleBodyType = RegisterSample( "Bodies", "Body Type", BodyType::Cre

/// This is a test of typical character collision scenarios. This does not
/// show how you should implement a character in your application.
/// Instead this is used to test smooth collision on edge chains.
/// Instead this is used to test smooth collision on chain shapes.
class Character : public Sample
{
public:
Expand Down Expand Up @@ -347,7 +347,7 @@ class Character : public Sample

// Square tiles. This shows that adjacency shapes may have non-smooth collision. Box2D has no solution
// to this problem.
// TODO_ERIN try this: https://briansemrau.github.io/dealing-with-ghost-collisions/
// todo_erin try this: https://briansemrau.github.io/dealing-with-ghost-collisions/
{
b2BodyDef bodyDef = b2DefaultBodyDef();
b2BodyId groundId = b2CreateBody( m_worldId, &bodyDef );
Expand Down Expand Up @@ -454,8 +454,6 @@ class Character : public Sample
m_textLine += m_textIncrement;
g_draw.DrawString( 5, m_textLine, "Limitation: square and hexagon can snag on aligned boxes." );
m_textLine += m_textIncrement;
g_draw.DrawString( 5, m_textLine, "Feature: edge chains have smooth collision inside and out." );
m_textLine += m_textIncrement;
}

static Sample* Create( Settings& settings )
Expand Down
Loading

0 comments on commit 5fdbbc8

Please sign in to comment.