Skip to content

Commit

Permalink
Array refactor (#796)
Browse files Browse the repository at this point in the history
Internal arrays using macro generated functions instead of stretchy
buffers.
Added `b2Body_GetWorld`
Added `b2CosSin` and `b2ComputeCosSin`
  • Loading branch information
erincatto authored Sep 21, 2024
1 parent c69eee4 commit c56a76d
Show file tree
Hide file tree
Showing 60 changed files with 1,399 additions and 1,830 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ jobs:
- uses: actions/checkout@v4

- name: Configure CMake
# run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOX2D_SAMPLES=OFF -DBOX2D_SANITIZE=ON -DBUILD_SHARED_LIBS=OFF
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOX2D_SAMPLES=OFF -DBUILD_SHARED_LIBS=OFF
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOX2D_SAMPLES=OFF -DBOX2D_SANITIZE=ON -DBUILD_SHARED_LIBS=OFF
# run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOX2D_SAMPLES=OFF -DBUILD_SHARED_LIBS=OFF

- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
Expand All @@ -76,8 +76,8 @@ jobs:

- name: Configure CMake
# enkiTS is failing ASAN on windows
# run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOX2D_SAMPLES=OFF -DBOX2D_SANITIZE=ON -DBUILD_SHARED_LIBS=OFF
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOX2D_SAMPLES=OFF -DBUILD_SHARED_LIBS=OFF
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOX2D_SAMPLES=OFF -DBOX2D_SANITIZE=ON -DBUILD_SHARED_LIBS=OFF
# run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOX2D_SAMPLES=OFF -DBUILD_SHARED_LIBS=OFF

- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
Expand Down
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ message(STATUS "CMake C++ compiler: ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "CMake system name: ${CMAKE_SYSTEM_NAME}")
message(STATUS "CMake host system processor: ${CMAKE_HOST_SYSTEM_PROCESSOR}")

# static link
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

if (MSVC OR APPLE)
option(BOX2D_SANITIZE "Enable sanitizers for some builds" OFF)
if(BOX2D_SANITIZE)
Expand Down
16 changes: 8 additions & 8 deletions benchmark/amd7950x_avx2/joint_grid.csv
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
threads,fps
1,333.07
2,641.434
3,944.038
4,1206.21
5,1496.76
6,1722.19
7,1956.35
8,2146.81
1,335.038
2,638.117
3,938.253
4,1211.86
5,1495.94
6,1719.76
7,1964.31
8,2148.41
16 changes: 8 additions & 8 deletions benchmark/amd7950x_avx2/large_pyramid.csv
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
threads,fps
1,337.452
2,623.273
3,889.504
4,1124.83
5,1339.88
6,1493.98
7,1689.74
8,1726.49
1,334.105
2,617.266
3,895.838
4,1131.52
5,1338.68
6,1503.01
7,1686.74
8,1721.57
16 changes: 8 additions & 8 deletions benchmark/amd7950x_avx2/many_pyramids.csv
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
threads,fps
1,87.7948
2,165.138
3,244.692
4,310.302
5,379.072
6,436.226
7,503.71
8,554.489
1,85.2506
2,163.857
3,241.226
4,309.927
5,369.713
6,431.47
7,496.292
8,547.372
16 changes: 8 additions & 8 deletions benchmark/amd7950x_avx2/smash.csv
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
threads,fps
1,178.234
2,282.589
3,360.22
4,431.746
5,485.852
6,529.01
7,570.548
8,599.725
1,180.404
2,284.615
3,364.465
4,441.008
5,495.098
6,538.398
7,578.614
8,610.615
16 changes: 8 additions & 8 deletions benchmark/amd7950x_avx2/tumbler.csv
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
threads,fps
1,379.168
2,593.692
3,768.849
4,908.277
5,1050.74
6,1145.49
7,1231.01
8,1298.58
1,385.465
2,604.521
3,790.813
4,934.896
5,1088.09
6,1192.74
7,1276.24
8,1346.88
68 changes: 52 additions & 16 deletions benchmark/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
#include <string.h>

#if defined( _WIN64 )
#include <windows.h>
#include <windows.h>
#elif defined( __APPLE__ )
#include <unistd.h>
#include <unistd.h>
#elif defined( __linux__ )
#include <unistd.h>
#include <unistd.h>
#endif

#define ARRAY_COUNT( A ) (int)( sizeof( A ) / sizeof( A[0] ) )
Expand Down Expand Up @@ -114,10 +114,23 @@ static void FinishTask( void* userTask, void* userContext )
enkiWaitForTaskSet( scheduler, task );
}

// Box2D benchmark application. On Windows I recommend running this in an administrator command prompt. Don't use Windows Terminal.
int main( int argc, char** argv )
{
Benchmark benchmarks[] = {
{ "joint_grid", JointGrid, 500 },
{ "large_pyramid", LargePyramid, 500 },
{ "many_pyramids", ManyPyramids, 200 },
{ "smash", Smash, 300 },
{ "tumbler", Tumbler, 750 },
};

int benchmarkCount = ARRAY_COUNT( benchmarks );

int maxThreadCount = GetNumberOfCores();
int runCount = 4;
int singleBenchmark = -1;
int singleWorkerCount = -1;
b2Counters counters = { 0 };
bool enableContinuous = true;

Expand All @@ -129,30 +142,47 @@ int main( int argc, char** argv )
if ( strncmp( arg, "-t=", 3 ) == 0 )
{
int threadCount = atoi( arg + 3 );
maxThreadCount = b2MinInt( maxThreadCount, threadCount );
maxThreadCount = b2ClampInt( threadCount, 1, maxThreadCount );
}
else if ( strncmp( arg, "-b=", 3 ) == 0 )
{
singleBenchmark = atoi( arg + 3 );
singleBenchmark = b2ClampInt( singleBenchmark, 0, benchmarkCount - 1 );
}
else if ( strncmp( arg, "-w=", 3 ) == 0 )
{
singleWorkerCount = atoi( arg + 3 );
}
else if ( strncmp( arg, "-r=", 3 ) == 0 )
{
runCount = b2ClampInt(atoi( arg + 3 ), 1, 16);
}
else if ( strcmp( arg, "-h" ) == 0 )
{
printf( "Usage\n"
"-t=<thread count>: the maximum number of threads to use\n" );
"-t=<integer>: the maximum number of threads to use\n"
"-b=<integer>: run a single benchmark\n"
"-w=<integer>: run a single worker count\n"
"-r=<integer>: number of repeats (default is 4)\n" );
exit( 0 );
}
}

Benchmark benchmarks[] = {
{ "joint_grid", JointGrid, 500 },
{ "large_pyramid", LargePyramid, 500 },
{ "many_pyramids", ManyPyramids, 200 },
{ "smash", Smash, 300 },
{ "tumbler", Tumbler, 750 },
};

int benchmarkCount = ARRAY_COUNT( benchmarks );
if ( singleWorkerCount != -1 )
{
singleWorkerCount = b2ClampInt( singleWorkerCount, 1, maxThreadCount );
}

printf( "Starting Box2D benchmarks\n" );
printf( "======================================\n" );

for ( int benchmarkIndex = 0; benchmarkIndex < benchmarkCount; ++benchmarkIndex )
{
if ( singleBenchmark != -1 && benchmarkIndex != singleBenchmark )
{
continue;
}

#ifdef NDEBUG
int stepCount = benchmarks[benchmarkIndex].stepCount;
#else
Expand All @@ -167,6 +197,11 @@ int main( int argc, char** argv )

for ( int threadCount = 1; threadCount <= maxThreadCount; ++threadCount )
{
if ( singleWorkerCount != -1 && singleWorkerCount != threadCount )
{
continue;
}

printf( "thread count: %d\n", threadCount );

for ( int runIndex = 0; runIndex < runCount; ++runIndex )
Expand Down Expand Up @@ -195,6 +230,7 @@ int main( int argc, char** argv )

// Initial step can be expensive and skew benchmark
b2World_Step( worldId, timeStep, subStepCount );
taskCount = 0;

b2Timer timer = b2CreateTimer();

Expand Down Expand Up @@ -242,9 +278,9 @@ int main( int argc, char** argv )
}

fprintf( file, "threads,fps\n" );
for ( int threadCount = 1; threadCount <= maxThreadCount; ++threadCount )
for ( int threadIndex = 1; threadIndex <= maxThreadCount; ++threadIndex )
{
fprintf( file, "%d,%g\n", threadCount, maxFps[threadCount - 1] );
fprintf( file, "%d,%g\n", threadIndex, maxFps[threadIndex - 1] );
}

fclose( file );
Expand Down
3 changes: 3 additions & 0 deletions include/box2d/box2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,9 @@ B2_API bool b2Body_IsBullet( b2BodyId bodyId );
/// @see b2ShapeDef::enableHitEvents
B2_API void b2Body_EnableHitEvents( b2BodyId bodyId, bool enableHitEvents );

/// Get the world that owns this body
B2_API b2WorldId b2Body_GetWorld( b2BodyId bodyId );

/// Get the number of shapes on this body
B2_API int b2Body_GetShapeCount( b2BodyId bodyId );

Expand Down
19 changes: 17 additions & 2 deletions include/box2d/math_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ typedef struct b2Vec2
float x, y;
} b2Vec2;

/// Cosine and sine pair
/// This uses a custom implementation designed for cross platform determinism
typedef struct b2CosSin
{
/// cosine and sine
float cosine;
float sine;
} b2CosSin;

/// 2D rotation
/// This is similar to using a complex number for rotation
typedef struct b2Rot
Expand Down Expand Up @@ -323,7 +332,14 @@ B2_INLINE float b2DistanceSquared( b2Vec2 a, b2Vec2 b )
}

/// Make a rotation using an angle in radians
B2_API b2Rot b2MakeRot( float angle );
B2_API b2CosSin b2ComputeCosSin( float angle );

/// Make a rotation using an angle in radians
B2_INLINE b2Rot b2MakeRot( float angle )
{
b2CosSin cs = b2ComputeCosSin( angle );
return B2_LITERAL( b2Rot ){ cs.cosine, cs.sine };
}

/// Is this rotation normalized?
B2_INLINE bool b2IsNormalized( b2Rot q )
Expand All @@ -346,7 +362,6 @@ B2_INLINE b2Rot b2NLerp( b2Rot q1, b2Rot q2, float t )
return b2NormalizeRot( q );
}


/// Compute the angular velocity necessary to rotate between two rotations over a give time
/// @param q1 initial rotation
/// @param q2 final rotation
Expand Down
12 changes: 7 additions & 5 deletions samples/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@
#include <vector>

#if defined( _WIN32 )
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>
#else
#include <stdlib.h>
#include <stdlib.h>
#endif

// clang-format off
#include <glad/glad.h>
// Keep glad.h before glfw3.h
#include <GLFW/glfw3.h>
// clang-format on

#include <imgui.h>

#define BUFFER_OFFSET( x ) ( (const void*)( x ) )
Expand Down
15 changes: 8 additions & 7 deletions samples/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,25 @@
#include "box2d/box2d.h"
#include "box2d/math_functions.h"

// clang-format off
#include <glad/glad.h>
// Keep glad.h before glfw3.h
#include <GLFW/glfw3.h>
// clang-format on

#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef BOX2D_PROFILE
#include <tracy/Tracy.hpp>
#include <tracy/Tracy.hpp>
#else
#define FrameMark
#define FrameMark
#endif

#if defined( _WIN32 )
#include <crtdbg.h>
#include <crtdbg.h>

static int MyAllocHook( int allocType, void* userData, size_t size, int blockType, long requestNumber,
const unsigned char* filename, int lineNumber )
Expand Down Expand Up @@ -515,7 +517,6 @@ static void UpdateUI()
}
}

//
int main( int, char** )
{
#if defined( _WIN32 )
Expand Down Expand Up @@ -707,9 +708,9 @@ int main( int, char** )

// if (g_draw.m_showUI)
{
snprintf( buffer, 128, "%.1f ms - step %d - camera (%g, %g, %g)", 1000.0f * frameTime, s_sample->m_stepCount,
snprintf( buffer, 128, "%.1f ms - step %d - camera (%g, %g, %g)", 1000.0f * frameTime, s_sample->m_stepCount,
g_camera.m_center.x, g_camera.m_center.y, g_camera.m_zoom );
//snprintf( buffer, 128, "%.1f ms", 1000.0f * frameTime );
// snprintf( buffer, 128, "%.1f ms", 1000.0f * frameTime );

ImGui::Begin( "Overlay", nullptr,
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize |
Expand Down
4 changes: 2 additions & 2 deletions samples/sample_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,8 @@ class BenchmarkManyPyramids : public Sample
m_extent = 0.5f;
m_round = 0.0f;
m_baseCount = 10;
m_rowCount = g_sampleDebug ? 4 : 13;
m_columnCount = g_sampleDebug ? 4 : 14;
m_rowCount = g_sampleDebug ? 4 : 20;
m_columnCount = g_sampleDebug ? 4 : 20;
m_groundId = b2_nullBodyId;
m_bodyIds = nullptr;
m_bodyCount = 0;
Expand Down
Loading

0 comments on commit c56a76d

Please sign in to comment.