Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross platform determinism #773

Merged
merged 37 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
bd7b708
stddef
erincatto Aug 19, 2024
e60e605
approximate sin, cos, and atan for determinism
erincatto Aug 21, 2024
8039d61
fix typos
erincatto Aug 23, 2024
e7a3687
64 bit filtering
erincatto Aug 24, 2024
3ea1071
CI fix
erincatto Aug 24, 2024
79448bd
restored island validation
erincatto Aug 24, 2024
ed4846b
fixed another island bug
erincatto Aug 24, 2024
dd372f8
wip
erincatto Aug 25, 2024
873d96b
fix for 64-bit category
erincatto Aug 25, 2024
85e8d23
warp sqrt
erincatto Aug 25, 2024
f5baf84
ffp-contract off
erincatto Aug 25, 2024
bc52212
neon fix
erincatto Aug 25, 2024
48cd727
API consistency
erincatto Aug 25, 2024
bd1c74e
fix documentation typo
erincatto Aug 25, 2024
bc1a2c5
Removed all internal usage of b2MakeRot (sin/cos)
erincatto Aug 26, 2024
e22bc4e
CI fix
erincatto Aug 26, 2024
e9633c9
testing macos settings
erincatto Aug 26, 2024
4ebc59e
fp precise on clang
erincatto Aug 26, 2024
c2f6333
fix typo
erincatto Aug 27, 2024
a7eb565
fix 01
erincatto Aug 27, 2024
570373f
try 02
erincatto Aug 27, 2024
d7ab203
try 02
erincatto Aug 27, 2024
3c733cd
try03
erincatto Aug 27, 2024
1a1d1b2
try04
erincatto Aug 27, 2024
b1c61c7
try05
erincatto Aug 27, 2024
073a663
try06
erincatto Aug 27, 2024
6f6f899
testing cos and sin
erincatto Aug 27, 2024
96142bc
test 1
erincatto Aug 28, 2024
e13bc93
test 02
erincatto Aug 28, 2024
5220ca0
test 3
erincatto Aug 28, 2024
19119e2
test 4
erincatto Aug 28, 2024
a524645
test 5
erincatto Aug 28, 2024
8e19813
back to sqrtf
erincatto Aug 28, 2024
5f98c2b
clean up
erincatto Aug 29, 2024
ffa454c
clean up
erincatto Aug 29, 2024
bebfa53
clean up
erincatto Aug 29, 2024
d1fbc61
3.1 version
erincatto Aug 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ jobs:
- uses: actions/checkout@v4

- name: Configure CMake
# some problem with simde
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
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ include(FetchContent)
include(CMakeDependentOption)

project(box2d
VERSION 3.0.1
VERSION 3.1.0
DESCRIPTION "A 2D physics engine for games"
HOMEPAGE_URL "https://box2d.org"
LANGUAGES C CXX
Expand Down
2 changes: 1 addition & 1 deletion benchmark/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ int main( int argc, char** argv )

b2WorldDef worldDef = b2DefaultWorldDef();
worldDef.enableSleep = false;
worldDef.enableContinous = enableContinuous;
worldDef.enableContinuous = enableContinuous;
worldDef.enqueueTask = EnqueueTask;
worldDef.finishTask = FinishTask;
worldDef.workerCount = threadCount;
Expand Down
8 changes: 4 additions & 4 deletions benchmark/tumbler.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ b2WorldId Tumbler( b2WorldDef* worldDef )
shapeDef.density = 50.0f;

b2Polygon polygon;
polygon = b2MakeOffsetBox( 0.5f, 10.0f, ( b2Vec2 ){ 10.0f, 0.0f }, 0.0 );
polygon = b2MakeOffsetBox( 0.5f, 10.0f, ( b2Vec2 ){ 10.0f, 0.0f }, b2Rot_identity );
b2CreatePolygonShape( bodyId, &shapeDef, &polygon );
polygon = b2MakeOffsetBox( 0.5f, 10.0f, ( b2Vec2 ){ -10.0f, 0.0f }, 0.0 );
polygon = b2MakeOffsetBox( 0.5f, 10.0f, ( b2Vec2 ){ -10.0f, 0.0f }, b2Rot_identity );
b2CreatePolygonShape( bodyId, &shapeDef, &polygon );
polygon = b2MakeOffsetBox( 10.0f, 0.5f, ( b2Vec2 ){ 0.0f, 10.0f }, 0.0 );
polygon = b2MakeOffsetBox( 10.0f, 0.5f, ( b2Vec2 ){ 0.0f, 10.0f }, b2Rot_identity );
b2CreatePolygonShape( bodyId, &shapeDef, &polygon );
polygon = b2MakeOffsetBox( 10.0f, 0.5f, ( b2Vec2 ){ 0.0f, -10.0f }, 0.0 );
polygon = b2MakeOffsetBox( 10.0f, 0.5f, ( b2Vec2 ){ 0.0f, -10.0f }, b2Rot_identity );
b2CreatePolygonShape( bodyId, &shapeDef, &polygon );

float motorSpeed = 25.0f;
Expand Down
9 changes: 4 additions & 5 deletions docs/simulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,8 @@ scenarios that require altering the mass.
b2MassData myMassData;
myMassData.mass = 10.0f;
myMassData.center = (b2Vec2){0.0f, 0.0f};
myMassData.I = 100.0f;
b2Body_SetMassData(myBodyId, &myMassData);
myMassData.rotationalInertia = 100.0f;
b2Body_SetMassData(myBodyId, myMassData);
```

After setting a body's mass directly, you may wish to revert to the
Expand All @@ -470,7 +470,7 @@ The body's mass data is available through the following functions:
```c
float mass = b2Body_GetMass(myBodyId);
float inertia = b2Body_GetInertiaTensor(myBodyId);
float inertia = b2Body_GetRotationalInertia(myBodyId);
b2Vec2 localCenter b2Body_GetLocalCenterOfMass(myBodyId);
b2MassData massData = b2Body_GetMassData(myBodyId);
```
Expand Down Expand Up @@ -1448,8 +1448,7 @@ joint limit and a friction motor:
```c
b2Vec2 worldPivot = {10.0f, -4.0f};
b2Vec2 worldAxis = {1.0f, 0.0f};
b2PrismaticJointDef jointDef;
b2RevoluteJointDef jointDef = b2DefaultRevoluteJointDef();
b2PrismaticJointDef jointDef = b2DefaultPrismaticJointDef();
jointDef.bodyIdA = myBodyIdA;
jointDef.bodyIdB = myBodyIdB;
jointDef.localAnchorA = b2Body_GetLocalPoint(myBodyIdA, worldPivot);
Expand Down
14 changes: 10 additions & 4 deletions include/box2d/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,24 @@

#include <stdint.h>

// clang-format off
//
// Shared library macros
#if defined( _MSC_VER ) && defined( box2d_EXPORTS )
// build the Windows DLL
#define BOX2D_EXPORT __declspec( dllexport )
#elif defined( _MSC_VER ) && defined( BOX2D_DLL )
// using the Windows DLL
// using the Windows DLL
#define BOX2D_EXPORT __declspec( dllimport )
#elif defined( box2d_EXPORTS )
// building or using the Box2D shared library
// building or using the Box2D shared library
#define BOX2D_EXPORT __attribute__( ( visibility( "default" ) ) )
#else
// static library
// static library
#define BOX2D_EXPORT
#endif

// C++ macros
// clang-format off
#ifdef __cplusplus
#define B2_API extern "C" BOX2D_EXPORT
#define B2_INLINE inline
Expand Down Expand Up @@ -104,4 +105,9 @@ B2_API float b2GetMilliseconds( const b2Timer* timer );
B2_API float b2GetMillisecondsAndReset( b2Timer* timer );
B2_API void b2SleepMilliseconds( int milliseconds );
B2_API void b2Yield( void );

// Simple djb2 hash function for determinism testing
#define B2_HASH_INIT 5381
B2_API uint32_t b2Hash( uint32_t hash, const uint8_t* data, int count );

//! @endcond
13 changes: 8 additions & 5 deletions include/box2d/box2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ B2_API void b2Body_ApplyAngularImpulse( b2BodyId bodyId, float impulse, bool wak
/// Get the mass of the body, typically in kilograms
B2_API float b2Body_GetMass( b2BodyId bodyId );

/// Get the inertia tensor of the body, typically in kg*m^2
B2_API float b2Body_GetInertiaTensor( b2BodyId bodyId );
/// Get the rotational inertia of the body, typically in kg*m^2
B2_API float b2Body_GetRotationalInertia( b2BodyId bodyId );

/// Get the center of mass position of the body in local space
B2_API b2Vec2 b2Body_GetLocalCenterOfMass( b2BodyId bodyId );
Expand Down Expand Up @@ -353,7 +353,7 @@ B2_API void b2Body_EnableSleep( b2BodyId bodyId, bool enableSleep );
B2_API bool b2Body_IsSleepEnabled( b2BodyId bodyId );

/// Set the sleep threshold, typically in meters per second
B2_API void b2Body_SetSleepThreshold( b2BodyId bodyId, float sleepVelocity );
B2_API void b2Body_SetSleepThreshold( b2BodyId bodyId, float sleepThreshold );

/// Get the sleep threshold, typically in meters per second.
B2_API float b2Body_GetSleepThreshold( b2BodyId bodyId );
Expand Down Expand Up @@ -674,10 +674,10 @@ B2_API void b2DistanceJoint_SetSpringHertz( b2JointId jointId, float hertz );
B2_API void b2DistanceJoint_SetSpringDampingRatio( b2JointId jointId, float dampingRatio );

/// Get the spring Hertz
B2_API float b2DistanceJoint_GetHertz( b2JointId jointId );
B2_API float b2DistanceJoint_GetSpringHertz( b2JointId jointId );

/// Get the spring damping ratio
B2_API float b2DistanceJoint_GetDampingRatio( b2JointId jointId );
B2_API float b2DistanceJoint_GetSpringDampingRatio( b2JointId jointId );

/// Enable joint limit. The limit only works if the joint spring is enabled. Otherwise the joint is rigid
/// and the limit has no effect.
Expand Down Expand Up @@ -893,6 +893,9 @@ B2_API b2JointId b2CreateRevoluteJoint( b2WorldId worldId, const b2RevoluteJoint
/// Enable/disable the revolute joint spring
B2_API void b2RevoluteJoint_EnableSpring( b2JointId jointId, bool enableSpring );

/// It the revolute angular spring enabled?
B2_API bool b2RevoluteJoint_IsSpringEnabled( b2JointId jointId );

/// Set the revolute joint spring stiffness in Hertz
B2_API void b2RevoluteJoint_SetSpringHertz( b2JointId jointId, float hertz );

Expand Down
22 changes: 10 additions & 12 deletions include/box2d/collision.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ B2_API b2Polygon b2MakeBox( float hx, float hy );
B2_API b2Polygon b2MakeRoundedBox( float hx, float hy, float radius );

/// Make an offset box, bypassing the need for a convex hull.
B2_API b2Polygon b2MakeOffsetBox( float hx, float hy, b2Vec2 center, float angle );
B2_API b2Polygon b2MakeOffsetBox( float hx, float hy, b2Vec2 center, b2Rot rotation );

/// Transform a polygon. This is useful for transferring a shape from one body to another.
B2_API b2Polygon b2TransformPolygon( b2Transform transform, const b2Polygon* polygon );
Expand Down Expand Up @@ -589,21 +589,20 @@ B2_API b2Manifold b2CollideSmoothSegmentAndPolygon( const b2SmoothSegment* smoot
*/

/// The default category bit for a tree proxy. Used for collision filtering.
#define b2_defaultCategoryBits ( 0x00000001 )
#define b2_defaultCategoryBits ( 1 )

/// Convenience mask bits to use when you don't need collision filtering and just want
/// all results.
#define b2_defaultMaskBits ( 0xFFFFFFFF )
#define b2_defaultMaskBits ( UINT64_MAX )

/// A node in the dynamic tree. This is private data placed here for performance reasons.
/// 16 + 16 + 8 + pad(8)
typedef struct b2TreeNode
{
/// The node bounding box
b2AABB aabb; // 16

/// Category bits for collision filtering
uint32_t categoryBits; // 4
uint64_t categoryBits; // 8

union
{
Expand Down Expand Up @@ -631,7 +630,7 @@ typedef struct b2TreeNode
bool enlarged; // 1

/// Padding for clarity
char pad[9];
char pad[5];
} b2TreeNode;

/// The dynamic tree structure. This should be considered private data.
Expand Down Expand Up @@ -679,7 +678,7 @@ B2_API b2DynamicTree b2DynamicTree_Create( void );
B2_API void b2DynamicTree_Destroy( b2DynamicTree* tree );

/// Create a proxy. Provide an AABB and a userData value.
B2_API int32_t b2DynamicTree_CreateProxy( b2DynamicTree* tree, b2AABB aabb, uint32_t categoryBits, int32_t userData );
B2_API int32_t b2DynamicTree_CreateProxy( b2DynamicTree* tree, b2AABB aabb, uint64_t categoryBits, int32_t userData );

/// Destroy a proxy. This asserts if the id is invalid.
B2_API void b2DynamicTree_DestroyProxy( b2DynamicTree* tree, int32_t proxyId );
Expand All @@ -694,9 +693,8 @@ B2_API void b2DynamicTree_EnlargeProxy( b2DynamicTree* tree, int32_t proxyId, b2
/// @return true if the query should continue
typedef bool b2TreeQueryCallbackFcn( int32_t proxyId, int32_t userData, void* context );

/// Query an AABB for overlapping proxies. The callback class
/// is called for each proxy that overlaps the supplied AABB.
B2_API void b2DynamicTree_Query( const b2DynamicTree* tree, b2AABB aabb, uint32_t maskBits, b2TreeQueryCallbackFcn* callback,
/// Query an AABB for overlapping proxies. The callback class is called for each proxy that overlaps the supplied AABB.
B2_API void b2DynamicTree_Query( const b2DynamicTree* tree, b2AABB aabb, uint64_t maskBits, b2TreeQueryCallbackFcn* callback,
void* context );

/// This function receives clipped raycast input for a proxy. The function
Expand All @@ -717,7 +715,7 @@ typedef float b2TreeRayCastCallbackFcn( const b2RayCastInput* input, int32_t pro
/// @param maskBits filter bits: `bool accept = (maskBits & node->categoryBits) != 0;`
/// @param callback a callback class that is called for each proxy that is hit by the ray
/// @param context user context that is passed to the callback
B2_API void b2DynamicTree_RayCast( const b2DynamicTree* tree, const b2RayCastInput* input, uint32_t maskBits,
B2_API void b2DynamicTree_RayCast( const b2DynamicTree* tree, const b2RayCastInput* input, uint64_t maskBits,
b2TreeRayCastCallbackFcn* callback, void* context );

/// This function receives clipped ray-cast input for a proxy. The function
Expand All @@ -737,7 +735,7 @@ typedef float b2TreeShapeCastCallbackFcn( const b2ShapeCastInput* input, int32_t
/// @param maskBits filter bits: `bool accept = (maskBits & node->categoryBits) != 0;`
/// @param callback a callback class that is called for each proxy that is hit by the shape
/// @param context user context that is passed to the callback
B2_API void b2DynamicTree_ShapeCast( const b2DynamicTree* tree, const b2ShapeCastInput* input, uint32_t maskBits,
B2_API void b2DynamicTree_ShapeCast( const b2DynamicTree* tree, const b2ShapeCastInput* input, uint64_t maskBits,
b2TreeShapeCastCallbackFcn* callback, void* context );

/// Validate this tree. For testing.
Expand Down
Loading