Skip to content

Commit

Permalink
minor fixes (#174)
Browse files Browse the repository at this point in the history
issues #168, #167, #170
pull request #169
  • Loading branch information
erincatto authored Jul 28, 2024
1 parent 069a6c7 commit b36d549
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 17 deletions.
13 changes: 7 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ if (MSVC OR APPLE)
endif()
endif()


if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
option(BOX2D_AVX2 "Enable AVX2 (faster)" ON)
endif()

# Needed for samples.exe to find box2d.dll
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
if(PROJECT_IS_TOP_LEVEL)
# Needed for samples.exe to find box2d.dll
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
endif()

# C++17 needed for imgui
set(CMAKE_CXX_STANDARD 17)
Expand All @@ -56,7 +57,7 @@ add_subdirectory(extern/simde)
add_subdirectory(src)

# This hides samples, test, and doxygen from apps that use box2d via FetchContent
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
if(PROJECT_IS_TOP_LEVEL)
option(BOX2D_SAMPLES "Build the Box2D samples" ON)
option(BOX2D_BENCHMARKS "Build the Box2D benchmarks" OFF)
option(BOX2D_DOCS "Build the Box2D documentation" OFF)
Expand Down Expand Up @@ -119,4 +120,4 @@ endif()

# # Building on clang in windows
# cmake -S .. -B . -G "Visual Studio 17 2022" -A x64 -T ClangCL
# https://clang.llvm.org/docs/UsersManual.html#clang-cl
# https://clang.llvm.org/docs/UsersManual.html#clang-cl
2 changes: 1 addition & 1 deletion docs/collision.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ This is called the *time of impact* (TOI). The main purpose of `b2TimeOfImpact()
tunnel prevention. Box2D uses this internally to prevent moving objects from tunneling through
static shapes.
The `b2TimeOfImpact()` identities an initial separating axis and
The `b2TimeOfImpact()` identifies an initial separating axis and
ensures the shapes do not cross on that axis. This process is repeated
as shapes are moved closer together, until they touch or pass by each other.
Expand Down
4 changes: 2 additions & 2 deletions docs/simulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ Restitution is combined this way so that you can have a bouncy super
ball without having a bouncy floor.

When a shape develops multiple contacts, restitution is simulated
approximately. This is because Box2D uses an sequential solver. Box2D
approximately. This is because Box2D uses a sequential solver. Box2D
also uses inelastic collisions when the collision velocity is small.
This is done to prevent jitter. See `b2WorldDef::restitutionThreshold`.

Expand Down Expand Up @@ -927,7 +927,7 @@ For convenience, this is stored as an impulse.
#### contact point id
Box2D tries to re-use the contact impulse results from a time step as the
initial guess for the next time step. Box2D uses contact point ids to match
contact points across time steps. The ids contain geometric features
contact points across time steps. The ids contain geometric feature
indices that help to distinguish one contact point from another.

#### speculative contact
Expand Down
80 changes: 80 additions & 0 deletions samples/sample_bodies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -759,3 +759,83 @@ class Sleep : public Sample
};

static int sampleSleep = RegisterSample("Bodies", "Sleep", Sleep::Create);

class BadBody : public Sample
{
public:
explicit BadBody(Settings& settings)
: Sample(settings)
{
if (settings.restart == false)
{
g_camera.m_center = {2.3f, 10.0f};
g_camera.m_zoom = 25.0f * 0.5f;
}

b2BodyId groundId = b2_nullBodyId;
{
b2BodyDef bodyDef = b2DefaultBodyDef();
groundId = b2CreateBody(m_worldId, &bodyDef);

b2Segment segment = {{-20.0f, 0.0f}, {20.0f, 0.0f}};
b2ShapeDef shapeDef = b2DefaultShapeDef();
b2CreateSegmentShape(groundId, &shapeDef, &segment);
}

// Build a bad body
{
b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_dynamicBody;
bodyDef.position = {0.0f, 3.0f};
bodyDef.angularVelocity = 0.2f;
bodyDef.angle = 0.25f * b2_pi;

m_badBodyId = b2CreateBody(m_worldId, &bodyDef);

b2Capsule capsule = {{0.0f, -1.0f}, {0.0f, 1.0f}, 1.0f};
b2ShapeDef shapeDef = b2DefaultShapeDef();

// density set to zero intentionally to create a bad body
shapeDef.density = 0.0f;
b2CreateCapsuleShape(m_badBodyId, &shapeDef, &capsule);
}

// Build a normal body
{
b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_dynamicBody;
bodyDef.position = {2.0f, 3.0f};
bodyDef.angle = 0.25f * b2_pi;

b2BodyId bodyId = b2CreateBody(m_worldId, &bodyDef);

b2Capsule capsule = {{0.0f, -1.0f}, {0.0f, 1.0f}, 1.0f};
b2ShapeDef shapeDef = b2DefaultShapeDef();

b2CreateCapsuleShape(bodyId, &shapeDef, &capsule);
}
}

void Step(Settings& settings) override
{
Sample::Step(settings);

g_draw.DrawString(5, m_textLine, "A bad body is a dynamic body with no mass and behaves like a kinematic body.");
m_textLine += m_textIncrement;

g_draw.DrawString(5, m_textLine, "Bad bodies are considered invalid and a user bug. Behavior is not guaranteed.");
m_textLine += m_textIncrement;

// For science
b2Body_ApplyForceToCenter(m_badBodyId, {0.0f, 10.0f}, true);
}

static Sample* Create(Settings& settings)
{
return new BadBody(settings);
}

b2BodyId m_badBodyId;
};

static int sampleBadBody = RegisterSample("Bodies", "Bad", BadBody::Create);
20 changes: 12 additions & 8 deletions src/body.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,34 +761,38 @@ void b2Body_SetLinearVelocity(b2BodyId bodyId, b2Vec2 linearVelocity)
{
b2World* world = b2GetWorld(bodyId.world0);
b2Body* body = b2GetBodyFullId(world, bodyId);

if (b2LengthSquared(linearVelocity) > 0.0f)
{
b2WakeBody(world, body);
}

b2BodyState* state = b2GetBodyState(world, body);
if (state == NULL)
{
return;
}

state->linearVelocity = linearVelocity;
if (b2LengthSquared(linearVelocity) > 0.0f)
{
b2WakeBody(world, body);
}
}

void b2Body_SetAngularVelocity(b2BodyId bodyId, float angularVelocity)
{
b2World* world = b2GetWorld(bodyId.world0);
b2Body* body = b2GetBodyFullId(world, bodyId);

if (angularVelocity != 0.0f)
{
b2WakeBody(world, body);
}

b2BodyState* state = b2GetBodyState(world, body);
if (state == NULL)
{
return;
}

state->angularVelocity = angularVelocity;
if (angularVelocity != 0.0f)
{
b2WakeBody(world, body);
}
}

void b2Body_ApplyForce(b2BodyId bodyId, b2Vec2 force, b2Vec2 point, bool wake)
Expand Down

0 comments on commit b36d549

Please sign in to comment.