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 random numbers for samples #785

Merged
merged 4 commits into from
Aug 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 5 additions & 2 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ set_target_properties(benchmark PROPERTIES
C_EXTENSIONS NO
)

if(MSVC)
# target_compile_options(benchmark PRIVATE /experimental:c11atomics)
if (MSVC)
target_compile_options(benchmark PRIVATE /experimental:c11atomics)
elseif (APPLE)
# determinism settings
target_compile_options(benchmark PRIVATE -ffp-contract=off)
endif()

target_link_libraries(benchmark PRIVATE box2d enkiTS)
2 changes: 1 addition & 1 deletion include/box2d/box2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ B2_API bool b2Shape_AreHitEventsEnabled( b2ShapeId shapeId );
B2_API bool b2Shape_TestPoint( b2ShapeId shapeId, b2Vec2 point );

/// Ray cast a shape directly
B2_API b2CastOutput b2Shape_RayCast( b2ShapeId shapeId, b2Vec2 origin, b2Vec2 translation );
B2_API b2CastOutput b2Shape_RayCast( b2ShapeId shapeId, const b2RayCastInput* input );

/// Get a copy of the shape's circle. Asserts the type is correct.
B2_API b2Circle b2Shape_GetCircle( b2ShapeId shapeId );
Expand Down
2 changes: 1 addition & 1 deletion samples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ set_target_properties(samples PROPERTIES

if (APPLE)
# determinism settings
target_compile_options(samples PRIVATE -ffp-model=precise -ffp-contract=off)
target_compile_options(samples PRIVATE -ffp-contract=off)
endif()

target_include_directories(samples PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${JSMN_DIR})
Expand Down
6 changes: 5 additions & 1 deletion samples/sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ Sample::Sample( Settings& settings )
m_maxProfile = {};
m_totalProfile = {};

g_seed = RAND_SEED;

TestMathCpp();
}

Expand Down Expand Up @@ -488,10 +490,12 @@ int RegisterSample( const char* category, const char* name, SampleCreateFcn* fcn
return -1;
}

uint32_t g_seed = RAND_SEED;

b2Polygon RandomPolygon( float extent )
{
b2Vec2 points[b2_maxPolygonVertices];
int count = 3 + rand() % 6;
int count = 3 + RandomInt() % 6;
for ( int i = 0; i < count; ++i )
{
points[i] = RandomVec2( -extent, extent );
Expand Down
36 changes: 27 additions & 9 deletions samples/sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
// todo this include is slow
#include "TaskScheduler.h"

#include <stdlib.h>

#define ARRAY_COUNT( A ) (int)( sizeof( A ) / sizeof( A[0] ) )

struct Settings;
Expand Down Expand Up @@ -113,32 +111,52 @@ extern SampleEntry g_sampleEntries[MAX_SAMPLES];
extern int g_sampleCount;

#define RAND_LIMIT 32767
#define RAND_SEED 12345

// Global seed for simple random number generator. This is reset
// for each sample.
extern uint32_t g_seed;

// Simple random number generator. Using this instead of rand()
// for cross platform determinism.
inline int RandomInt()
{
// XorShift32 algorithm
uint32_t x = g_seed;
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
g_seed = x;

// Map the 32-bit value to the range 0 to RAND_LIMIT
return (int)( x % ( RAND_LIMIT + 1 ) );
}

/// Random integer in range [lo, hi)
// Random integer in range [lo, hi]
inline float RandomInt( int lo, int hi )
{
return lo + rand() % ( hi - lo );
return lo + RandomInt() % ( hi - lo + 1 );
}

/// Random number in range [-1,1]
// Random number in range [-1,1]
inline float RandomFloat()
{
float r = (float)( rand() & ( RAND_LIMIT ) );
float r = (float)( RandomInt() & ( RAND_LIMIT ) );
r /= RAND_LIMIT;
r = 2.0f * r - 1.0f;
return r;
}

/// Random floating point number in range [lo, hi]
// Random floating point number in range [lo, hi]
inline float RandomFloat( float lo, float hi )
{
float r = (float)( rand() & ( RAND_LIMIT ) );
float r = (float)( RandomInt() & ( RAND_LIMIT ) );
r /= RAND_LIMIT;
r = ( hi - lo ) * r + lo;
return r;
}

/// Random vector with coordinates in range [lo, hi]
// Random vector with coordinates in range [lo, hi]
inline b2Vec2 RandomVec2( float lo, float hi )
{
b2Vec2 v;
Expand Down
2 changes: 1 addition & 1 deletion samples/sample_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class BenchmarkBarrel : public Sample

void CreateScene()
{
srand( 42 );
g_seed = 42;

for ( int i = 0; i < e_maxRows * e_maxColumns; ++i )
{
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ elseif (MINGW)
endif()
elseif (APPLE)
message(STATUS "Box2D on Apple")
target_compile_options(box2d PRIVATE -ffp-model=precise -ffp-contract=off)
target_compile_options(box2d PRIVATE -ffp-contract=off)
elseif (EMSCRIPTEN)
message(STATUS "Box2D on Emscripten")
elseif (UNIX)
Expand Down
31 changes: 14 additions & 17 deletions src/shape.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ static b2Shape* b2GetShape( b2World* world, b2ShapeId shapeId )
return shape;
}

b2Transform b2GetOwnerTransform( b2World* world, b2Shape* shape )
{
return b2GetBodyTransform( world, shape->bodyId );
}

static b2ChainShape* b2GetChainShape( b2World* world, b2ChainId chainId )
{
int id = chainId.index1 - 1;
Expand Down Expand Up @@ -766,7 +761,7 @@ bool b2Shape_TestPoint( b2ShapeId shapeId, b2Vec2 point )
b2World* world = b2GetWorld( shapeId.world0 );
b2Shape* shape = b2GetShape( world, shapeId );

b2Transform transform = b2GetOwnerTransform( world, shape );
b2Transform transform = b2GetBodyTransform( world, shape->bodyId );
b2Vec2 localPoint = b2InvTransformPoint( transform, point );

switch ( shape->type )
Expand All @@ -785,40 +780,41 @@ bool b2Shape_TestPoint( b2ShapeId shapeId, b2Vec2 point )
}
}

b2CastOutput b2Shape_RayCast( b2ShapeId shapeId, b2Vec2 origin, b2Vec2 translation )
// todo_erin untested
b2CastOutput b2Shape_RayCast( b2ShapeId shapeId, const b2RayCastInput* input )
{
b2World* world = b2GetWorld( shapeId.world0 );
b2Shape* shape = b2GetShape( world, shapeId );

b2Transform transform = b2GetOwnerTransform( world, shape );
b2Transform transform = b2GetBodyTransform( world, shape->bodyId );

// input in local coordinates
b2RayCastInput input;
input.maxFraction = 1.0f;
input.origin = b2InvTransformPoint( transform, origin );
input.translation = b2InvRotateVector( transform.q, translation );
b2RayCastInput localInput;
localInput.origin = b2InvTransformPoint( transform, input->origin );
localInput.translation = b2InvRotateVector( transform.q, input->translation );
localInput.maxFraction = input->maxFraction;

b2CastOutput output = { 0 };
switch ( shape->type )
{
case b2_capsuleShape:
output = b2RayCastCapsule( &input, &shape->capsule );
output = b2RayCastCapsule( &localInput, &shape->capsule );
break;

case b2_circleShape:
output = b2RayCastCircle( &input, &shape->circle );
output = b2RayCastCircle( &localInput, &shape->circle );
break;

case b2_segmentShape:
output = b2RayCastSegment( &input, &shape->segment, false );
output = b2RayCastSegment( &localInput, &shape->segment, false );
break;

case b2_polygonShape:
output = b2RayCastPolygon( &input, &shape->polygon );
output = b2RayCastPolygon( &localInput, &shape->polygon );
break;

case b2_chainSegmentShape:
output = b2RayCastSegment( &input, &shape->chainSegment.segment, true );
output = b2RayCastSegment( &localInput, &shape->chainSegment.segment, true );
break;

default:
Expand All @@ -832,6 +828,7 @@ b2CastOutput b2Shape_RayCast( b2ShapeId shapeId, b2Vec2 origin, b2Vec2 translati
output.normal = b2RotateVector( transform.q, output.normal );
output.point = b2TransformPoint( transform, output.point );
}

return output;
}

Expand Down
2 changes: 1 addition & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ if (MSVC)
target_compile_options(test PRIVATE /experimental:c11atomics)
elseif (APPLE)
# determinism settings
target_compile_options(test PRIVATE -ffp-model=precise -ffp-contract=off)
target_compile_options(test PRIVATE -ffp-contract=off)
endif()

target_link_libraries(test PRIVATE box2d enkiTS)
Expand Down