Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
erincatto committed Jan 25, 2025
1 parent cad8599 commit b6984de
Show file tree
Hide file tree
Showing 17 changed files with 244 additions and 43 deletions.
10 changes: 7 additions & 3 deletions include/box2d/collision.h
Original file line number Diff line number Diff line change
Expand Up @@ -535,14 +535,18 @@ typedef struct b2ManifoldPoint
/// @note Box2D uses speculative collision so some contact points may be separated.
typedef struct b2Manifold
{
/// The manifold points, up to two are possible in 2D
b2ManifoldPoint points[2];

/// The unit normal vector in world space, points from shape A to bodyB
b2Vec2 normal;

/// Angular impulse applied for rolling resistance. N * m * s = kg * m^2 / s
float rollingImpulse;

/// The manifold points, up to two are possible in 2D
b2ManifoldPoint points[2];

/// The number of contacts points, will be 0, 1, or 2
int pointCount;

} b2Manifold;

/// Compute the contact manifold between two circles
Expand Down
4 changes: 3 additions & 1 deletion include/box2d/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,11 @@ typedef struct b2ShapeDef
float restitution;

/// The rolling resistance usually in the range [0,1].
/// todo
float rollingResistance;

/// The tangent speed for conveyor belts
float tangentSpeed;

/// User material identifier. This is passed with query results and to friction and restitution
/// combining functions. It is not used internally.
int material;
Expand Down
13 changes: 2 additions & 11 deletions samples/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,6 @@ int main( int, char** )

float frameTime = 0.0;

// int32_t frame = 0;

while ( !glfwWindowShouldClose( g_mainWindow ) )
{
double time1 = glfwGetTime();
Expand Down Expand Up @@ -754,21 +752,14 @@ int main( int, char** )

// Limit frame rate to 60Hz
double time2 = glfwGetTime();
double targetTime = time1 + 1.0f / 60.0f;
// int loopCount = 0;
double targetTime = time1 + 1.0 / 60.0;
while ( time2 < targetTime )
{
b2Yield();
time2 = glfwGetTime();
//++loopCount;
}

frameTime = (float)( time2 - time1 );
// if (frame % 17 == 0)
//{
// printf("loop count = %d, frame time = %.1f\n", loopCount, 1000.0f * frameTime);
// }
//++frame;
frameTime = float( time2 - time1 );
}

delete s_sample;
Expand Down
29 changes: 22 additions & 7 deletions samples/sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,8 @@ Sample::Sample( Settings& settings )

m_threadCount = 1 + settings.workerCount;

b2WorldDef worldDef = b2DefaultWorldDef();
worldDef.workerCount = settings.workerCount;
worldDef.enqueueTask = EnqueueTask;
worldDef.finishTask = FinishTask;
worldDef.userTaskContext = this;
worldDef.enableSleep = settings.enableSleep;
m_worldId = b2_nullWorldId;

m_worldId = b2CreateWorld( &worldDef );
m_textLine = 30;
m_textIncrement = 22;
m_mouseJointId = b2_nullJointId;
Expand All @@ -122,6 +116,9 @@ Sample::Sample( Settings& settings )

g_seed = RAND_SEED;

m_settings = &settings;

CreateWorld( );
TestMathCpp();
}

Expand All @@ -134,6 +131,24 @@ Sample::~Sample()
delete[] m_tasks;
}

void Sample::CreateWorld( )
{
if ( B2_IS_NON_NULL( m_worldId ) )
{
b2DestroyWorld( m_worldId );
m_worldId = b2_nullWorldId;
}

b2WorldDef worldDef = b2DefaultWorldDef();
worldDef.workerCount = m_settings->workerCount;
worldDef.enqueueTask = EnqueueTask;
worldDef.finishTask = FinishTask;
worldDef.userTaskContext = this;
worldDef.enableSleep = m_settings->enableSleep;

m_worldId = b2CreateWorld( &worldDef );
}

void Sample::DrawTitle( const char* string )
{
g_draw.DrawString( 5, 5, string );
Expand Down
7 changes: 4 additions & 3 deletions samples/sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@

#include "box2d/id.h"
#include "box2d/types.h"
#include "settings.h"

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

struct Settings;

namespace enki
{
class TaskScheduler;
Expand Down Expand Up @@ -43,6 +42,8 @@ class Sample
explicit Sample( Settings& settings );
virtual ~Sample();

void CreateWorld( );

void DrawTitle( const char* string );
virtual void Step( Settings& settings );
virtual void UpdateUI()
Expand All @@ -66,9 +67,9 @@ class Sample
static constexpr int m_maxTasks = 64;
static constexpr int m_maxThreads = 64;

const Settings* m_settings;
enki::TaskScheduler* m_scheduler;
class SampleTask* m_tasks;

int m_taskCount;
int m_threadCount;

Expand Down
29 changes: 22 additions & 7 deletions samples/sample_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ class BenchmarkLargePyramid : public Sample
settings.enableSleep = false;
}

CreateLargePyramid(m_worldId);
CreateLargePyramid( m_worldId );
}

static Sample* Create( Settings& settings )
Expand Down Expand Up @@ -624,13 +624,18 @@ class BenchmarkCreateDestroy : public Sample
m_bodies[i] = b2_nullBodyId;
}

m_createTime = 0.0f;
m_destroyTime = 0.0f;

m_baseCount = g_sampleDebug ? 40 : 100;
m_iterations = g_sampleDebug ? 1 : 10;
m_bodyCount = 0;
}

void CreateScene()
{
uint64_t ticks = b2GetTicks();

for ( int i = 0; i < e_maxBodyCount; ++i )
{
if ( B2_IS_NON_NULL( m_bodies[i] ) )
Expand All @@ -640,6 +645,8 @@ class BenchmarkCreateDestroy : public Sample
}
}

m_destroyTime += b2GetMillisecondsAndReset( &ticks );

int count = m_baseCount;
float rad = 0.5f;
float shift = rad * 2.0f;
Expand Down Expand Up @@ -675,22 +682,28 @@ class BenchmarkCreateDestroy : public Sample
}
}

m_createTime += b2GetMilliseconds( ticks );

m_bodyCount = index;

b2World_Step( m_worldId, 1.0f / 60.0f, 4 );
}

void Step( Settings& settings ) override
{
uint64_t ticks = b2GetTicks();
m_createTime = 0.0f;
m_destroyTime = 0.0f;

for ( int i = 0; i < m_iterations; ++i )
{
CreateScene();
}

float ms = b2GetMilliseconds( ticks );
DrawTextLine( "total: create = %g ms, destroy = %g ms", m_createTime, m_destroyTime );

g_draw.DrawString( 5, m_textLine, "milliseconds = %g", ms );
m_textLine += m_textIncrement;
float createPerBody = 1000.0f * m_createTime / m_iterations / m_bodyCount;
float destroyPerBody = 1000.0f * m_destroyTime / m_iterations / m_bodyCount;
DrawTextLine( "body: create = %g us, destroy = %g us", createPerBody, destroyPerBody );

Sample::Step( settings );
}
Expand All @@ -700,6 +713,8 @@ class BenchmarkCreateDestroy : public Sample
return new BenchmarkCreateDestroy( settings );
}

float m_createTime;
float m_destroyTime;
b2BodyId m_bodies[e_maxBodyCount];
int m_bodyCount;
int m_baseCount;
Expand Down Expand Up @@ -1529,14 +1544,14 @@ class BenchmarkRain : public Sample

void Step( Settings& settings ) override
{
if (settings.pause == false || settings.singleStep == true)
if ( settings.pause == false || settings.singleStep == true )
{
StepRain( m_worldId, m_stepCount );
}

Sample::Step( settings );

if (m_stepCount % 1000 == 0)
if ( m_stepCount % 1000 == 0 )
{
m_stepCount += 0;
}
Expand Down
91 changes: 90 additions & 1 deletion samples/sample_shapes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,96 @@ class Friction : public Sample
}
};

static int sampleIndex3 = RegisterSample( "Shapes", "Friction", Friction::Create );
static int sampleFriction = RegisterSample( "Shapes", "Friction", Friction::Create );

class RollingResistance : public Sample
{
public:
explicit RollingResistance( Settings& settings )
: Sample( settings )
{
if ( settings.restart == false )
{
g_camera.m_center = { 5.0f, 20.0f };
g_camera.m_zoom = 27.5f;
}

m_lift = 0.0f;
CreateScene();
}

void CreateScene()
{
b2Circle circle = { b2Vec2_zero, 0.5f };

b2ShapeDef shapeDef = b2DefaultShapeDef();

for ( int i = 0; i < 20; ++i )
{
b2BodyDef bodyDef = b2DefaultBodyDef();
b2BodyId groundId = b2CreateBody( m_worldId, &bodyDef );

b2Segment segment = { { -40.0f, 2.0f * i }, { 40.0f, 2.0f * i + m_lift } };
b2CreateSegmentShape( groundId, &shapeDef, &segment );

bodyDef.type = b2_dynamicBody;
bodyDef.position = { -39.5f, 2.0f * i + 0.75f };
bodyDef.angularVelocity = -10.0f;
bodyDef.linearVelocity = { 5.0f, 0.0f };

b2BodyId bodyId = b2CreateBody( m_worldId, &bodyDef );
shapeDef.rollingResistance = 0.1f * i;
b2CreateCircleShape( bodyId, &shapeDef, &circle );
}
}

void Keyboard( int key ) override
{
switch ( key )
{
case GLFW_KEY_1:
m_lift = 0.0f;
CreateWorld();
CreateScene();
break;

case GLFW_KEY_2:
m_lift = 5.0f;
CreateWorld();
CreateScene();
break;

case GLFW_KEY_3:
m_lift = -5.0f;
CreateWorld();
CreateScene();
break;

default:
Sample::Keyboard( key );
break;
}
}

void Step( Settings& settings ) override
{
Sample::Step( settings );

for ( int i = 0; i < 20; ++i )
{
g_draw.DrawString( { -41.5f, 2.0f * i + 1.0f }, "%.2f", 0.1f * i );
}
}

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

float m_lift;
};

static int sampleRollingResistance = RegisterSample( "Shapes", "Rolling Resistance", RollingResistance::Create );

// This sample shows how to modify the geometry on an existing shape. This is only supported on
// dynamic and kinematic shapes because static shapes don't look for new collisions.
Expand Down
Loading

0 comments on commit b6984de

Please sign in to comment.