From cb54cd677f3eae444c2ff972f2064e68f9274ae1 Mon Sep 17 00:00:00 2001 From: Erin Catto Date: Thu, 29 Aug 2024 21:47:18 -0700 Subject: [PATCH 1/7] renamed smooth segment to chain segment --- docs/collision.md | 18 +++---- docs/migration.md | 4 +- docs/simulation.md | 9 ++-- include/box2d/box2d.h | 6 +-- include/box2d/collision.h | 20 +++---- include/box2d/types.h | 8 +-- samples/sample_bodies.cpp | 6 +-- samples/sample_collision.cpp | 50 +++++++++--------- src/contact.c | 18 +++---- src/manifold.c | 34 ++++++------ src/shape.c | 100 +++++++++++++++++------------------ src/shape.h | 2 +- src/solver.c | 8 +-- src/world.c | 4 +- 14 files changed, 142 insertions(+), 145 deletions(-) diff --git a/docs/collision.md b/docs/collision.md index 7977de0de..406794add 100644 --- a/docs/collision.md +++ b/docs/collision.md @@ -160,7 +160,7 @@ If edge1 did not exist this collision would seem fine. With edge1 present, the internal collision seems like a bug. But normally when Box2D collides two shapes, it views them in isolation. -`b2SmoothSegment` provides a mechanism for eliminating ghost +`b2ChainSegment` provides a mechanism for eliminating ghost collisions by storing the adjacent *ghost* vertices. Box2D uses these ghost vertices to prevent internal collisions. @@ -171,21 +171,21 @@ one-sided collision. The front face is to the right when looking from the first vertex towards the second vertex. This matches the counter-clockwise winding order used by polygons. -### Smooth segment -Smooth segments use a concept called *ghost vertices* that Box2D can use to eliminate ghost +### Chain segment +Chain segments use a concept called *ghost vertices* that Box2D can use to eliminate ghost collisions. ```c -b2SmoothSegment smoothSegment = {0}; -smoothSegment.ghost1 = (b2Vec2){1.7f, 0.0f}; -smoothSegment.segment = (b2Segment){{1.0f, 0.25f}, {0.0f, 0.0f}}; -smoothSegment.ghost2 = (b2Vec2){-1.7f, 0.4f}; +b2ChainSegment chainSegment = {0}; +chainSegment.ghost1 = (b2Vec2){1.7f, 0.0f}; +chainSegment.segment = (b2Segment){{1.0f, 0.25f}, {0.0f, 0.0f}}; +chainSegment.ghost2 = (b2Vec2){-1.7f, 0.4f}; ``` -These ghost vertices must align with vertices of neighboring smooth segments, making them +These ghost vertices must align with vertices of neighboring chain segments, making them tedious and error-prone to setup. -Smooth segments are not created directly. Instead, you can create chains of smooth +Chain segments are not created directly. Instead, you can create chains of line segments. See `b2ChainDef` and `b2CreateChain()`. ## Geometric Queries diff --git a/docs/migration.md b/docs/migration.md index 22b83e1ee..6132bc465 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -162,9 +162,9 @@ chainDef.loop = true; b2ChainId chainId = b2CreateChain(bodyId, &chainDef); ``` -Since chains are their own concept now, they get their own identifier, `b2ChainId`. You can view chains as macro objects, they create many `b2SmoothSegment` shapes internally. Normally you don't interact with these. However they are returned from queries. You can use `b2Shape_GetParentChain()` to get the `b2ChainId` for a smooth segment that you get from a query. +Since chains are their own concept now, they get their own identifier, `b2ChainId`. You can view chains as macro objects, they create many `b2ChainSegment` shapes internally. Normally you don't interact with these. However they are returned from queries. You can use `b2Shape_GetParentChain()` to get the `b2ChainId` for a chain segment that you get from a query. -> DO NOT destroy or modify a `b2SmoothSegment` that belongs to a chain shape directly +> DO NOT destroy or modify a `b2ChainSegment` that belongs to a chain shape directly ### Creating a joint Joints are very similar in v3.0. The lack of C member functions changes initialization. diff --git a/docs/simulation.md b/docs/simulation.md index a4f2bf2e8..19c7f270a 100644 --- a/docs/simulation.md +++ b/docs/simulation.md @@ -860,16 +860,15 @@ problems. Make sure all your points are more than than about a centimeter apart. ![Self Intersection is Bad](images/self_intersect.svg) -Each segment in the chain is created as a `b2SmoothSegment` shape on the body. If you have the -shape id for a smooth segment shape, you can get the owning chain id. This will return `b2_nullChainId` -if the shape is not a smooth segment. +Each segment in the chain is created as a `b2ChainSegment` shape on the body. If you have the +shape id for a chain segment shape, you can get the owning chain id. This will return `b2_nullChainId` +if the shape is not a chain segment. ```c b2ChainId chainId = b2SHape_GetParentChain(myShapeId); ``` -You cannot create a smooth segment shape directly. - +You cannot create a chain segment shape directly. ### Sensors Sometimes game logic needs to know when two shapes overlap yet there diff --git a/include/box2d/box2d.h b/include/box2d/box2d.h index c7d80d5dc..6d8ee9603 100644 --- a/include/box2d/box2d.h +++ b/include/box2d/box2d.h @@ -529,9 +529,9 @@ B2_API b2Circle b2Shape_GetCircle( b2ShapeId shapeId ); /// Get a copy of the shape's line segment. Asserts the type is correct. B2_API b2Segment b2Shape_GetSegment( b2ShapeId shapeId ); -/// Get a copy of the shape's smooth line segment. These come from chain shapes. +/// Get a copy of the shape's chain segment. These come from chain shapes. /// Asserts the type is correct. -B2_API b2SmoothSegment b2Shape_GetSmoothSegment( b2ShapeId shapeId ); +B2_API b2ChainSegment b2Shape_GetChainSegment( b2ShapeId shapeId ); /// Get a copy of the shape's capsule. Asserts the type is correct. B2_API b2Capsule b2Shape_GetCapsule( b2ShapeId shapeId ); @@ -557,7 +557,7 @@ B2_API void b2Shape_SetSegment( b2ShapeId shapeId, const b2Segment* segment ); /// @see b2Body_ApplyMassFromShapes B2_API void b2Shape_SetPolygon( b2ShapeId shapeId, const b2Polygon* polygon ); -/// Get the parent chain id if the shape type is b2_smoothSegmentShape, otherwise +/// Get the parent chain id if the shape type is a chain segment, otherwise /// returns b2_nullChainId. B2_API b2ChainId b2Shape_GetParentChain( b2ShapeId shapeId ); diff --git a/include/box2d/collision.h b/include/box2d/collision.h index 1430e3201..facd1fef2 100644 --- a/include/box2d/collision.h +++ b/include/box2d/collision.h @@ -13,7 +13,7 @@ typedef struct b2Capsule b2Capsule; typedef struct b2DistanceCache b2DistanceCache; typedef struct b2Polygon b2Polygon; typedef struct b2Segment b2Segment; -typedef struct b2SmoothSegment b2SmoothSegment; +typedef struct b2ChainSegment b2ChainSegment; typedef struct b2Hull b2Hull; @@ -153,10 +153,10 @@ typedef struct b2Segment b2Vec2 point2; } b2Segment; -/// A smooth line segment with one-sided collision. Only collides on the right side. +/// A line segment with one-sided collision. Only collides on the right side. /// Several of these are generated for a chain shape. /// ghost1 -> point1 -> point2 -> ghost2 -typedef struct b2SmoothSegment +typedef struct b2ChainSegment { /// The tail ghost vertex b2Vec2 ghost1; @@ -169,7 +169,7 @@ typedef struct b2SmoothSegment /// The owning chain shape index (internal usage only) int32_t chainId; -} b2SmoothSegment; +} b2ChainSegment; /// Validate ray cast input data (NaN, etc) B2_API bool b2IsValidRay( const b2RayCastInput* input ); @@ -554,16 +554,16 @@ B2_API b2Manifold b2CollidePolygons( const b2Polygon* polygonA, b2Transform xfA, B2_API b2Manifold b2CollideSegmentAndPolygon( const b2Segment* segmentA, b2Transform xfA, const b2Polygon* polygonB, b2Transform xfB ); -/// Compute the contact manifold between a smooth segment and a circle -B2_API b2Manifold b2CollideSmoothSegmentAndCircle( const b2SmoothSegment* smoothSegmentA, b2Transform xfA, +/// Compute the contact manifold between a chain segment and a circle +B2_API b2Manifold b2CollideChainSegmentAndCircle( const b2ChainSegment* segmentA, b2Transform xfA, const b2Circle* circleB, b2Transform xfB ); -/// Compute the contact manifold between an segment and a capsule -B2_API b2Manifold b2CollideSmoothSegmentAndCapsule( const b2SmoothSegment* smoothSegmentA, b2Transform xfA, +/// Compute the contact manifold between a chain segment and a capsule +B2_API b2Manifold b2CollideChainSegmentAndCapsule( const b2ChainSegment* segmentA, b2Transform xfA, const b2Capsule* capsuleB, b2Transform xfB, b2DistanceCache* cache ); -/// Compute the contact manifold between a smooth segment and a rounded polygon -B2_API b2Manifold b2CollideSmoothSegmentAndPolygon( const b2SmoothSegment* smoothSegmentA, b2Transform xfA, +/// Compute the contact manifold between a chain segment and a rounded polygon +B2_API b2Manifold b2CollideChainSegmentAndPolygon( const b2ChainSegment* segmentA, b2Transform xfA, const b2Polygon* polygonB, b2Transform xfB, b2DistanceCache* cache ); /**@}*/ diff --git a/include/box2d/types.h b/include/box2d/types.h index d6c753b36..0f57840ff 100644 --- a/include/box2d/types.h +++ b/include/box2d/types.h @@ -292,8 +292,8 @@ typedef enum b2ShapeType /// A convex polygon b2_polygonShape, - /// A smooth segment owned by a chain shape - b2_smoothSegmentShape, + /// A line segment owned by a chain shape + b2_chainSegmentShape, /// The number of shape types b2_shapeTypeCount @@ -356,7 +356,7 @@ typedef struct b2ShapeDef /// @ingroup shape B2_API b2ShapeDef b2DefaultShapeDef( void ); -/// Used to create a chain of edges. This is designed to eliminate ghost collisions with some limitations. +/// Used to create a chain of line segments. This is designed to eliminate ghost collisions with some limitations. /// - chains are one-sided /// - chains have no mass and should be used on static bodies /// - chains have a counter-clockwise winding order @@ -366,7 +366,7 @@ B2_API b2ShapeDef b2DefaultShapeDef( void ); /// - a chain shape should not self intersect (this is not validated) /// - an open chain shape has NO COLLISION on the first and final edge /// - you may overlap two open chains on their first three and/or last three points to get smooth collision -/// - a chain shape creates multiple smooth edges shapes on the body +/// - a chain shape creates multiple line segment shapes on the body /// https://en.wikipedia.org/wiki/Polygonal_chain /// Must be initialized using b2DefaultChainDef(). /// @warning Do not use chain shapes unless you understand the limitations. This is an advanced feature. diff --git a/samples/sample_bodies.cpp b/samples/sample_bodies.cpp index a9ef0d550..1d5017cd8 100644 --- a/samples/sample_bodies.cpp +++ b/samples/sample_bodies.cpp @@ -289,7 +289,7 @@ static int sampleBodyType = RegisterSample( "Bodies", "Body Type", BodyType::Cre /// This is a test of typical character collision scenarios. This does not /// show how you should implement a character in your application. -/// Instead this is used to test smooth collision on edge chains. +/// Instead this is used to test smooth collision on chain shapes. class Character : public Sample { public: @@ -347,7 +347,7 @@ class Character : public Sample // Square tiles. This shows that adjacency shapes may have non-smooth collision. Box2D has no solution // to this problem. - // TODO_ERIN try this: https://briansemrau.github.io/dealing-with-ghost-collisions/ + // todo_erin try this: https://briansemrau.github.io/dealing-with-ghost-collisions/ { b2BodyDef bodyDef = b2DefaultBodyDef(); b2BodyId groundId = b2CreateBody( m_worldId, &bodyDef ); @@ -454,8 +454,6 @@ class Character : public Sample m_textLine += m_textIncrement; g_draw.DrawString( 5, m_textLine, "Limitation: square and hexagon can snag on aligned boxes." ); m_textLine += m_textIncrement; - g_draw.DrawString( 5, m_textLine, "Feature: edge chains have smooth collision inside and out." ); - m_textLine += m_textIncrement; } static Sample* Create( Settings& settings ) diff --git a/samples/sample_collision.cpp b/samples/sample_collision.cpp index 869727824..b2bde09d1 100644 --- a/samples/sample_collision.cpp +++ b/samples/sample_collision.cpp @@ -2657,15 +2657,15 @@ class Manifold : public Sample offset = { -10.0f, 5.0f }; - // smooth-segment vs circle + // chain-segment vs circle { - b2SmoothSegment segment = { { 2.0f, 1.0f }, { { 1.0f, 1.0f }, { -1.0f, 0.0f } }, { -2.0f, 0.0f }, -1 }; + b2ChainSegment segment = { { 2.0f, 1.0f }, { { 1.0f, 1.0f }, { -1.0f, 0.0f } }, { -2.0f, 0.0f }, -1 }; b2Circle circle = { { 0.0f, 0.0f }, 0.5f }; b2Transform transform1 = { offset, b2Rot_identity }; b2Transform transform2 = { b2Add( m_transform.p, offset ), m_transform.q }; - b2Manifold m = b2CollideSmoothSegmentAndCircle( &segment, transform1, &circle, transform2 ); + b2Manifold m = b2CollideChainSegmentAndCircle( &segment, transform1, &circle, transform2 ); b2Vec2 g1 = b2TransformPoint( transform1, segment.ghost1 ); b2Vec2 g2 = b2TransformPoint( transform1, segment.ghost2 ); @@ -2681,22 +2681,22 @@ class Manifold : public Sample offset.x += 2.0f * increment.x; } - // smooth-segment vs rounded polygon + // chain-segment vs rounded polygon { - b2SmoothSegment segment1 = { { 2.0f, 1.0f }, { { 1.0f, 1.0f }, { -1.0f, 0.0f } }, { -2.0f, 0.0f }, -1 }; - b2SmoothSegment segment2 = { { 3.0f, 1.0f }, { { 2.0f, 1.0f }, { 1.0f, 1.0f } }, { -1.0f, 0.0f }, -1 }; - // b2SmoothSegment segment1 = {{2.0f, 0.0f}, {{1.0f, 0.0f}, {-1.0f, 0.0f}}, {-2.0f, 0.0f}, -1}; - // b2SmoothSegment segment2 = {{3.0f, 0.0f}, {{2.0f, 0.0f}, {1.0f, 0.0f}}, {-1.0f, 0.0f}, -1}; - // b2SmoothSegment segment1 = {{0.5f, 1.0f}, {{0.0f, 2.0f}, {-0.5f, 1.0f}}, {-1.0f, 0.0f}, -1}; - // b2SmoothSegment segment2 = {{1.0f, 0.0f}, {{0.5f, 1.0f}, {0.0f, 2.0f}}, {-0.5f, 1.0f}, -1}; + b2ChainSegment segment1 = { { 2.0f, 1.0f }, { { 1.0f, 1.0f }, { -1.0f, 0.0f } }, { -2.0f, 0.0f }, -1 }; + b2ChainSegment segment2 = { { 3.0f, 1.0f }, { { 2.0f, 1.0f }, { 1.0f, 1.0f } }, { -1.0f, 0.0f }, -1 }; + // b2ChainSegment segment1 = {{2.0f, 0.0f}, {{1.0f, 0.0f}, {-1.0f, 0.0f}}, {-2.0f, 0.0f}, -1}; + // b2ChainSegment segment2 = {{3.0f, 0.0f}, {{2.0f, 0.0f}, {1.0f, 0.0f}}, {-1.0f, 0.0f}, -1}; + // b2ChainSegment segment1 = {{0.5f, 1.0f}, {{0.0f, 2.0f}, {-0.5f, 1.0f}}, {-1.0f, 0.0f}, -1}; + // b2ChainSegment segment2 = {{1.0f, 0.0f}, {{0.5f, 1.0f}, {0.0f, 2.0f}}, {-0.5f, 1.0f}, -1}; float h = 0.5f - m_round; b2Polygon rox = b2MakeRoundedBox( h, h, m_round ); b2Transform transform1 = { offset, b2Rot_identity }; b2Transform transform2 = { b2Add( m_transform.p, offset ), m_transform.q }; - b2Manifold m1 = b2CollideSmoothSegmentAndPolygon( &segment1, transform1, &rox, transform2, &m_smgroxCache1 ); - b2Manifold m2 = b2CollideSmoothSegmentAndPolygon( &segment2, transform1, &rox, transform2, &m_smgroxCache2 ); + b2Manifold m1 = b2CollideChainSegmentAndPolygon( &segment1, transform1, &rox, transform2, &m_smgroxCache1 ); + b2Manifold m2 = b2CollideChainSegmentAndPolygon( &segment2, transform1, &rox, transform2, &m_smgroxCache2 ); { b2Vec2 g1 = b2TransformPoint( transform1, segment1.ghost1 ); @@ -2729,17 +2729,17 @@ class Manifold : public Sample offset.x += 2.0f * increment.x; } - // smooth-segment vs capsule + // chain-segment vs capsule { - b2SmoothSegment segment1 = { { 2.0f, 1.0f }, { { 1.0f, 1.0f }, { -1.0f, 0.0f } }, { -2.0f, 0.0f }, -1 }; - b2SmoothSegment segment2 = { { 3.0f, 1.0f }, { { 2.0f, 1.0f }, { 1.0f, 1.0f } }, { -1.0f, 0.0f }, -1 }; + b2ChainSegment segment1 = { { 2.0f, 1.0f }, { { 1.0f, 1.0f }, { -1.0f, 0.0f } }, { -2.0f, 0.0f }, -1 }; + b2ChainSegment segment2 = { { 3.0f, 1.0f }, { { 2.0f, 1.0f }, { 1.0f, 1.0f } }, { -1.0f, 0.0f }, -1 }; b2Capsule capsule = { { -0.5f, 0.0f }, { 0.5f, 0.0 }, 0.25f }; b2Transform transform1 = { offset, b2Rot_identity }; b2Transform transform2 = { b2Add( m_transform.p, offset ), m_transform.q }; - b2Manifold m1 = b2CollideSmoothSegmentAndCapsule( &segment1, transform1, &capsule, transform2, &m_smgcapCache1 ); - b2Manifold m2 = b2CollideSmoothSegmentAndCapsule( &segment2, transform1, &capsule, transform2, &m_smgcapCache2 ); + b2Manifold m1 = b2CollideChainSegmentAndCapsule( &segment1, transform1, &capsule, transform2, &m_smgcapCache1 ); + b2Manifold m2 = b2CollideChainSegmentAndCapsule( &segment2, transform1, &capsule, transform2, &m_smgcapCache2 ); { b2Vec2 g1 = b2TransformPoint( transform1, segment1.ghost1 ); @@ -2882,7 +2882,7 @@ class SmoothManifold : public Sample points[34] = { -15.29175, 14.54175 }; points[35] = { -19.2605, 14.54175 }; - m_segments = (b2SmoothSegment*)malloc( m_count * sizeof( b2SmoothSegment ) ); + m_segments = (b2ChainSegment*)malloc( m_count * sizeof( b2ChainSegment ) ); for ( int i = 0; i < m_count; ++i ) { @@ -3037,14 +3037,14 @@ class SmoothManifold : public Sample for ( int i = 0; i < m_count; ++i ) { - const b2SmoothSegment* segment = m_segments + i; + const b2ChainSegment* segment = m_segments + i; b2Vec2 p1 = b2TransformPoint( transform1, segment->segment.point1 ); b2Vec2 p2 = b2TransformPoint( transform1, segment->segment.point2 ); g_draw.DrawSegment( p1, p2, color1 ); g_draw.DrawPoint( p1, 4.0f, color1 ); } - // smooth-segment vs circle + // chain-segment vs circle if ( m_shapeType == e_circleShape ) { b2Circle circle = { { 0.0f, 0.0f }, 0.5f }; @@ -3052,8 +3052,8 @@ class SmoothManifold : public Sample for ( int i = 0; i < m_count; ++i ) { - const b2SmoothSegment* segment = m_segments + i; - b2Manifold m = b2CollideSmoothSegmentAndCircle( segment, transform1, &circle, transform2 ); + const b2ChainSegment* segment = m_segments + i; + b2Manifold m = b2CollideChainSegmentAndCircle( segment, transform1, &circle, transform2 ); DrawManifold( &m ); } } @@ -3065,9 +3065,9 @@ class SmoothManifold : public Sample for ( int i = 0; i < m_count; ++i ) { - const b2SmoothSegment* segment = m_segments + i; + const b2ChainSegment* segment = m_segments + i; b2DistanceCache cache = {}; - b2Manifold m = b2CollideSmoothSegmentAndPolygon( segment, transform1, &rox, transform2, &cache ); + b2Manifold m = b2CollideChainSegmentAndPolygon( segment, transform1, &rox, transform2, &cache ); DrawManifold( &m ); } } @@ -3080,7 +3080,7 @@ class SmoothManifold : public Sample ShapeType m_shapeType; - b2SmoothSegment* m_segments; + b2ChainSegment* m_segments; int m_count; b2Transform m_transform; diff --git a/src/contact.c b/src/contact.c index f530622b3..ae5ddff7e 100644 --- a/src/contact.c +++ b/src/contact.c @@ -128,23 +128,23 @@ static b2Manifold b2SegmentAndPolygonManifold( const b2Shape* shapeA, b2Transfor return b2CollideSegmentAndPolygon( &shapeA->segment, xfA, &shapeB->polygon, xfB ); } -static b2Manifold b2SmoothSegmentAndCircleManifold( const b2Shape* shapeA, b2Transform xfA, const b2Shape* shapeB, +static b2Manifold b2ChainSegmentAndCircleManifold( const b2Shape* shapeA, b2Transform xfA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache ) { B2_MAYBE_UNUSED( cache ); - return b2CollideSmoothSegmentAndCircle( &shapeA->smoothSegment, xfA, &shapeB->circle, xfB ); + return b2CollideChainSegmentAndCircle( &shapeA->chainSegment, xfA, &shapeB->circle, xfB ); } -static b2Manifold b2SmoothSegmentAndCapsuleManifold( const b2Shape* shapeA, b2Transform xfA, const b2Shape* shapeB, +static b2Manifold b2ChainSegmentAndCapsuleManifold( const b2Shape* shapeA, b2Transform xfA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache ) { - return b2CollideSmoothSegmentAndCapsule( &shapeA->smoothSegment, xfA, &shapeB->capsule, xfB, cache ); + return b2CollideChainSegmentAndCapsule( &shapeA->chainSegment, xfA, &shapeB->capsule, xfB, cache ); } -static b2Manifold b2SmoothSegmentAndPolygonManifold( const b2Shape* shapeA, b2Transform xfA, const b2Shape* shapeB, +static b2Manifold b2ChainSegmentAndPolygonManifold( const b2Shape* shapeA, b2Transform xfA, const b2Shape* shapeB, b2Transform xfB, b2DistanceCache* cache ) { - return b2CollideSmoothSegmentAndPolygon( &shapeA->smoothSegment, xfA, &shapeB->polygon, xfB, cache ); + return b2CollideChainSegmentAndPolygon( &shapeA->chainSegment, xfA, &shapeB->polygon, xfB, cache ); } static void b2AddType( b2ManifoldFcn* fcn, b2ShapeType type1, b2ShapeType type2 ) @@ -175,9 +175,9 @@ void b2InitializeContactRegisters( void ) b2AddType( b2SegmentAndCircleManifold, b2_segmentShape, b2_circleShape ); b2AddType( b2SegmentAndCapsuleManifold, b2_segmentShape, b2_capsuleShape ); b2AddType( b2SegmentAndPolygonManifold, b2_segmentShape, b2_polygonShape ); - b2AddType( b2SmoothSegmentAndCircleManifold, b2_smoothSegmentShape, b2_circleShape ); - b2AddType( b2SmoothSegmentAndCapsuleManifold, b2_smoothSegmentShape, b2_capsuleShape ); - b2AddType( b2SmoothSegmentAndPolygonManifold, b2_smoothSegmentShape, b2_polygonShape ); + b2AddType( b2ChainSegmentAndCircleManifold, b2_chainSegmentShape, b2_circleShape ); + b2AddType( b2ChainSegmentAndCapsuleManifold, b2_chainSegmentShape, b2_capsuleShape ); + b2AddType( b2ChainSegmentAndPolygonManifold, b2_chainSegmentShape, b2_polygonShape ); s_initialized = true; } } diff --git a/src/manifold.c b/src/manifold.c index cd46ee0b7..74b94c5be 100644 --- a/src/manifold.c +++ b/src/manifold.c @@ -713,7 +713,7 @@ b2Manifold b2CollideSegmentAndPolygon( const b2Segment* segmentA, b2Transform xf return b2CollidePolygons( &polygonA, xfA, polygonB, xfB ); } -b2Manifold b2CollideSmoothSegmentAndCircle( const b2SmoothSegment* smoothSegmentA, b2Transform xfA, const b2Circle* circleB, +b2Manifold b2CollideChainSegmentAndCircle( const b2ChainSegment* segmentA, b2Transform xfA, const b2Circle* circleB, b2Transform xfB ) { b2Manifold manifold = { 0 }; @@ -723,8 +723,8 @@ b2Manifold b2CollideSmoothSegmentAndCircle( const b2SmoothSegment* smoothSegment // Compute circle in frame of segment b2Vec2 pB = b2TransformPoint( xf, circleB->center ); - b2Vec2 p1 = smoothSegmentA->segment.point1; - b2Vec2 p2 = smoothSegmentA->segment.point2; + b2Vec2 p1 = segmentA->segment.point1; + b2Vec2 p2 = segmentA->segment.point2; b2Vec2 e = b2Sub( p2, p1 ); // Normal points to the right @@ -745,7 +745,7 @@ b2Manifold b2CollideSmoothSegmentAndCircle( const b2SmoothSegment* smoothSegment { // Behind point1? // Is pB in the Voronoi region of the previous edge? - b2Vec2 prevEdge = b2Sub( p1, smoothSegmentA->ghost1 ); + b2Vec2 prevEdge = b2Sub( p1, segmentA->ghost1 ); float uPrev = b2Dot( prevEdge, b2Sub( pB, p1 ) ); if ( uPrev <= 0.0f ) { @@ -757,7 +757,7 @@ b2Manifold b2CollideSmoothSegmentAndCircle( const b2SmoothSegment* smoothSegment else if ( u <= 0.0f ) { // Ahead of point2? - b2Vec2 nextEdge = b2Sub( smoothSegmentA->ghost2, p2 ); + b2Vec2 nextEdge = b2Sub( segmentA->ghost2, p2 ); float vNext = b2Dot( nextEdge, b2Sub( pB, p2 ) ); // Is pB in the Voronoi region of the next edge? @@ -801,11 +801,11 @@ b2Manifold b2CollideSmoothSegmentAndCircle( const b2SmoothSegment* smoothSegment return manifold; } -b2Manifold b2CollideSmoothSegmentAndCapsule( const b2SmoothSegment* segmentA, b2Transform xfA, const b2Capsule* capsuleB, +b2Manifold b2CollideChainSegmentAndCapsule( const b2ChainSegment* segmentA, b2Transform xfA, const b2Capsule* capsuleB, b2Transform xfB, b2DistanceCache* cache ) { b2Polygon polyB = b2MakeCapsule( capsuleB->center1, capsuleB->center2, capsuleB->radius ); - return b2CollideSmoothSegmentAndPolygon( segmentA, xfA, &polyB, xfB, cache ); + return b2CollideChainSegmentAndPolygon( segmentA, xfA, &polyB, xfB, cache ); } static b2Manifold b2ClipSegments( b2Vec2 a1, b2Vec2 a2, b2Vec2 b1, b2Vec2 b2, b2Vec2 normal, float ra, float rb, uint16_t id1, @@ -888,11 +888,11 @@ enum b2NormalType // This means the normal points in a direction that is smooth relative to a convex vertex and should be used for collision b2_normalAdmit, - // This means the normal is in a region of a concave vertex and should be snapped to the smooth segment normal + // This means the normal is in a region of a concave vertex and should be snapped to the segment normal b2_normalSnap }; -struct b2SmoothSegmentParams +struct b2ChainSegmentParams { b2Vec2 edge1; b2Vec2 normal0; @@ -903,7 +903,7 @@ struct b2SmoothSegmentParams // Evaluate Gauss map // See https://box2d.org/posts/2020/06/ghost-collisions/ -static enum b2NormalType b2ClassifyNormal( struct b2SmoothSegmentParams params, b2Vec2 normal ) +static enum b2NormalType b2ClassifyNormal( struct b2ChainSegmentParams params, b2Vec2 normal ) { const float sinTol = 0.01f; @@ -943,7 +943,7 @@ static enum b2NormalType b2ClassifyNormal( struct b2SmoothSegmentParams params, } } -b2Manifold b2CollideSmoothSegmentAndPolygon( const b2SmoothSegment* smoothSegmentA, b2Transform xfA, const b2Polygon* polygonB, +b2Manifold b2CollideChainSegmentAndPolygon( const b2ChainSegment* segmentA, b2Transform xfA, const b2Polygon* polygonB, b2Transform xfB, b2DistanceCache* cache ) { b2Manifold manifold = { 0 }; @@ -953,20 +953,20 @@ b2Manifold b2CollideSmoothSegmentAndPolygon( const b2SmoothSegment* smoothSegmen b2Vec2 centroidB = b2TransformPoint( xf, polygonB->centroid ); float radiusB = polygonB->radius; - b2Vec2 p1 = smoothSegmentA->segment.point1; - b2Vec2 p2 = smoothSegmentA->segment.point2; + b2Vec2 p1 = segmentA->segment.point1; + b2Vec2 p2 = segmentA->segment.point2; b2Vec2 edge1 = b2Normalize( b2Sub( p2, p1 ) ); - struct b2SmoothSegmentParams smoothParams = { 0 }; + struct b2ChainSegmentParams smoothParams = { 0 }; smoothParams.edge1 = edge1; const float convexTol = 0.01f; - b2Vec2 edge0 = b2Normalize( b2Sub( p1, smoothSegmentA->ghost1 ) ); + b2Vec2 edge0 = b2Normalize( b2Sub( p1, segmentA->ghost1 ) ); smoothParams.normal0 = b2RightPerp( edge0 ); smoothParams.convex1 = b2Cross( edge0, edge1 ) >= convexTol; - b2Vec2 edge2 = b2Normalize( b2Sub( smoothSegmentA->ghost2, p2 ) ); + b2Vec2 edge2 = b2Normalize( b2Sub( segmentA->ghost2, p2 ) ); smoothParams.normal2 = b2RightPerp( edge2 ); smoothParams.convex2 = b2Cross( edge1, edge2 ) >= convexTol; @@ -1003,7 +1003,7 @@ b2Manifold b2CollideSmoothSegmentAndPolygon( const b2SmoothSegment* smoothSegmen // Distance doesn't work correctly with partial polygons b2DistanceInput input; - input.proxyA = b2MakeProxy( &smoothSegmentA->segment.point1, 2, 0.0f ); + input.proxyA = b2MakeProxy( &segmentA->segment.point1, 2, 0.0f ); input.proxyB = b2MakeProxy( vertices, count, 0.0f ); input.transformA = b2Transform_identity; input.transformB = b2Transform_identity; diff --git a/src/shape.c b/src/shape.c index dea3c2962..ee502de01 100644 --- a/src/shape.c +++ b/src/shape.c @@ -97,8 +97,8 @@ static b2Shape* b2CreateShapeInternal( b2World* world, b2Body* body, b2Transform shape->segment = *(const b2Segment*)geometry; break; - case b2_smoothSegmentShape: - shape->smoothSegment = *(const b2SmoothSegment*)geometry; + case b2_chainSegmentShape: + shape->chainSegment = *(const b2ChainSegment*)geometry; break; default: @@ -342,39 +342,39 @@ b2ChainId b2CreateChain( b2BodyId bodyId, const b2ChainDef* def ) chainShape->count = n; chainShape->shapeIndices = b2Alloc( n * sizeof( int ) ); - b2SmoothSegment smoothSegment; + b2ChainSegment chainSegment; int prevIndex = n - 1; for ( int i = 0; i < n - 2; ++i ) { - smoothSegment.ghost1 = points[prevIndex]; - smoothSegment.segment.point1 = points[i]; - smoothSegment.segment.point2 = points[i + 1]; - smoothSegment.ghost2 = points[i + 2]; - smoothSegment.chainId = chainId; + chainSegment.ghost1 = points[prevIndex]; + chainSegment.segment.point1 = points[i]; + chainSegment.segment.point2 = points[i + 1]; + chainSegment.ghost2 = points[i + 2]; + chainSegment.chainId = chainId; prevIndex = i; - b2Shape* shape = b2CreateShapeInternal( world, body, transform, &shapeDef, &smoothSegment, b2_smoothSegmentShape ); + b2Shape* shape = b2CreateShapeInternal( world, body, transform, &shapeDef, &chainSegment, b2_chainSegmentShape ); chainShape->shapeIndices[i] = shape->id; } { - smoothSegment.ghost1 = points[n - 3]; - smoothSegment.segment.point1 = points[n - 2]; - smoothSegment.segment.point2 = points[n - 1]; - smoothSegment.ghost2 = points[0]; - smoothSegment.chainId = chainId; - b2Shape* shape = b2CreateShapeInternal( world, body, transform, &shapeDef, &smoothSegment, b2_smoothSegmentShape ); + chainSegment.ghost1 = points[n - 3]; + chainSegment.segment.point1 = points[n - 2]; + chainSegment.segment.point2 = points[n - 1]; + chainSegment.ghost2 = points[0]; + chainSegment.chainId = chainId; + b2Shape* shape = b2CreateShapeInternal( world, body, transform, &shapeDef, &chainSegment, b2_chainSegmentShape ); chainShape->shapeIndices[n - 2] = shape->id; } { - smoothSegment.ghost1 = points[n - 2]; - smoothSegment.segment.point1 = points[n - 1]; - smoothSegment.segment.point2 = points[0]; - smoothSegment.ghost2 = points[1]; - smoothSegment.chainId = chainId; - b2Shape* shape = b2CreateShapeInternal( world, body, transform, &shapeDef, &smoothSegment, b2_smoothSegmentShape ); + chainSegment.ghost1 = points[n - 2]; + chainSegment.segment.point1 = points[n - 1]; + chainSegment.segment.point2 = points[0]; + chainSegment.ghost2 = points[1]; + chainSegment.chainId = chainId; + b2Shape* shape = b2CreateShapeInternal( world, body, transform, &shapeDef, &chainSegment, b2_chainSegmentShape ); chainShape->shapeIndices[n - 1] = shape->id; } } @@ -383,17 +383,17 @@ b2ChainId b2CreateChain( b2BodyId bodyId, const b2ChainDef* def ) chainShape->count = n - 3; chainShape->shapeIndices = b2Alloc( n * sizeof( int ) ); - b2SmoothSegment smoothSegment; + b2ChainSegment chainSegment; for ( int i = 0; i < n - 3; ++i ) { - smoothSegment.ghost1 = points[i]; - smoothSegment.segment.point1 = points[i + 1]; - smoothSegment.segment.point2 = points[i + 2]; - smoothSegment.ghost2 = points[i + 3]; - smoothSegment.chainId = chainId; + chainSegment.ghost1 = points[i]; + chainSegment.segment.point1 = points[i + 1]; + chainSegment.segment.point2 = points[i + 2]; + chainSegment.ghost2 = points[i + 3]; + chainSegment.chainId = chainId; - b2Shape* shape = b2CreateShapeInternal( world, body, transform, &shapeDef, &smoothSegment, b2_smoothSegmentShape ); + b2Shape* shape = b2CreateShapeInternal( world, body, transform, &shapeDef, &chainSegment, b2_chainSegmentShape ); chainShape->shapeIndices[i] = shape->id; } } @@ -466,8 +466,8 @@ b2AABB b2ComputeShapeAABB( const b2Shape* shape, b2Transform xf ) return b2ComputePolygonAABB( &shape->polygon, xf ); case b2_segmentShape: return b2ComputeSegmentAABB( &shape->segment, xf ); - case b2_smoothSegmentShape: - return b2ComputeSegmentAABB( &shape->smoothSegment.segment, xf ); + case b2_chainSegmentShape: + return b2ComputeSegmentAABB( &shape->chainSegment.segment, xf ); default: { B2_ASSERT( false ); @@ -489,8 +489,8 @@ b2Vec2 b2GetShapeCentroid( const b2Shape* shape ) return shape->polygon.centroid; case b2_segmentShape: return b2Lerp( shape->segment.point1, shape->segment.point2, 0.5f ); - case b2_smoothSegmentShape: - return b2Lerp( shape->smoothSegment.segment.point1, shape->smoothSegment.segment.point2, 0.5f ); + case b2_chainSegmentShape: + return b2Lerp( shape->chainSegment.segment.point1, shape->chainSegment.segment.point2, 0.5f ); default: return b2Vec2_zero; } @@ -524,8 +524,8 @@ float b2GetShapePerimeter( const b2Shape* shape ) } case b2_segmentShape: return 2.0f * b2Length( b2Sub( shape->segment.point1, shape->segment.point2 ) ); - case b2_smoothSegmentShape: - return 2.0f * b2Length( b2Sub( shape->smoothSegment.segment.point1, shape->smoothSegment.segment.point2 ) ); + case b2_chainSegmentShape: + return 2.0f * b2Length( b2Sub( shape->chainSegment.segment.point1, shape->chainSegment.segment.point2 ) ); default: return 0.0f; } @@ -602,11 +602,11 @@ b2ShapeExtent b2ComputeShapeExtent( const b2Shape* shape, b2Vec2 localCenter ) } break; - case b2_smoothSegmentShape: + case b2_chainSegmentShape: { extent.minExtent = 0.0f; - b2Vec2 c1 = b2Sub( shape->smoothSegment.segment.point1, localCenter ); - b2Vec2 c2 = b2Sub( shape->smoothSegment.segment.point2, localCenter ); + b2Vec2 c1 = b2Sub( shape->chainSegment.segment.point1, localCenter ); + b2Vec2 c2 = b2Sub( shape->chainSegment.segment.point2, localCenter ); extent.maxExtent = sqrtf( b2MaxFloat( b2LengthSquared( c1 ), b2LengthSquared( c2 ) ) ); } break; @@ -639,8 +639,8 @@ b2CastOutput b2RayCastShape( const b2RayCastInput* input, const b2Shape* shape, case b2_segmentShape: output = b2RayCastSegment( &localInput, &shape->segment, false ); break; - case b2_smoothSegmentShape: - output = b2RayCastSegment( &localInput, &shape->smoothSegment.segment, true ); + case b2_chainSegmentShape: + output = b2RayCastSegment( &localInput, &shape->chainSegment.segment, true ); break; default: return output; @@ -677,8 +677,8 @@ b2CastOutput b2ShapeCastShape( const b2ShapeCastInput* input, const b2Shape* sha case b2_segmentShape: output = b2ShapeCastSegment( &localInput, &shape->segment ); break; - case b2_smoothSegmentShape: - output = b2ShapeCastSegment( &localInput, &shape->smoothSegment.segment ); + case b2_chainSegmentShape: + output = b2ShapeCastSegment( &localInput, &shape->chainSegment.segment ); break; default: return output; @@ -722,8 +722,8 @@ b2DistanceProxy b2MakeShapeDistanceProxy( const b2Shape* shape ) return b2MakeProxy( shape->polygon.vertices, shape->polygon.count, shape->polygon.radius ); case b2_segmentShape: return b2MakeProxy( &shape->segment.point1, 2, 0.0f ); - case b2_smoothSegmentShape: - return b2MakeProxy( &shape->smoothSegment.segment.point1, 2, 0.0f ); + case b2_chainSegmentShape: + return b2MakeProxy( &shape->chainSegment.segment.point1, 2, 0.0f ); default: { B2_ASSERT( false ); @@ -817,8 +817,8 @@ b2CastOutput b2Shape_RayCast( b2ShapeId shapeId, b2Vec2 origin, b2Vec2 translati output = b2RayCastPolygon( &input, &shape->polygon ); break; - case b2_smoothSegmentShape: - output = b2RayCastSegment( &input, &shape->smoothSegment.segment, true ); + case b2_chainSegmentShape: + output = b2RayCastSegment( &input, &shape->chainSegment.segment, true ); break; default: @@ -1088,12 +1088,12 @@ b2Segment b2Shape_GetSegment( b2ShapeId shapeId ) return shape->segment; } -b2SmoothSegment b2Shape_GetSmoothSegment( b2ShapeId shapeId ) +b2ChainSegment b2Shape_GetChainSegment( b2ShapeId shapeId ) { b2World* world = b2GetWorld( shapeId.world0 ); b2Shape* shape = b2GetShape( world, shapeId ); - B2_ASSERT( shape->type == b2_smoothSegmentShape ); - return shape->smoothSegment; + B2_ASSERT( shape->type == b2_chainSegmentShape ); + return shape->chainSegment; } b2Capsule b2Shape_GetCapsule( b2ShapeId shapeId ) @@ -1188,9 +1188,9 @@ b2ChainId b2Shape_GetParentChain( b2ShapeId shapeId ) { b2World* world = b2GetWorld( shapeId.world0 ); b2Shape* shape = b2GetShape( world, shapeId ); - if ( shape->type == b2_smoothSegmentShape ) + if ( shape->type == b2_chainSegmentShape ) { - int chainId = shape->smoothSegment.chainId; + int chainId = shape->chainSegment.chainId; if ( chainId != B2_NULL_INDEX ) { b2CheckId( world->chainArray, chainId ); diff --git a/src/shape.h b/src/shape.h index b089730a6..fd8e398b7 100644 --- a/src/shape.h +++ b/src/shape.h @@ -36,7 +36,7 @@ typedef struct b2Shape b2Circle circle; b2Polygon polygon; b2Segment segment; - b2SmoothSegment smoothSegment; + b2ChainSegment chainSegment; }; uint16_t revision; diff --git a/src/solver.c b/src/solver.c index de2be855e..a24ee9187 100644 --- a/src/solver.c +++ b/src/solver.c @@ -877,12 +877,12 @@ static bool b2ContinuousQueryCallback( int proxyId, int shapeId, void* context ) } } - // Prevent pausing on smooth segment junctions - if ( shape->type == b2_smoothSegmentShape ) + // Prevent pausing on chain segment junctions + if ( shape->type == b2_chainSegmentShape ) { b2Transform transform = bodySim->transform; - b2Vec2 p1 = b2TransformPoint( transform, shape->smoothSegment.segment.point1 ); - b2Vec2 p2 = b2TransformPoint( transform, shape->smoothSegment.segment.point2 ); + b2Vec2 p1 = b2TransformPoint( transform, shape->chainSegment.segment.point1 ); + b2Vec2 p2 = b2TransformPoint( transform, shape->chainSegment.segment.point2 ); b2Vec2 e = b2Sub( p2, p1 ); b2Vec2 c1 = continuousContext->centroid1; b2Vec2 c2 = continuousContext->centroid2; diff --git a/src/world.c b/src/world.c index d84728fd2..9229dcbc3 100644 --- a/src/world.c +++ b/src/world.c @@ -814,9 +814,9 @@ static void b2DrawShape( b2DebugDraw* draw, b2Shape* shape, b2Transform xf, b2He } break; - case b2_smoothSegmentShape: + case b2_chainSegmentShape: { - b2Segment* segment = &shape->smoothSegment.segment; + b2Segment* segment = &shape->chainSegment.segment; b2Vec2 p1 = b2TransformPoint( xf, segment->point1 ); b2Vec2 p2 = b2TransformPoint( xf, segment->point2 ); draw->DrawSegment( p1, p2, color, draw->context ); From 10febfc5ac606b214964ed69935e6dc177c10c6f Mon Sep 17 00:00:00 2001 From: Erin Catto Date: Thu, 29 Aug 2024 21:57:34 -0700 Subject: [PATCH 2/7] PR #779 --- CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c9648ca0..77eab8373 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,6 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") cmake_dependent_option(BOX2D_AVX2 "Enable AVX2" OFF "BOX2D_ENABLE_SIMD" OFF) endif() - if(PROJECT_IS_TOP_LEVEL) # Needed for samples.exe to find box2d.dll # set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") @@ -67,6 +66,13 @@ if(PROJECT_IS_TOP_LEVEL) option(BOX2D_VALIDATE "Enable heavy validation" ON) option(BOX2D_UNIT_TESTS "Build the Box2D unit tests" ON) + include(GNUInstallDirs) + + install( + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) + if(MSVC AND WIN32) # Enable edit and continue only in debug due to perf hit in release # add_link_options($<$:/INCREMENTAL>) From 1347aec82a22fba766c023498491b30e5903e8b0 Mon Sep 17 00:00:00 2001 From: Erin Catto Date: Thu, 29 Aug 2024 22:29:41 -0700 Subject: [PATCH 3/7] PR #754 --- samples/CMakeLists.txt | 1 + src/CMakeLists.txt | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 477afa08d..d6ac7a42b 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -45,6 +45,7 @@ add_library(imgui STATIC ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp ${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp ) + target_link_libraries(imgui PUBLIC glfw glad) target_include_directories(imgui PUBLIC ${IMGUI_DIR} ${IMGUI_DIR}/backends) target_compile_definitions(imgui PUBLIC IMGUI_DISABLE_OBSOLETE_FUNCTIONS) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index db1b331d6..b136d2cab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -88,6 +88,8 @@ target_include_directories(box2d ${CMAKE_CURRENT_SOURCE_DIR} ) +set(CMAKE_DEBUG_POSTFIX "d") + # Box2D uses C17 set_target_properties(box2d PROPERTIES C_STANDARD 17 @@ -95,6 +97,7 @@ set_target_properties(box2d PROPERTIES C_EXTENSIONS YES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} + DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX} ) if (BOX2D_PROFILE) @@ -176,4 +179,6 @@ endif() source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "src" FILES ${BOX2D_SOURCE_FILES}) source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/../include" PREFIX "include" FILES ${BOX2D_API_FILES}) +add_library(box2d::box2d ALIAS box2d) + install(TARGETS box2d) From 2c4374e3c8bcdcd5569b3e4aa806279635482637 Mon Sep 17 00:00:00 2001 From: Erin Catto Date: Thu, 29 Aug 2024 22:32:19 -0700 Subject: [PATCH 4/7] PR #749 --- docs/simulation.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/simulation.md b/docs/simulation.md index 19c7f270a..e3f5a0876 100644 --- a/docs/simulation.md +++ b/docs/simulation.md @@ -1492,13 +1492,6 @@ when multiple dynamic bodies interact. You can make this as large as you like. The frequency and damping ratio are used to create a spring/damper effect similar to the distance joint. -### Wheel Joint -The wheel joint restricts a point on bodyB to a line on bodyA. The wheel -joint also provides a suspension spring and a motor. See the `Driving` sample -for details. - -![Wheel Joint](images/wheel_joint.svg) - ### Weld Joint The weld joint attempts to constrain all relative motion between two bodies. See the `Cantilever` sample to see how the weld joint @@ -1521,6 +1514,12 @@ proportional the maximum motor force and torque. See `b2MotorJointDef` and the `MotorJoint` sample for details. ### Wheel Joint +The wheel joint restricts a point on bodyB to a line on bodyA. The wheel +joint also provides a suspension spring and a motor. See the `Driving` sample +for details. + +![Wheel Joint](images/wheel_joint.svg) + The wheel joint is designed specifically for vehicles. It provides a translation and rotation. The translation has a spring and damper to simulate the vehicle suspension. The rotation allows the wheel to rotate. You can specify an rotational From b511f67b14b0a939d82475fcd7b2032dc947b197 Mon Sep 17 00:00:00 2001 From: Erin Catto Date: Fri, 30 Aug 2024 23:29:26 -0700 Subject: [PATCH 5/7] #776 : typo some android stuff --- CMakeLists.txt | 2 +- docs/simulation.md | 2 +- src/allocate.c | 7 +++++++ src/core.h | 10 +++++----- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 77eab8373..631e057ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ if(PROJECT_IS_TOP_LEVEL) include(GNUInstallDirs) install( - DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include" + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/box2d" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) diff --git a/docs/simulation.md b/docs/simulation.md index e3f5a0876..9822babb7 100644 --- a/docs/simulation.md +++ b/docs/simulation.md @@ -1180,7 +1180,7 @@ or disable a joint. You can specify user data for any joint type and you can provide a flag to prevent the attached bodies from colliding with each other. This is the default behavior and you must set the `collideConnected` -Boolean to allow collision between to connected bodies. +Boolean to allow collision between two connected bodies. Many joint definitions require that you provide some geometric data. Often a joint will be defined by anchor points. These are points fixed diff --git a/src/allocate.c b/src/allocate.c index 5e832eff7..f49ff2822 100644 --- a/src/allocate.c +++ b/src/allocate.c @@ -67,6 +67,13 @@ void* b2Alloc( uint32_t size ) #ifdef B2_PLATFORM_WINDOWS void* ptr = _aligned_malloc( size32, B2_ALIGNMENT ); +#elif defined(B2_PLATFORM_ANDROID) + void* ptr = NULL; + if (posix_memalign(&ptr, B2_ALIGNMENT, size32) != 0) + { + // allocation failed, exit the application + exit(EXIT_FAILURE); + } #else void* ptr = aligned_alloc( B2_ALIGNMENT, size32 ); #endif diff --git a/src/core.h b/src/core.h index 62909202a..c3d61e9a0 100644 --- a/src/core.h +++ b/src/core.h @@ -42,9 +42,9 @@ #endif // Define CPU -#if defined( __x86_64__ ) || defined( _M_X64 ) - #define B2_CPU_X64 -#elif defined( __aarch64__ ) || defined( _M_ARM64 ) +#if defined( __x86_64__ ) || defined( _M_X64 ) || defined( __i386__ ) || defined( _M_IX86 ) + #define B2_CPU_X86_X64 +#elif defined( __aarch64__ ) || defined( _M_ARM64 ) || defined( __arm__ ) || defined( _M_ARM ) #define B2_CPU_ARM #elif defined( __EMSCRIPTEN__ ) #define B2_CPU_WASM @@ -54,7 +54,7 @@ // Define SIMD #if defined( BOX2D_ENABLE_SIMD ) - #if defined( B2_CPU_X64 ) + #if defined( B2_CPU_X86_X64 ) #if defined( BOX2D_AVX2 ) #define B2_SIMD_AVX2 #define B2_SIMD_WIDTH 8 @@ -96,7 +96,7 @@ } \ while ( 0 ) #elif defined( B2_COMPILER_GCC ) || defined( B2_COMPILER_CLANG ) - #if defined( B2_CPU_X64 ) + #if defined( B2_CPU_X86_X64 ) #define B2_BREAKPOINT __asm volatile( "int $0x3" ) #elif defined( B2_CPU_ARM ) #define B2_BREAKPOINT __builtin_trap() From 67d230629eb0b72b6e1697bbaa557c715b9959ed Mon Sep 17 00:00:00 2001 From: Erin Catto Date: Fri, 30 Aug 2024 23:44:30 -0700 Subject: [PATCH 6/7] breakpoint for #782 --- src/core.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core.h b/src/core.h index c3d61e9a0..d33f7a747 100644 --- a/src/core.h +++ b/src/core.h @@ -89,6 +89,8 @@ #if defined( B2_COMPILER_MSVC ) #define B2_BREAKPOINT __debugbreak() +#elif defined( B2_PLATFORM_ANDROID ) + #define B2_BREAKPOINT __builtin_trap() #elif defined( B2_PLATFORM_WASM ) #define B2_BREAKPOINT \ do \ From a1b1cbe571ae485120abe1b6ef4f926dc2af664d Mon Sep 17 00:00:00 2001 From: Erin Catto Date: Fri, 30 Aug 2024 23:53:08 -0700 Subject: [PATCH 7/7] cmake config stuff --- src/CMakeLists.txt | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b136d2cab..c3f23cec9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -181,4 +181,29 @@ source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/../include" PREFIX "include" FILE add_library(box2d::box2d ALIAS box2d) -install(TARGETS box2d) +install( + TARGETS box2d + EXPORT box2dConfig + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + +install( + EXPORT box2dConfig + NAMESPACE box2d:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/box2d" +) + +include(CMakePackageConfigHelpers) + +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/box2dConfigVersion.cmake" + COMPATIBILITY SameMajorVersion +) + +install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/box2dConfigVersion.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/box2d" +) +