Skip to content

Commit 30b6000

Browse files
authored
Joint events (#942)
Added joint events for when a joint force or torque exceeds a specified threshold. Joint definitions now include a base `b2JointDef` for common properties. Joint definitions now use local frames (b2Transform) instead of bespoke local axes and reference angles. The mouse and motor joints are now controlled by updating the joint frames. Flipped order of arguments in b2RelativeAngle to match similar functions. Improved joint debug draw.
1 parent 8c66146 commit 30b6000

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1525
-1251
lines changed

CMakeLists.txt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ if (MSVC OR APPLE)
3131
add_compile_options(-fsanitize=address -fsanitize-address-use-after-scope -fsanitize=undefined)
3232
add_link_options(-fsanitize=address -fsanitize-address-use-after-scope -fsanitize=undefined)
3333
endif()
34+
else()
35+
if(MSVC AND PROJECT_IS_TOP_LEVEL)
36+
# enable hot reloading
37+
add_compile_options("$<$<CONFIG:Debug>:/ZI>")
38+
add_link_options("$<$<CONFIG:Debug>:/INCREMENTAL>")
39+
endif()
3440
endif()
3541
endif()
3642

@@ -67,13 +73,6 @@ if(PROJECT_IS_TOP_LEVEL)
6773
option(BOX2D_UNIT_TESTS "Build the Box2D unit tests" ON)
6874

6975
if(BOX2D_UNIT_TESTS OR BOX2D_SAMPLES OR BOX2D_BENCHMARKS)
70-
71-
if(MSVC AND NOT BOX2D_SANITIZE)
72-
# enable hot reloading
73-
add_compile_options("$<$<CONFIG:Debug>:/ZI>")
74-
add_link_options("$<$<CONFIG:Debug>:/INCREMENTAL>")
75-
endif()
76-
7776
# Emscripten pthread support for enkiTS
7877
if(EMSCRIPTEN)
7978
set(EMSCRIPTEN_PTHREADS_COMPILER_FLAGS "-pthread -s USE_PTHREADS=1")

include/box2d/box2d.h

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ B2_API b2SensorEvents b2World_GetSensorEvents( b2WorldId worldId );
5050
/// Get contact events for this current time step. The event data is transient. Do not store a reference to this data.
5151
B2_API b2ContactEvents b2World_GetContactEvents( b2WorldId worldId );
5252

53+
/// Get the joint events for the current time step. The event data is transient. Do not store a reference to this data.
54+
B2_API b2JointEvents b2World_GetJointEvents( b2WorldId worldId );
55+
5356
/// Overlap test for all shapes that *potentially* overlap the provided AABB
5457
B2_API b2TreeStats b2World_OverlapAABB( b2WorldId worldId, b2AABB aabb, b2QueryFilter filter, b2OverlapResultFcn* fcn,
5558
void* context );
@@ -745,29 +748,17 @@ B2_API b2BodyId b2Joint_GetBodyB( b2JointId jointId );
745748
/// Get the world that owns this joint
746749
B2_API b2WorldId b2Joint_GetWorld( b2JointId jointId );
747750

748-
/// Set the local anchor on bodyA
749-
B2_API void b2Joint_SetLocalAnchorA( b2JointId jointId, b2Vec2 localAnchor );
750-
751-
/// Get the local anchor on bodyA
752-
B2_API b2Vec2 b2Joint_GetLocalAnchorA( b2JointId jointId );
753-
754-
/// Set the local anchor on bodyB
755-
B2_API void b2Joint_SetLocalAnchorB( b2JointId jointId, b2Vec2 localAnchor );
751+
/// Set the local frame on bodyA
752+
B2_API void b2Joint_SetLocalFrameA( b2JointId jointId, b2Transform localFrame );
756753

757-
/// Get the local anchor on bodyB
758-
B2_API b2Vec2 b2Joint_GetLocalAnchorB( b2JointId jointId );
754+
/// Get the local frame on bodyA
755+
B2_API b2Transform b2Joint_GetLocalFrameA( b2JointId jointId );
759756

760-
/// Get the joint reference angle in radians (revolute, prismatic, and weld)
761-
B2_API float b2Joint_GetReferenceAngle( b2JointId jointId );
757+
/// Set the local frame on bodyB
758+
B2_API void b2Joint_SetLocalFrameB( b2JointId jointId, b2Transform localFrame );
762759

763-
/// Set the joint reference angle in radians, must be in [-pi,pi]. (revolute, prismatic, and weld)
764-
B2_API void b2Joint_SetReferenceAngle( b2JointId jointId, float angleInRadians );
765-
766-
/// Set the local axis on bodyA (prismatic and wheel)
767-
B2_API void b2Joint_SetLocalAxisA( b2JointId jointId, b2Vec2 localAxis );
768-
769-
/// Get the local axis on bodyA (prismatic and wheel)
770-
B2_API b2Vec2 b2Joint_GetLocalAxisA( b2JointId jointId );
760+
/// Get the local frame on bodyB
761+
B2_API b2Transform b2Joint_GetLocalFrameB( b2JointId jointId );
771762

772763
/// Toggle collision between connected bodies
773764
B2_API void b2Joint_SetCollideConnected( b2JointId jointId, bool shouldCollide );
@@ -887,29 +878,15 @@ B2_API float b2DistanceJoint_GetMotorForce( b2JointId jointId );
887878
* @defgroup motor_joint Motor Joint
888879
* @brief Functions for the motor joint.
889880
*
890-
* The motor joint is used to drive the relative transform between two bodies. It takes
891-
* a relative position and rotation and applies the forces and torques needed to achieve
892-
* that relative transform over time.
881+
* The motor joint is used to drive the relative transform between two bodies. The target
882+
* is set by updating the local frames using b2Joint_SetLocalFrameA or b2Joint_SetLocalFrameB.
893883
* @{
894884
*/
895885

896886
/// Create a motor joint
897887
/// @see b2MotorJointDef for details
898888
B2_API b2JointId b2CreateMotorJoint( b2WorldId worldId, const b2MotorJointDef* def );
899889

900-
/// Set the motor joint linear offset target
901-
B2_API void b2MotorJoint_SetLinearOffset( b2JointId jointId, b2Vec2 linearOffset );
902-
903-
/// Get the motor joint linear offset target
904-
B2_API b2Vec2 b2MotorJoint_GetLinearOffset( b2JointId jointId );
905-
906-
/// Set the motor joint angular offset target in radians. This angle will be unwound
907-
/// so the motor will drive along the shortest arc.
908-
B2_API void b2MotorJoint_SetAngularOffset( b2JointId jointId, float angularOffset );
909-
910-
/// Get the motor joint angular offset target in radians
911-
B2_API float b2MotorJoint_GetAngularOffset( b2JointId jointId );
912-
913890
/// Set the motor joint maximum force, usually in newtons
914891
B2_API void b2MotorJoint_SetMaxForce( b2JointId jointId, float maxForce );
915892

@@ -943,12 +920,6 @@ B2_API float b2MotorJoint_GetCorrectionFactor( b2JointId jointId );
943920
/// @see b2MouseJointDef for details
944921
B2_API b2JointId b2CreateMouseJoint( b2WorldId worldId, const b2MouseJointDef* def );
945922

946-
/// Set the mouse joint target
947-
B2_API void b2MouseJoint_SetTarget( b2JointId jointId, b2Vec2 target );
948-
949-
/// Get the mouse joint target
950-
B2_API b2Vec2 b2MouseJoint_GetTarget( b2JointId jointId );
951-
952923
/// Set the mouse joint spring stiffness in Hertz
953924
B2_API void b2MouseJoint_SetSpringHertz( b2JointId jointId, float hertz );
954925

include/box2d/math_functions.h

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ B2_API bool b2IsValidVec2( b2Vec2 v );
9292
/// Is this a valid rotation? Not NaN or infinity. Is normalized.
9393
B2_API bool b2IsValidRotation( b2Rot q );
9494

95+
/// Is this a valid transform? Not NaN or infinity. Rotation is normalized.
96+
B2_API bool b2IsValidTransform( b2Transform t );
97+
9598
/// Is this a valid bounding box? Not Nan or infinity. Upper bound greater than or equal to lower bound.
9699
B2_API bool b2IsValidAABB( b2AABB aabb );
97100

@@ -373,6 +376,13 @@ B2_INLINE b2Rot b2MakeRot( float radians )
373376
return B2_LITERAL( b2Rot ){ cs.cosine, cs.sine };
374377
}
375378

379+
/// Make a rotation using a unit vector
380+
B2_INLINE b2Rot b2MakeRotFromUnitVector( b2Vec2 unitVector )
381+
{
382+
B2_ASSERT( b2IsNormalized( unitVector ) );
383+
return B2_LITERAL( b2Rot ){ unitVector.x, unitVector.y };
384+
}
385+
376386
/// Compute the rotation between two unit vectors
377387
B2_API b2Rot b2ComputeRotationBetweenUnitVectors( b2Vec2 v1, b2Vec2 v2 );
378388

@@ -454,26 +464,27 @@ B2_INLINE b2Rot b2MulRot( b2Rot q, b2Rot r )
454464
return qr;
455465
}
456466

457-
/// Transpose multiply two rotations: qT * r
458-
B2_INLINE b2Rot b2InvMulRot( b2Rot q, b2Rot r )
467+
/// Transpose multiply two rotations: inv(a) * b
468+
/// This rotates a vector local in frame b into a vector local in frame a
469+
B2_INLINE b2Rot b2InvMulRot( b2Rot a, b2Rot b )
459470
{
460-
// [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc]
461-
// [-qs qc] [rs rc] [-qs*rc+qc*rs qs*rs+qc*rc]
462-
// s(q - r) = qc * rs - qs * rc
463-
// c(q - r) = qc * rc + qs * rs
464-
b2Rot qr;
465-
qr.s = q.c * r.s - q.s * r.c;
466-
qr.c = q.c * r.c + q.s * r.s;
467-
return qr;
471+
// [ ac as] * [bc -bs] = [ac*bc+qs*bs -ac*bs+as*bc]
472+
// [-as ac] [bs bc] [-as*bc+ac*bs as*bs+ac*bc]
473+
// s(a - b) = ac * bs - as * bc
474+
// c(a - b) = ac * bc + as * bs
475+
b2Rot r;
476+
r.s = a.c * b.s - a.s * b.c;
477+
r.c = a.c * b.c + a.s * b.s;
478+
return r;
468479
}
469480

470-
/// relative angle between b and a (rot_b * inv(rot_a))
471-
B2_INLINE float b2RelativeAngle( b2Rot b, b2Rot a )
481+
/// Relative angle between a and b
482+
B2_INLINE float b2RelativeAngle( b2Rot a, b2Rot b )
472483
{
473484
// sin(b - a) = bs * ac - bc * as
474485
// cos(b - a) = bc * ac + bs * as
475-
float s = b.s * a.c - b.c * a.s;
476-
float c = b.c * a.c + b.s * a.s;
486+
float s = a.c * b.s - a.s * b.c;
487+
float c = a.c *b.c + a.s * b.s;
477488
return b2Atan2( s, c );
478489
}
479490

0 commit comments

Comments
 (0)