From cad8599955ad7ce19e5a3aff753535c17eeca8ef Mon Sep 17 00:00:00 2001 From: Erin Catto Date: Wed, 22 Jan 2025 20:48:41 -0800 Subject: [PATCH] chain shape material (#874) adjusted chain time of impact to improve performance --- include/box2d/box2d.h | 7 +++++++ include/box2d/types.h | 4 ++++ samples/sample_benchmark.cpp | 13 +++++++++---- samples/sample_continuous.cpp | 10 +++++----- samples/sample_shapes.cpp | 6 +++--- src/shape.c | 32 +++++++++++++++++++++++++++++++- src/shape.h | 1 + src/solver.c | 2 +- 8 files changed, 61 insertions(+), 14 deletions(-) diff --git a/include/box2d/box2d.h b/include/box2d/box2d.h index 7ffaf426f..bee6e5c8a 100644 --- a/include/box2d/box2d.h +++ b/include/box2d/box2d.h @@ -708,6 +708,13 @@ B2_API void b2Chain_SetRestitution( b2ChainId chainId, float restitution ); /// Get the chain restitution B2_API float b2Chain_GetRestitution( b2ChainId chainId ); +/// Set the chain material +/// @see b2ChainDef::material +B2_API void b2Chain_SetMaterial( b2ChainId chainId, int material ); + +/// Get the chain material +B2_API int b2Chain_GetMaterial( b2ChainId chainId ); + /// Chain identifier validation. Provides validation for up to 64K allocations. B2_API bool b2Chain_IsValid( b2ChainId id ); diff --git a/include/box2d/types.h b/include/box2d/types.h index 1b77f36a9..dab2cee19 100644 --- a/include/box2d/types.h +++ b/include/box2d/types.h @@ -426,6 +426,10 @@ typedef struct b2ChainDef /// The restitution (elasticity) usually in the range [0,1]. float restitution; + /// User material identifier. This is passed with query results and to friction and restitution + /// combining functions. It is not used internally. + int material; + /// Contact filtering data. b2Filter filter; diff --git a/samples/sample_benchmark.cpp b/samples/sample_benchmark.cpp index 6439a623e..71c3338a6 100644 --- a/samples/sample_benchmark.cpp +++ b/samples/sample_benchmark.cpp @@ -16,6 +16,7 @@ #include #ifndef NDEBUG +extern "C" int b2_toiCalls; extern "C" int b2_toiHitCount; #endif @@ -1476,6 +1477,7 @@ class BenchmarkSpinner : public Sample } #ifndef NDEBUG + b2_toiCalls = 0; b2_toiHitCount = 0; #endif @@ -1486,13 +1488,16 @@ class BenchmarkSpinner : public Sample { Sample::Step( settings ); - if ( m_stepCount == 1000 ) + if ( m_stepCount == 1000 && false ) { - m_stepCount += 0; + // 0.1 : 46544, 25752 + // 0.25 : 5745, 1947 + // 0.5 : 2197, 660 + settings.pause = true; } + #ifndef NDEBUG - g_draw.DrawString( 5, m_textLine, "toi hits = %d", b2_toiHitCount ); - m_textLine += m_textIncrement; + DrawTextLine( "toi calls, hits = %d, %d", b2_toiCalls, b2_toiHitCount ); #endif } diff --git a/samples/sample_continuous.cpp b/samples/sample_continuous.cpp index dde3608bd..86387043a 100644 --- a/samples/sample_continuous.cpp +++ b/samples/sample_continuous.cpp @@ -330,15 +330,15 @@ class ChainDrop : public Sample b2ShapeDef shapeDef = b2DefaultShapeDef(); - //b2Circle circle = { { 0.0f, 0.0f }, 0.5f }; - //m_shapeId = b2CreateCircleShape( m_bodyId, &shapeDef, &circle ); + b2Circle circle = { { 0.0f, 0.0f }, 0.5f }; + m_shapeId = b2CreateCircleShape( m_bodyId, &shapeDef, &circle ); //b2Capsule capsule = { { -0.5f, 0.0f }, { 0.5f, 0.0 }, 0.25f }; //m_shapeId = b2CreateCapsuleShape( m_bodyId, &shapeDef, &capsule ); - float h = 0.5f; - b2Polygon box = b2MakeBox( h, h ); - m_shapeId = b2CreatePolygonShape( m_bodyId, &shapeDef, &box ); + //float h = 0.5f; + //b2Polygon box = b2MakeBox( h, h ); + //m_shapeId = b2CreatePolygonShape( m_bodyId, &shapeDef, &box ); } void UpdateUI() override diff --git a/samples/sample_shapes.cpp b/samples/sample_shapes.cpp index 508668967..a09d1e5d7 100644 --- a/samples/sample_shapes.cpp +++ b/samples/sample_shapes.cpp @@ -118,6 +118,7 @@ class ChainShape : public Sample chainDef.customColor = b2_colorSteelBlue; chainDef.isLoop = true; chainDef.friction = 0.2f; + chainDef.material = 42; b2BodyDef bodyDef = b2DefaultBodyDef(); m_groundId = b2CreateBody( m_worldId, &bodyDef ); @@ -210,8 +211,7 @@ class ChainShape : public Sample g_draw.DrawSegment( b2Vec2_zero, { 0.0f, 0.5f }, b2_colorGreen ); #ifndef NDEBUG - g_draw.DrawString( 5, m_textLine, "toi calls, hits = %d, %d", b2_toiCalls, b2_toiHitCount ); - m_textLine += m_textIncrement; + DrawTextLine( "toi calls, hits = %d, %d", b2_toiCalls, b2_toiHitCount ); #endif } @@ -814,7 +814,7 @@ class Restitution : public Sample } } - b2Circle circle = { }; + b2Circle circle = {}; circle.radius = 0.5f; b2Polygon box = b2MakeBox( 0.5f, 0.5f ); diff --git a/src/shape.c b/src/shape.c index 4b9454827..42dcd4793 100644 --- a/src/shape.c +++ b/src/shape.c @@ -371,13 +371,15 @@ b2ChainId b2CreateChain( b2BodyId bodyId, const b2ChainDef* def ) chainShape->generation += 1; chainShape->friction = def->friction; chainShape->restitution = def->restitution; + chainShape->material = def->material; body->headChainId = chainId; b2ShapeDef shapeDef = b2DefaultShapeDef(); shapeDef.userData = def->userData; - shapeDef.restitution = def->restitution; shapeDef.friction = def->friction; + shapeDef.restitution = def->restitution; + shapeDef.material = def->material; shapeDef.filter = def->filter; shapeDef.customColor = def->customColor; shapeDef.enableContactEvents = false; @@ -1417,6 +1419,34 @@ float b2Chain_GetRestitution( b2ChainId chainId ) return chainShape->restitution; } +void b2Chain_SetMaterial( b2ChainId chainId, int material ) +{ + b2World* world = b2GetWorldLocked( chainId.world0 ); + if ( world == NULL ) + { + return; + } + + b2ChainShape* chainShape = b2GetChainShape( world, chainId ); + chainShape->material = material; + + int count = chainShape->count; + + for ( int i = 0; i < count; ++i ) + { + int shapeId = chainShape->shapeIndices[i]; + b2Shape* shape = b2ShapeArray_Get( &world->shapes, shapeId ); + shape->material = material; + } +} + +int b2Chain_GetMaterial( b2ChainId chainId ) +{ + b2World* world = b2GetWorld( chainId.world0 ); + b2ChainShape* chainShape = b2GetChainShape( world, chainId ); + return chainShape->material; +} + int b2Shape_GetContactCapacity( b2ShapeId shapeId ) { b2World* world = b2GetWorldLocked( shapeId.world0 ); diff --git a/src/shape.h b/src/shape.h index 3ae8f6bd6..71b0278a1 100644 --- a/src/shape.h +++ b/src/shape.h @@ -57,6 +57,7 @@ typedef struct b2ChainShape int* shapeIndices; float friction; float restitution; + int material; uint16_t generation; } b2ChainShape; diff --git a/src/solver.c b/src/solver.c index 81e670807..bc37d6174 100644 --- a/src/solver.c +++ b/src/solver.c @@ -289,7 +289,7 @@ static bool b2ContinuousQueryCallback( int proxyId, int shapeId, void* context ) b2Vec2 c2 = continuousContext->centroid2; float offset2 = b2Cross( b2Sub( c2, p1 ), e ); - const float allowedFraction = 0.1f; + const float allowedFraction = 0.25f; if ( offset1 < 0.0f || offset1 - offset2 < allowedFraction * fastBodySim->minExtent ) { // Minimal clipping