box2d-ruby 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +336 -0
  4. data/examples/contact_events.rb +22 -0
  5. data/examples/debug_draw.rb +15 -0
  6. data/examples/falling_ball.rb +19 -0
  7. data/examples/rugl_debug_draw.rb +68 -0
  8. data/examples/stagecraft_debug_draw.rb +64 -0
  9. data/examples/support/box2d_debug_lines.rb +125 -0
  10. data/ext/box2d/CMakeLists.txt +35 -0
  11. data/ext/box2d/extconf.rb +42 -0
  12. data/ext/box2d/native.c +9 -0
  13. data/ext/box2d/vendor/box2d/LICENSE +21 -0
  14. data/ext/box2d/vendor/box2d/VERSION +1 -0
  15. data/ext/box2d/vendor/box2d/include/box2d/base.h +131 -0
  16. data/ext/box2d/vendor/box2d/include/box2d/box2d.h +1222 -0
  17. data/ext/box2d/vendor/box2d/include/box2d/collision.h +830 -0
  18. data/ext/box2d/vendor/box2d/include/box2d/id.h +144 -0
  19. data/ext/box2d/vendor/box2d/include/box2d/math_functions.h +761 -0
  20. data/ext/box2d/vendor/box2d/include/box2d/types.h +1457 -0
  21. data/ext/box2d/vendor/box2d/src/CMakeLists.txt +223 -0
  22. data/ext/box2d/vendor/box2d/src/aabb.c +132 -0
  23. data/ext/box2d/vendor/box2d/src/aabb.h +56 -0
  24. data/ext/box2d/vendor/box2d/src/arena_allocator.c +112 -0
  25. data/ext/box2d/vendor/box2d/src/arena_allocator.h +48 -0
  26. data/ext/box2d/vendor/box2d/src/array.c +8 -0
  27. data/ext/box2d/vendor/box2d/src/array.h +179 -0
  28. data/ext/box2d/vendor/box2d/src/atomic.h +79 -0
  29. data/ext/box2d/vendor/box2d/src/bitset.c +67 -0
  30. data/ext/box2d/vendor/box2d/src/bitset.h +65 -0
  31. data/ext/box2d/vendor/box2d/src/body.c +1884 -0
  32. data/ext/box2d/vendor/box2d/src/body.h +194 -0
  33. data/ext/box2d/vendor/box2d/src/box2d.natvis +41 -0
  34. data/ext/box2d/vendor/box2d/src/broad_phase.c +524 -0
  35. data/ext/box2d/vendor/box2d/src/broad_phase.h +83 -0
  36. data/ext/box2d/vendor/box2d/src/constants.h +54 -0
  37. data/ext/box2d/vendor/box2d/src/constraint_graph.c +322 -0
  38. data/ext/box2d/vendor/box2d/src/constraint_graph.h +58 -0
  39. data/ext/box2d/vendor/box2d/src/contact.c +650 -0
  40. data/ext/box2d/vendor/box2d/src/contact.h +148 -0
  41. data/ext/box2d/vendor/box2d/src/contact_solver.c +2120 -0
  42. data/ext/box2d/vendor/box2d/src/contact_solver.h +54 -0
  43. data/ext/box2d/vendor/box2d/src/core.c +178 -0
  44. data/ext/box2d/vendor/box2d/src/core.h +149 -0
  45. data/ext/box2d/vendor/box2d/src/ctz.h +112 -0
  46. data/ext/box2d/vendor/box2d/src/distance.c +1415 -0
  47. data/ext/box2d/vendor/box2d/src/distance_joint.c +556 -0
  48. data/ext/box2d/vendor/box2d/src/dynamic_tree.c +1989 -0
  49. data/ext/box2d/vendor/box2d/src/geometry.c +1028 -0
  50. data/ext/box2d/vendor/box2d/src/hull.c +328 -0
  51. data/ext/box2d/vendor/box2d/src/id_pool.c +79 -0
  52. data/ext/box2d/vendor/box2d/src/id_pool.h +35 -0
  53. data/ext/box2d/vendor/box2d/src/island.c +977 -0
  54. data/ext/box2d/vendor/box2d/src/island.h +89 -0
  55. data/ext/box2d/vendor/box2d/src/joint.c +1272 -0
  56. data/ext/box2d/vendor/box2d/src/joint.h +335 -0
  57. data/ext/box2d/vendor/box2d/src/manifold.c +1726 -0
  58. data/ext/box2d/vendor/box2d/src/math_functions.c +159 -0
  59. data/ext/box2d/vendor/box2d/src/motor_joint.c +283 -0
  60. data/ext/box2d/vendor/box2d/src/mouse_joint.c +214 -0
  61. data/ext/box2d/vendor/box2d/src/mover.c +73 -0
  62. data/ext/box2d/vendor/box2d/src/prismatic_joint.c +656 -0
  63. data/ext/box2d/vendor/box2d/src/revolute_joint.c +534 -0
  64. data/ext/box2d/vendor/box2d/src/sensor.c +389 -0
  65. data/ext/box2d/vendor/box2d/src/sensor.h +36 -0
  66. data/ext/box2d/vendor/box2d/src/shape.c +1714 -0
  67. data/ext/box2d/vendor/box2d/src/shape.h +123 -0
  68. data/ext/box2d/vendor/box2d/src/solver.c +2038 -0
  69. data/ext/box2d/vendor/box2d/src/solver.h +155 -0
  70. data/ext/box2d/vendor/box2d/src/solver_set.c +613 -0
  71. data/ext/box2d/vendor/box2d/src/solver_set.h +57 -0
  72. data/ext/box2d/vendor/box2d/src/table.c +238 -0
  73. data/ext/box2d/vendor/box2d/src/table.h +37 -0
  74. data/ext/box2d/vendor/box2d/src/timer.c +185 -0
  75. data/ext/box2d/vendor/box2d/src/types.c +151 -0
  76. data/ext/box2d/vendor/box2d/src/weld_joint.c +310 -0
  77. data/ext/box2d/vendor/box2d/src/wheel_joint.c +551 -0
  78. data/ext/box2d/vendor/box2d/src/world.c +3301 -0
  79. data/ext/box2d/vendor/box2d/src/world.h +192 -0
  80. data/generator/generate.rb +316 -0
  81. data/generator/layout_probe.c +507 -0
  82. data/generator/verify_layouts.rb +32 -0
  83. data/lib/box2d/body.rb +172 -0
  84. data/lib/box2d/body_definition.rb +38 -0
  85. data/lib/box2d/body_shapes.rb +135 -0
  86. data/lib/box2d/chain.rb +61 -0
  87. data/lib/box2d/debug_draw.rb +118 -0
  88. data/lib/box2d/events.rb +103 -0
  89. data/lib/box2d/fixed_stepper.rb +39 -0
  90. data/lib/box2d/handle.rb +46 -0
  91. data/lib/box2d/hit.rb +5 -0
  92. data/lib/box2d/joint.rb +197 -0
  93. data/lib/box2d/native.rb +1462 -0
  94. data/lib/box2d/native_loader.rb +45 -0
  95. data/lib/box2d/pixel_scale.rb +29 -0
  96. data/lib/box2d/shape.rb +109 -0
  97. data/lib/box2d/shape_definition.rb +44 -0
  98. data/lib/box2d/value_conversion.rb +80 -0
  99. data/lib/box2d/version.rb +7 -0
  100. data/lib/box2d/world.rb +135 -0
  101. data/lib/box2d/world_joints.rb +156 -0
  102. data/lib/box2d/world_queries.rb +122 -0
  103. data/lib/box2d/world_registry.rb +95 -0
  104. data/lib/box2d.rb +31 -0
  105. data/script/build_platform_gem.rb +24 -0
  106. data/script/deterministic_scene.rb +56 -0
  107. data/script/update_deterministic_snapshot.rb +11 -0
  108. data/script/verify_platform_gem.rb +24 -0
  109. metadata +164 -0
@@ -0,0 +1,310 @@
1
+ // SPDX-FileCopyrightText: 2023 Erin Catto
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ #include "body.h"
5
+ #include "core.h"
6
+ #include "joint.h"
7
+ #include "solver.h"
8
+ #include "solver_set.h"
9
+ #include "world.h"
10
+
11
+ // needed for dll export
12
+ #include "box2d/box2d.h"
13
+
14
+ float b2WeldJoint_GetReferenceAngle( b2JointId jointId )
15
+ {
16
+ b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_weldJoint );
17
+ return joint->weldJoint.referenceAngle;
18
+ }
19
+
20
+ void b2WeldJoint_SetReferenceAngle( b2JointId jointId, float angleInRadians )
21
+ {
22
+ B2_ASSERT( b2IsValidFloat( angleInRadians ) );
23
+ b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_weldJoint );
24
+ joint->weldJoint.referenceAngle = b2ClampFloat(angleInRadians, -B2_PI, B2_PI);
25
+ }
26
+
27
+ void b2WeldJoint_SetLinearHertz( b2JointId jointId, float hertz )
28
+ {
29
+ B2_ASSERT( b2IsValidFloat( hertz ) && hertz >= 0.0f );
30
+ b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_weldJoint );
31
+ joint->weldJoint.linearHertz = hertz;
32
+ }
33
+
34
+ float b2WeldJoint_GetLinearHertz( b2JointId jointId )
35
+ {
36
+ b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_weldJoint );
37
+ return joint->weldJoint.linearHertz;
38
+ }
39
+
40
+ void b2WeldJoint_SetLinearDampingRatio( b2JointId jointId, float dampingRatio )
41
+ {
42
+ B2_ASSERT( b2IsValidFloat( dampingRatio ) && dampingRatio >= 0.0f );
43
+ b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_weldJoint );
44
+ joint->weldJoint.linearDampingRatio = dampingRatio;
45
+ }
46
+
47
+ float b2WeldJoint_GetLinearDampingRatio( b2JointId jointId )
48
+ {
49
+ b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_weldJoint );
50
+ return joint->weldJoint.linearDampingRatio;
51
+ }
52
+
53
+ void b2WeldJoint_SetAngularHertz( b2JointId jointId, float hertz )
54
+ {
55
+ B2_ASSERT( b2IsValidFloat( hertz ) && hertz >= 0.0f );
56
+ b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_weldJoint );
57
+ joint->weldJoint.angularHertz = hertz;
58
+ }
59
+
60
+ float b2WeldJoint_GetAngularHertz( b2JointId jointId )
61
+ {
62
+ b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_weldJoint );
63
+ return joint->weldJoint.angularHertz;
64
+ }
65
+
66
+ void b2WeldJoint_SetAngularDampingRatio( b2JointId jointId, float dampingRatio )
67
+ {
68
+ B2_ASSERT( b2IsValidFloat( dampingRatio ) && dampingRatio >= 0.0f );
69
+ b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_weldJoint );
70
+ joint->weldJoint.angularDampingRatio = dampingRatio;
71
+ }
72
+
73
+ float b2WeldJoint_GetAngularDampingRatio( b2JointId jointId )
74
+ {
75
+ b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_weldJoint );
76
+ return joint->weldJoint.angularDampingRatio;
77
+ }
78
+
79
+ b2Vec2 b2GetWeldJointForce( b2World* world, b2JointSim* base )
80
+ {
81
+ b2Vec2 force = b2MulSV( world->inv_h, base->weldJoint.linearImpulse );
82
+ return force;
83
+ }
84
+
85
+ float b2GetWeldJointTorque( b2World* world, b2JointSim* base )
86
+ {
87
+ return world->inv_h * base->weldJoint.angularImpulse;
88
+ }
89
+
90
+ // Point-to-point constraint
91
+ // C = p2 - p1
92
+ // Cdot = v2 - v1
93
+ // = v2 + cross(w2, r2) - v1 - cross(w1, r1)
94
+ // J = [-I -r1_skew I r2_skew ]
95
+ // Identity used:
96
+ // w k % (rx i + ry j) = w * (-ry i + rx j)
97
+
98
+ // Angle constraint
99
+ // C = angle2 - angle1 - referenceAngle
100
+ // Cdot = w2 - w1
101
+ // J = [0 0 -1 0 0 1]
102
+ // K = invI1 + invI2
103
+
104
+ void b2PrepareWeldJoint( b2JointSim* base, b2StepContext* context )
105
+ {
106
+ B2_ASSERT( base->type == b2_weldJoint );
107
+
108
+ // chase body id to the solver set where the body lives
109
+ int idA = base->bodyIdA;
110
+ int idB = base->bodyIdB;
111
+
112
+ b2World* world = context->world;
113
+
114
+ b2Body* bodyA = b2BodyArray_Get( &world->bodies, idA );
115
+ b2Body* bodyB = b2BodyArray_Get( &world->bodies, idB );
116
+
117
+ B2_ASSERT( bodyA->setIndex == b2_awakeSet || bodyB->setIndex == b2_awakeSet );
118
+ b2SolverSet* setA = b2SolverSetArray_Get( &world->solverSets, bodyA->setIndex );
119
+ b2SolverSet* setB = b2SolverSetArray_Get( &world->solverSets, bodyB->setIndex );
120
+
121
+ int localIndexA = bodyA->localIndex;
122
+ int localIndexB = bodyB->localIndex;
123
+
124
+ b2BodySim* bodySimA = b2BodySimArray_Get( &setA->bodySims, localIndexA );
125
+ b2BodySim* bodySimB = b2BodySimArray_Get( &setB->bodySims, localIndexB );
126
+
127
+ float mA = bodySimA->invMass;
128
+ float iA = bodySimA->invInertia;
129
+ float mB = bodySimB->invMass;
130
+ float iB = bodySimB->invInertia;
131
+
132
+ base->invMassA = mA;
133
+ base->invMassB = mB;
134
+ base->invIA = iA;
135
+ base->invIB = iB;
136
+
137
+ b2WeldJoint* joint = &base->weldJoint;
138
+ joint->indexA = bodyA->setIndex == b2_awakeSet ? localIndexA : B2_NULL_INDEX;
139
+ joint->indexB = bodyB->setIndex == b2_awakeSet ? localIndexB : B2_NULL_INDEX;
140
+
141
+ b2Rot qA = bodySimA->transform.q;
142
+ b2Rot qB = bodySimB->transform.q;
143
+
144
+ joint->anchorA = b2RotateVector( qA, b2Sub( base->localOriginAnchorA, bodySimA->localCenter ) );
145
+ joint->anchorB = b2RotateVector( qB, b2Sub( base->localOriginAnchorB, bodySimB->localCenter ) );
146
+ joint->deltaCenter = b2Sub( bodySimB->center, bodySimA->center );
147
+ joint->deltaAngle = b2RelativeAngle( qB, qA ) - joint->referenceAngle;
148
+ joint->deltaAngle = b2UnwindAngle( joint->deltaAngle );
149
+
150
+ float ka = iA + iB;
151
+ joint->axialMass = ka > 0.0f ? 1.0f / ka : 0.0f;
152
+
153
+ if ( joint->linearHertz == 0.0f )
154
+ {
155
+ joint->linearSoftness = context->jointSoftness;
156
+ }
157
+ else
158
+ {
159
+ joint->linearSoftness = b2MakeSoft( joint->linearHertz, joint->linearDampingRatio, context->h );
160
+ }
161
+
162
+ if ( joint->angularHertz == 0.0f )
163
+ {
164
+ joint->angularSoftness = context->jointSoftness;
165
+ }
166
+ else
167
+ {
168
+ joint->angularSoftness = b2MakeSoft( joint->angularHertz, joint->angularDampingRatio, context->h );
169
+ }
170
+
171
+ if ( context->enableWarmStarting == false )
172
+ {
173
+ joint->linearImpulse = b2Vec2_zero;
174
+ joint->angularImpulse = 0.0f;
175
+ }
176
+ }
177
+
178
+ void b2WarmStartWeldJoint( b2JointSim* base, b2StepContext* context )
179
+ {
180
+ float mA = base->invMassA;
181
+ float mB = base->invMassB;
182
+ float iA = base->invIA;
183
+ float iB = base->invIB;
184
+
185
+ // dummy state for static bodies
186
+ b2BodyState dummyState = b2_identityBodyState;
187
+
188
+ b2WeldJoint* joint = &base->weldJoint;
189
+
190
+ b2BodyState* stateA = joint->indexA == B2_NULL_INDEX ? &dummyState : context->states + joint->indexA;
191
+ b2BodyState* stateB = joint->indexB == B2_NULL_INDEX ? &dummyState : context->states + joint->indexB;
192
+
193
+ b2Vec2 rA = b2RotateVector( stateA->deltaRotation, joint->anchorA );
194
+ b2Vec2 rB = b2RotateVector( stateB->deltaRotation, joint->anchorB );
195
+
196
+ stateA->linearVelocity = b2MulSub( stateA->linearVelocity, mA, joint->linearImpulse );
197
+ stateA->angularVelocity -= iA * ( b2Cross( rA, joint->linearImpulse ) + joint->angularImpulse );
198
+
199
+ stateB->linearVelocity = b2MulAdd( stateB->linearVelocity, mB, joint->linearImpulse );
200
+ stateB->angularVelocity += iB * ( b2Cross( rB, joint->linearImpulse ) + joint->angularImpulse );
201
+ }
202
+
203
+ void b2SolveWeldJoint( b2JointSim* base, b2StepContext* context, bool useBias )
204
+ {
205
+ B2_ASSERT( base->type == b2_weldJoint );
206
+
207
+ float mA = base->invMassA;
208
+ float mB = base->invMassB;
209
+ float iA = base->invIA;
210
+ float iB = base->invIB;
211
+
212
+ // dummy state for static bodies
213
+ b2BodyState dummyState = b2_identityBodyState;
214
+
215
+ b2WeldJoint* joint = &base->weldJoint;
216
+
217
+ b2BodyState* stateA = joint->indexA == B2_NULL_INDEX ? &dummyState : context->states + joint->indexA;
218
+ b2BodyState* stateB = joint->indexB == B2_NULL_INDEX ? &dummyState : context->states + joint->indexB;
219
+
220
+ b2Vec2 vA = stateA->linearVelocity;
221
+ float wA = stateA->angularVelocity;
222
+ b2Vec2 vB = stateB->linearVelocity;
223
+ float wB = stateB->angularVelocity;
224
+
225
+ // angular constraint
226
+ {
227
+ float bias = 0.0f;
228
+ float massScale = 1.0f;
229
+ float impulseScale = 0.0f;
230
+ if ( useBias || joint->angularHertz > 0.0f )
231
+ {
232
+ float C = b2RelativeAngle( stateB->deltaRotation, stateA->deltaRotation ) + joint->deltaAngle;
233
+ bias = joint->angularSoftness.biasRate * C;
234
+ massScale = joint->angularSoftness.massScale;
235
+ impulseScale = joint->angularSoftness.impulseScale;
236
+ }
237
+
238
+ float Cdot = wB - wA;
239
+ float impulse = -massScale * joint->axialMass * ( Cdot + bias ) - impulseScale * joint->angularImpulse;
240
+ joint->angularImpulse += impulse;
241
+
242
+ wA -= iA * impulse;
243
+ wB += iB * impulse;
244
+ }
245
+
246
+ // linear constraint
247
+ {
248
+ b2Vec2 rA = b2RotateVector( stateA->deltaRotation, joint->anchorA );
249
+ b2Vec2 rB = b2RotateVector( stateB->deltaRotation, joint->anchorB );
250
+
251
+ b2Vec2 bias = b2Vec2_zero;
252
+ float massScale = 1.0f;
253
+ float impulseScale = 0.0f;
254
+ if ( useBias || joint->linearHertz > 0.0f )
255
+ {
256
+ b2Vec2 dcA = stateA->deltaPosition;
257
+ b2Vec2 dcB = stateB->deltaPosition;
258
+ b2Vec2 C = b2Add( b2Add( b2Sub( dcB, dcA ), b2Sub( rB, rA ) ), joint->deltaCenter );
259
+
260
+ bias = b2MulSV( joint->linearSoftness.biasRate, C );
261
+ massScale = joint->linearSoftness.massScale;
262
+ impulseScale = joint->linearSoftness.impulseScale;
263
+ }
264
+
265
+ b2Vec2 Cdot = b2Sub( b2Add( vB, b2CrossSV( wB, rB ) ), b2Add( vA, b2CrossSV( wA, rA ) ) );
266
+
267
+ b2Mat22 K;
268
+ K.cx.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;
269
+ K.cy.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;
270
+ K.cx.y = K.cy.x;
271
+ K.cy.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;
272
+ b2Vec2 b = b2Solve22( K, b2Add( Cdot, bias ) );
273
+
274
+ b2Vec2 impulse = {
275
+ -massScale * b.x - impulseScale * joint->linearImpulse.x,
276
+ -massScale * b.y - impulseScale * joint->linearImpulse.y,
277
+ };
278
+
279
+ joint->linearImpulse = b2Add( joint->linearImpulse, impulse );
280
+
281
+ vA = b2MulSub( vA, mA, impulse );
282
+ wA -= iA * b2Cross( rA, impulse );
283
+ vB = b2MulAdd( vB, mB, impulse );
284
+ wB += iB * b2Cross( rB, impulse );
285
+ }
286
+
287
+ stateA->linearVelocity = vA;
288
+ stateA->angularVelocity = wA;
289
+ stateB->linearVelocity = vB;
290
+ stateB->angularVelocity = wB;
291
+ }
292
+
293
+ #if 0
294
+ void b2DumpWeldJoint()
295
+ {
296
+ int32 indexA = m_bodyA->m_islandIndex;
297
+ int32 indexB = m_bodyB->m_islandIndex;
298
+
299
+ b2Dump(" b2WeldJointDef jd;\n");
300
+ b2Dump(" jd.bodyA = sims[%d];\n", indexA);
301
+ b2Dump(" jd.bodyB = sims[%d];\n", indexB);
302
+ b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected);
303
+ b2Dump(" jd.localAnchorA.Set(%.9g, %.9g);\n", m_localAnchorA.x, m_localAnchorA.y);
304
+ b2Dump(" jd.localAnchorB.Set(%.9g, %.9g);\n", m_localAnchorB.x, m_localAnchorB.y);
305
+ b2Dump(" jd.referenceAngle = %.9g;\n", m_referenceAngle);
306
+ b2Dump(" jd.stiffness = %.9g;\n", m_stiffness);
307
+ b2Dump(" jd.damping = %.9g;\n", m_damping);
308
+ b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index);
309
+ }
310
+ #endif