Skip to content

Commit

Permalink
sample for custom filter
Browse files Browse the repository at this point in the history
  • Loading branch information
erincatto committed May 29, 2024
1 parent 69b9f55 commit 2a4192a
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 13 deletions.
6 changes: 3 additions & 3 deletions samples/car.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ void Car::Spawn(b2WorldId worldId, b2Vec2 position, float scale, float hertz,

for (int i = 0; i < 6; ++i)
{
vertices[i].x *= scale;
vertices[i].y *= scale;
vertices[i].x *= 0.85f * scale;
vertices[i].y *= 0.85f * scale;
}

b2Hull hull = b2ComputeHull(vertices, 6);
b2Polygon chassis = b2MakePolygon(&hull, 0.0f);
b2Polygon chassis = b2MakePolygon(&hull, 0.15f * scale);

b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.density = 1.0f / scale;
Expand Down
4 changes: 2 additions & 2 deletions samples/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1451,9 +1451,9 @@ void Draw::DrawString(int x, int y, const char* string, ...)
va_end(arg);
}

void Draw::DrawString(b2Vec2 pw, const char* string, ...)
void Draw::DrawString(b2Vec2 p, const char* string, ...)
{
b2Vec2 ps = g_camera.ConvertWorldToScreen(pw);
b2Vec2 ps = g_camera.ConvertWorldToScreen(p);

va_list arg;
va_start(arg, string);
Expand Down
13 changes: 7 additions & 6 deletions samples/sample_continuous.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,11 +669,12 @@ class GhostCollision : public Sample

static int sampleGhostCollision = RegisterSample("Continuous", "Ghost Collision", GhostCollision::Create);

// Speculative collision failure case suggested by Dirk Gregorius
class SpeculativeFail : public Sample
// Speculative collision failure case suggested by Dirk Gregorius. This uses
// a simple fallback scheme to prevent tunneling.
class SpeculativeFallback : public Sample
{
public:
explicit SpeculativeFail(Settings& settings)
explicit SpeculativeFallback(Settings& settings)
: Sample(settings)
{
if (settings.restart == false)
Expand Down Expand Up @@ -701,7 +702,7 @@ class SpeculativeFail : public Sample
float offset = 8.0f;
b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_dynamicBody;
bodyDef.position = {offset, 8.0f};
bodyDef.position = {offset, 12.0f};
bodyDef.linearVelocity = {0.0f, -100.0f};
b2BodyId bodyId = b2CreateBody(m_worldId, &bodyDef);

Expand All @@ -713,11 +714,11 @@ class SpeculativeFail : public Sample

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

static int sampleSpeculativeFail = RegisterSample("Continuous", "Speculative Fail", SpeculativeFail::Create);
static int sampleSpeculativeFallback = RegisterSample("Continuous", "Speculative Fallback", SpeculativeFallback::Create);

// This shows a fast moving body that uses continuous collision versus static and dynamic bodies.
// This is achieved by setting the ball body as a *bullet*.
Expand Down
2 changes: 1 addition & 1 deletion samples/sample_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ class ContactEvent : public Sample
bodyDef.gravityScale = 0.0f;
bodyDef.linearDamping = 0.5f;
bodyDef.angularDamping = 0.5f;
bodyDef.isBullet = true;
m_playerId = b2CreateBody(m_worldId, &bodyDef);

b2Circle circle = {{0.0f, 0.0f}, 1.0f};
Expand Down Expand Up @@ -1012,7 +1013,6 @@ class BodyMove : public Sample
ImGui::End();
}


void Step(Settings& settings) override
{
if (settings.pause == false && (m_stepCount & 15) == 15 && m_count < e_count)
Expand Down
95 changes: 95 additions & 0 deletions samples/sample_shapes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,101 @@ class ShapeFilter : public Sample

static int sampleShapeFilter = RegisterSample("Shapes", "Filter", ShapeFilter::Create);

// This shows how to use custom filtering
class CustomFilter : public Sample
{
public:
enum
{
e_count = 10
};

explicit CustomFilter(Settings& settings)
: Sample(settings)
{
if (settings.restart == false)
{
g_camera.m_center = {0.0f, 5.0f};
g_camera.m_zoom = 10.0f;
}

// Register custom filter
b2World_SetCustomFilterCallback(m_worldId, CustomFilterStatic, this);

{
b2BodyDef bodyDef = b2DefaultBodyDef();
b2BodyId groundId = b2CreateBody(m_worldId, &bodyDef);
b2Segment segment = {{-40.0f, 0.0f}, {40.0f, 0.0f}};

b2ShapeDef shapeDef = b2DefaultShapeDef();

b2CreateSegmentShape(groundId, &shapeDef, &segment);
}

b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_dynamicBody;
b2ShapeDef shapeDef = b2DefaultShapeDef();
b2Polygon box = b2MakeSquare(1.0f);
float x = -e_count;

for (int i = 0; i < e_count; ++i)
{
bodyDef.position = {x, 5.0f};
m_bodyIds[i] = b2CreateBody(m_worldId, &bodyDef);

shapeDef.userData = reinterpret_cast<void*>(intptr_t(i + 1));
m_shapeIds[i] = b2CreatePolygonShape(m_bodyIds[i], &shapeDef, &box);
x += 2.0f;
}
}

void Step(Settings& settings) override
{
g_draw.DrawString(5, m_textLine, "Custom filter disables collision between odd and even shapes");
m_textLine += m_textIncrement;

Sample::Step(settings);

for (int i = 0; i < e_count; ++i)
{
b2Vec2 p = b2Body_GetPosition(m_bodyIds[i]);
g_draw.DrawString({p.x, p.y}, "%d", i);
}
}

bool ShouldCollide(b2ShapeId shapeIdA, b2ShapeId shapeIdB)
{
void* userDataA = b2Shape_GetUserData(shapeIdA);
void* userDataB = b2Shape_GetUserData(shapeIdB);

if (userDataA == NULL || userDataB == NULL)
{
return true;
}

int indexA = reinterpret_cast<intptr_t>(userDataA);
int indexB = reinterpret_cast<intptr_t>(userDataB);

return ((indexA & 1) + (indexB & 1)) != 1;
}

static bool CustomFilterStatic(b2ShapeId shapeIdA, b2ShapeId shapeIdB, void* context)
{
CustomFilter* customFilter = static_cast<CustomFilter*>(context);
return customFilter->ShouldCollide(shapeIdA, shapeIdB);
}

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

b2BodyId m_bodyIds[e_count];
b2ShapeId m_shapeIds[e_count];
};

static int sampleCustomFilter = RegisterSample("Shapes", "Custom Filter", CustomFilter::Create);

// Restitution is approximate since Box2D uses speculative collision
class Restitution : public Sample
{
Expand Down
2 changes: 1 addition & 1 deletion samples/sample_world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class LargeWorld : public Sample
for (int i = 0; i < 5; ++i)
{
Donut donut;
donut.Spawn(m_worldId, position, 0.75f, donutIndex + 1, NULL);
donut.Spawn(m_worldId, position, 0.75f, 0, NULL);
donutIndex += 1;
position.x += 2.0f;
}
Expand Down

0 comments on commit 2a4192a

Please sign in to comment.