Skip to content

Commit

Permalink
aabb margin experiments
Browse files Browse the repository at this point in the history
spinner benchmark
  • Loading branch information
erincatto committed Oct 14, 2024
1 parent 68a94d2 commit 577c62a
Show file tree
Hide file tree
Showing 8 changed files with 420 additions and 230 deletions.
1 change: 1 addition & 0 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_executable(benchmark
large_pyramid.c
many_pyramids.c
smash.c
spinner.c
tumbler.c
)

Expand Down
4 changes: 4 additions & 0 deletions benchmark/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extern b2WorldId JointGrid( b2WorldDef* worldDef );
extern b2WorldId LargePyramid( b2WorldDef* worldDef );
extern b2WorldId ManyPyramids( b2WorldDef* worldDef );
extern b2WorldId Smash( b2WorldDef* worldDef );
extern b2WorldId Spinner( b2WorldDef* worldDef );
extern b2WorldId Tumbler( b2WorldDef* worldDef );

typedef struct Benchmark
Expand Down Expand Up @@ -115,13 +116,16 @@ static void FinishTask( void* userTask, void* userContext )
}

// Box2D benchmark application. On Windows I recommend running this in an administrator command prompt. Don't use Windows Terminal.
// Or use affinity. [0x01 0x02 0x04 0x08 0x10 0x20 0x40 0x80]
// start /affinity 0x5555 .\build\bin\Release\benchmark.exe -t=4 -w=4
int main( int argc, char** argv )
{
Benchmark benchmarks[] = {
{ "joint_grid", JointGrid, 500 },
{ "large_pyramid", LargePyramid, 500 },
{ "many_pyramids", ManyPyramids, 200 },
{ "smash", Smash, 300 },
{ "spinner", Spinner, 1400 },
{ "tumbler", Tumbler, 750 },
};

Expand Down
112 changes: 112 additions & 0 deletions benchmark/spinner.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// SPDX-FileCopyrightText: 2024 Erin Catto
// SPDX-License-Identifier: MIT

#include "box2d/box2d.h"
#include "box2d/math_functions.h"

enum
{
e_count = 3038,
e_pointCount = 360,
};

b2WorldId Spinner( b2WorldDef* worldDef )
{
b2WorldId worldId = b2CreateWorld( worldDef );

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

b2Vec2 points[e_pointCount];

b2Rot q = b2MakeRot( -2.0f * b2_pi / e_pointCount );
b2Vec2 p = { 40.0f, 0.0f };
for ( int i = 0; i < e_pointCount; ++i )
{
points[i] = (b2Vec2){ p.x, p.y + 32.0f };
p = b2RotateVector( q, p );
}

b2ChainDef chainDef = b2DefaultChainDef();
chainDef.points = points;
chainDef.count = e_pointCount;
chainDef.isLoop = true;
chainDef.friction = 0.1f;

b2CreateChain( groundId, &chainDef );
}

{
b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_dynamicBody;
bodyDef.position = (b2Vec2){ 0.0, 12.0f };
bodyDef.enableSleep = false;

b2BodyId spinnerId = b2CreateBody( worldId, &bodyDef );

b2Polygon box = b2MakeRoundedBox( 0.4f, 20.0f, 0.2f );
b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.friction = 0.0f;
b2CreatePolygonShape( spinnerId, &shapeDef, &box );

float motorSpeed = 5.0f;
float maxMotorTorque = 40000.0f;
b2RevoluteJointDef jointDef = b2DefaultRevoluteJointDef();
jointDef.bodyIdA = groundId;
jointDef.bodyIdB = spinnerId;
jointDef.localAnchorA = bodyDef.position;
jointDef.enableMotor = true;
jointDef.motorSpeed = motorSpeed;
jointDef.maxMotorTorque = maxMotorTorque;
}

b2Capsule capsule = { { -0.25f, 0.0f }, { 0.25f, 0.0f }, 0.25f };
b2Circle circle = { { 0.0f, 0.0f }, 0.35f };
b2Polygon square = b2MakeSquare( 0.35f );

b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_dynamicBody;
b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.friction = 0.1f;
shapeDef.restitution = 0.1f;
shapeDef.density = 0.25f;

#ifdef NDEBUG
int bodyCount = e_count;
#else
int bodyCount = 499;
#endif

float x = -24.0f, y = 2.0f;
for ( int i = 0; i < bodyCount; ++i )
{
bodyDef.position = (b2Vec2){ x, y };
b2BodyId bodyId = b2CreateBody( worldId, &bodyDef );

int remainder = i % 3;
if ( remainder == 0 )
{
b2CreateCapsuleShape( bodyId, &shapeDef, &capsule );
}
else if ( remainder == 1 )
{
b2CreateCircleShape( bodyId, &shapeDef, &circle );
}
else if ( remainder == 2 )
{
b2CreatePolygonShape( bodyId, &shapeDef, &square );
}

x += 1.0f;

if ( x > 24.0f )
{
x = -24.0f;
y += 1.0f;
}
}

return worldId;
}
213 changes: 213 additions & 0 deletions samples/sample_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1975,3 +1975,216 @@ class BenchmarkCast : public Sample
};

static int sampleCast = RegisterSample( "Benchmark", "Cast", BenchmarkCast::Create );


class BenchmarkSpinner : public Sample
{
public:
enum
{
e_count = 3038,
e_pointCount = 360,
};

explicit BenchmarkSpinner( Settings& settings )
: Sample( settings )
{
if ( settings.restart == false )
{
g_camera.m_center = { 0.0f, 32.0f };
g_camera.m_zoom = 42.0f;
}

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

b2Vec2 points[e_pointCount];

b2Rot q = b2MakeRot( -2.0f * b2_pi / e_pointCount );
b2Vec2 p = { 40.0f, 0.0f };
for ( int i = 0; i < e_pointCount; ++i )
{
points[i] = { p.x, p.y + 32.0f };
p = b2RotateVector( q, p );
}

b2ChainDef chainDef = b2DefaultChainDef();
chainDef.points = points;
chainDef.count = e_pointCount;
chainDef.isLoop = true;
chainDef.friction = 0.1f;
chainDef.customColor = b2_colorWhite;

b2CreateChain( groundId, &chainDef );
}

{
m_bodyType = b2_dynamicBody;

b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = m_bodyType;
bodyDef.position = { 0.0, 12.0f };
bodyDef.enableSleep = false;

m_spinnerId = b2CreateBody( m_worldId, &bodyDef );

b2Polygon box = b2MakeRoundedBox( 0.4f, 20.0f, 0.2f );
b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.friction = 0.0f;
shapeDef.customColor = b2_colorAliceBlue;
b2CreatePolygonShape( m_spinnerId, &shapeDef, &box );

m_motorSpeed = 5.0f;
m_maxMotorTorque = 40000.0f;
b2RevoluteJointDef jointDef = b2DefaultRevoluteJointDef();
jointDef.bodyIdA = groundId;
jointDef.bodyIdB = m_spinnerId;
jointDef.localAnchorA = bodyDef.position;
jointDef.enableMotor = true;
jointDef.motorSpeed = m_motorSpeed;
jointDef.maxMotorTorque = m_maxMotorTorque;

m_jointId = b2CreateRevoluteJoint( m_worldId, &jointDef );
}

b2Capsule capsule = { { -0.25f, 0.0f }, { 0.25f, 0.0f }, 0.25f };
b2Circle circle = { { 0.0f, 0.0f }, 0.35f };
b2Polygon square = b2MakeSquare( 0.35f );

b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_dynamicBody;
b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.friction = 0.1f;
shapeDef.restitution = 0.1f;
shapeDef.density = 0.25f;

int bodyCount = g_sampleDebug ? 499 : e_count;

float x = -24.0f, y = 2.0f;
for ( int i = 0; i < bodyCount; ++i )
{
bodyDef.position = { x, y };
b2BodyId bodyId = b2CreateBody( m_worldId, &bodyDef );

int remainder = i % 3;
if ( remainder == 0 )
{
shapeDef.customColor = b2_colorYellow;
b2CreateCapsuleShape( bodyId, &shapeDef, &capsule );
}
else if ( remainder == 1 )
{
shapeDef.customColor = b2_colorYellowGreen;
b2CreateCircleShape( bodyId, &shapeDef, &circle );
}
else if ( remainder == 2 )
{
shapeDef.customColor = b2_colorGreenYellow;
b2CreatePolygonShape( bodyId, &shapeDef, &square );
}

x += 1.0f;

if ( x > 24.0f )
{
x = -24.0f;
y += 1.0f;
}
}

m_acceleration = 0.0f;
}

void UpdateUI() override
{
float height = 160.0f;
ImGui::SetNextWindowPos( ImVec2( 10.0f, g_camera.m_height - height - 50.0f ), ImGuiCond_Once );
ImGui::SetNextWindowSize( ImVec2( 240.0f, height ) );

ImGui::Begin( "Spinner", nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize );

if ( ImGui::SliderFloat( "Speed", &m_motorSpeed, -5.0f, 5.0f ) )
{
b2RevoluteJoint_SetMotorSpeed( m_jointId, m_motorSpeed );

if ( m_bodyType == b2_kinematicBody )
{
b2Body_SetAngularVelocity( m_spinnerId, m_motorSpeed );
}
}

if ( ImGui::SliderFloat( "Torque", &m_maxMotorTorque, 0.0f, 200000.0f ) )
{
b2RevoluteJoint_SetMaxMotorTorque( m_jointId, m_maxMotorTorque );
}

if ( ImGui::RadioButton( "Static", m_bodyType == b2_staticBody ) )
{
m_bodyType = b2_staticBody;
b2Body_SetType( m_spinnerId, b2_staticBody );
}

if ( ImGui::RadioButton( "Kinematic", m_bodyType == b2_kinematicBody ) )
{
m_bodyType = b2_kinematicBody;
b2Body_SetType( m_spinnerId, b2_kinematicBody );
b2Body_SetAngularVelocity( m_spinnerId, m_motorSpeed );
}

if ( ImGui::RadioButton( "Dynamic", m_bodyType == b2_dynamicBody ) )
{
m_bodyType = b2_dynamicBody;
b2Body_SetType( m_spinnerId, b2_dynamicBody );
}

ImGui::End();
}

void Step( Settings& settings ) override
{
if ( glfwGetKey( g_mainWindow, GLFW_KEY_A ) == GLFW_PRESS )
{
m_acceleration = -0.2f;
}

if ( glfwGetKey( g_mainWindow, GLFW_KEY_S ) == GLFW_PRESS )
{
m_acceleration = 0.0f;
m_motorSpeed = 0.0f;
}

if ( glfwGetKey( g_mainWindow, GLFW_KEY_D ) == GLFW_PRESS )
{
m_acceleration = 0.2f;
}

if ( settings.hertz > 0.0f )
{
m_motorSpeed = b2ClampFloat( m_motorSpeed + m_acceleration / settings.hertz, -5.0f, 5.0f );
b2RevoluteJoint_SetMotorSpeed( m_jointId, m_motorSpeed );

if ( m_bodyType == b2_kinematicBody )
{
b2Body_SetAngularVelocity( m_spinnerId, m_motorSpeed );
}
}

Sample::Step( settings );
}

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

b2BodyId m_spinnerId;
b2JointId m_jointId;
float m_acceleration;
float m_motorSpeed;
float m_maxMotorTorque;
b2BodyType m_bodyType;
};

static int sampleSpinner = RegisterSample( "Benchmark", "Spinner", BenchmarkSpinner::Create );
Loading

0 comments on commit 577c62a

Please sign in to comment.