pbox2d 0.6.0-java → 0.8.0-java

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 (154) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +8 -0
  3. data/.mvn/wrapper/maven-wrapper.properties +1 -0
  4. data/.travis.yml +23 -0
  5. data/CHANGELOG.md +8 -0
  6. data/README.md +7 -7
  7. data/Rakefile +1 -2
  8. data/lib/box2d.jar +0 -0
  9. data/lib/pbox2d/version.rb +1 -1
  10. data/lib/pbox2d.rb +1 -0
  11. data/pbox2d.gemspec +6 -11
  12. data/pom.rb +59 -0
  13. data/pom.xml +82 -73
  14. data/src/org/jbox2d/JBox2D.gwt.xml +12 -0
  15. data/src/org/jbox2d/callbacks/ContactAdaptor.java +27 -0
  16. data/src/org/jbox2d/callbacks/ContactFilter.java +59 -0
  17. data/src/org/jbox2d/callbacks/ContactImpulse.java +42 -0
  18. data/src/org/jbox2d/callbacks/ContactListener.java +87 -0
  19. data/src/org/jbox2d/callbacks/DebugDraw.java +297 -0
  20. data/src/org/jbox2d/callbacks/DestructionListener.java +53 -0
  21. data/src/org/jbox2d/callbacks/PairCallback.java +29 -0
  22. data/src/org/jbox2d/callbacks/ParticleDestructionListener.java +20 -0
  23. data/src/org/jbox2d/callbacks/ParticleQueryCallback.java +19 -0
  24. data/src/org/jbox2d/callbacks/ParticleRaycastCallback.java +19 -0
  25. data/src/org/jbox2d/callbacks/QueryCallback.java +45 -0
  26. data/src/org/jbox2d/callbacks/RayCastCallback.java +55 -0
  27. data/src/org/jbox2d/callbacks/TreeCallback.java +42 -0
  28. data/src/org/jbox2d/callbacks/TreeRayCastCallback.java +44 -0
  29. data/src/org/jbox2d/collision/AABB.java +338 -0
  30. data/src/org/jbox2d/collision/Collision.java +1444 -0
  31. data/src/org/jbox2d/collision/ContactID.java +106 -0
  32. data/src/org/jbox2d/collision/Distance.java +773 -0
  33. data/src/org/jbox2d/collision/DistanceInput.java +41 -0
  34. data/src/org/jbox2d/collision/DistanceOutput.java +43 -0
  35. data/src/org/jbox2d/collision/Manifold.java +116 -0
  36. data/src/org/jbox2d/collision/ManifoldPoint.java +104 -0
  37. data/src/org/jbox2d/collision/RayCastInput.java +47 -0
  38. data/src/org/jbox2d/collision/RayCastOutput.java +46 -0
  39. data/src/org/jbox2d/collision/TimeOfImpact.java +526 -0
  40. data/src/org/jbox2d/collision/WorldManifold.java +200 -0
  41. data/src/org/jbox2d/collision/broadphase/BroadPhase.java +92 -0
  42. data/src/org/jbox2d/collision/broadphase/BroadPhaseStrategy.java +88 -0
  43. data/src/org/jbox2d/collision/broadphase/DefaultBroadPhaseBuffer.java +268 -0
  44. data/src/org/jbox2d/collision/broadphase/DynamicTree.java +883 -0
  45. data/src/org/jbox2d/collision/broadphase/DynamicTreeFlatNodes.java +873 -0
  46. data/src/org/jbox2d/collision/broadphase/DynamicTreeNode.java +54 -0
  47. data/src/org/jbox2d/collision/broadphase/Pair.java +46 -0
  48. data/src/org/jbox2d/collision/shapes/ChainShape.java +264 -0
  49. data/src/org/jbox2d/collision/shapes/CircleShape.java +207 -0
  50. data/src/org/jbox2d/collision/shapes/EdgeShape.java +254 -0
  51. data/src/org/jbox2d/collision/shapes/MassData.java +105 -0
  52. data/src/org/jbox2d/collision/shapes/PolygonShape.java +718 -0
  53. data/src/org/jbox2d/collision/shapes/Shape.java +136 -0
  54. data/src/org/jbox2d/collision/shapes/ShapeType.java +32 -0
  55. data/src/org/jbox2d/common/BufferUtils.java +209 -0
  56. data/src/org/jbox2d/common/Color3f.java +88 -0
  57. data/src/org/jbox2d/common/IViewportTransform.java +133 -0
  58. data/src/org/jbox2d/common/Mat22.java +609 -0
  59. data/src/org/jbox2d/common/Mat33.java +290 -0
  60. data/src/org/jbox2d/common/MathUtils.java +335 -0
  61. data/src/org/jbox2d/common/OBBViewportTransform.java +174 -0
  62. data/src/org/jbox2d/common/PlatformMathUtils.java +46 -0
  63. data/src/org/jbox2d/common/RaycastResult.java +37 -0
  64. data/src/org/jbox2d/common/Rot.java +150 -0
  65. data/src/org/jbox2d/common/Settings.java +246 -0
  66. data/src/org/jbox2d/common/Sweep.java +116 -0
  67. data/src/org/jbox2d/common/Timer.java +46 -0
  68. data/src/org/jbox2d/common/Transform.java +203 -0
  69. data/src/org/jbox2d/common/Vec2.java +388 -0
  70. data/src/org/jbox2d/common/Vec3.java +170 -0
  71. data/src/org/jbox2d/dynamics/Body.java +1246 -0
  72. data/src/org/jbox2d/dynamics/BodyDef.java +382 -0
  73. data/src/org/jbox2d/dynamics/BodyType.java +41 -0
  74. data/src/org/jbox2d/dynamics/ContactManager.java +293 -0
  75. data/src/org/jbox2d/dynamics/Filter.java +62 -0
  76. data/src/org/jbox2d/dynamics/Fixture.java +454 -0
  77. data/src/org/jbox2d/dynamics/FixtureDef.java +214 -0
  78. data/src/org/jbox2d/dynamics/FixtureProxy.java +38 -0
  79. data/src/org/jbox2d/dynamics/Island.java +602 -0
  80. data/src/org/jbox2d/dynamics/Profile.java +97 -0
  81. data/src/org/jbox2d/dynamics/SolverData.java +33 -0
  82. data/src/org/jbox2d/dynamics/TimeStep.java +46 -0
  83. data/src/org/jbox2d/dynamics/World.java +2075 -0
  84. data/src/org/jbox2d/dynamics/contacts/ChainAndCircleContact.java +57 -0
  85. data/src/org/jbox2d/dynamics/contacts/ChainAndPolygonContact.java +57 -0
  86. data/src/org/jbox2d/dynamics/contacts/CircleContact.java +50 -0
  87. data/src/org/jbox2d/dynamics/contacts/Contact.java +365 -0
  88. data/src/org/jbox2d/dynamics/contacts/ContactCreator.java +35 -0
  89. data/src/org/jbox2d/dynamics/contacts/ContactEdge.java +56 -0
  90. data/src/org/jbox2d/dynamics/contacts/ContactPositionConstraint.java +49 -0
  91. data/src/org/jbox2d/dynamics/contacts/ContactRegister.java +31 -0
  92. data/src/org/jbox2d/dynamics/contacts/ContactSolver.java +1104 -0
  93. data/src/org/jbox2d/dynamics/contacts/ContactVelocityConstraint.java +60 -0
  94. data/src/org/jbox2d/dynamics/contacts/EdgeAndCircleContact.java +52 -0
  95. data/src/org/jbox2d/dynamics/contacts/EdgeAndPolygonContact.java +52 -0
  96. data/src/org/jbox2d/dynamics/contacts/PolygonAndCircleContact.java +51 -0
  97. data/src/org/jbox2d/dynamics/contacts/PolygonContact.java +50 -0
  98. data/src/org/jbox2d/dynamics/contacts/Position.java +31 -0
  99. data/src/org/jbox2d/dynamics/contacts/Velocity.java +31 -0
  100. data/src/org/jbox2d/dynamics/joints/ConstantVolumeJoint.java +258 -0
  101. data/src/org/jbox2d/dynamics/joints/ConstantVolumeJointDef.java +75 -0
  102. data/src/org/jbox2d/dynamics/joints/DistanceJoint.java +356 -0
  103. data/src/org/jbox2d/dynamics/joints/DistanceJointDef.java +106 -0
  104. data/src/org/jbox2d/dynamics/joints/FrictionJoint.java +294 -0
  105. data/src/org/jbox2d/dynamics/joints/FrictionJointDef.java +78 -0
  106. data/src/org/jbox2d/dynamics/joints/GearJoint.java +520 -0
  107. data/src/org/jbox2d/dynamics/joints/GearJointDef.java +58 -0
  108. data/src/org/jbox2d/dynamics/joints/Jacobian.java +32 -0
  109. data/src/org/jbox2d/dynamics/joints/Joint.java +235 -0
  110. data/src/org/jbox2d/dynamics/joints/JointDef.java +65 -0
  111. data/src/org/jbox2d/dynamics/joints/JointEdge.java +57 -0
  112. data/src/org/jbox2d/dynamics/joints/JointType.java +28 -0
  113. data/src/org/jbox2d/dynamics/joints/LimitState.java +28 -0
  114. data/src/org/jbox2d/dynamics/joints/MotorJoint.java +339 -0
  115. data/src/org/jbox2d/dynamics/joints/MotorJointDef.java +55 -0
  116. data/src/org/jbox2d/dynamics/joints/MouseJoint.java +262 -0
  117. data/src/org/jbox2d/dynamics/joints/MouseJointDef.java +62 -0
  118. data/src/org/jbox2d/dynamics/joints/PrismaticJoint.java +808 -0
  119. data/src/org/jbox2d/dynamics/joints/PrismaticJointDef.java +120 -0
  120. data/src/org/jbox2d/dynamics/joints/PulleyJoint.java +393 -0
  121. data/src/org/jbox2d/dynamics/joints/PulleyJointDef.java +105 -0
  122. data/src/org/jbox2d/dynamics/joints/RevoluteJoint.java +554 -0
  123. data/src/org/jbox2d/dynamics/joints/RevoluteJointDef.java +137 -0
  124. data/src/org/jbox2d/dynamics/joints/RopeJoint.java +276 -0
  125. data/src/org/jbox2d/dynamics/joints/RopeJointDef.java +34 -0
  126. data/src/org/jbox2d/dynamics/joints/WeldJoint.java +424 -0
  127. data/src/org/jbox2d/dynamics/joints/WeldJointDef.java +85 -0
  128. data/src/org/jbox2d/dynamics/joints/WheelJoint.java +498 -0
  129. data/src/org/jbox2d/dynamics/joints/WheelJointDef.java +98 -0
  130. data/src/org/jbox2d/particle/ParticleBodyContact.java +17 -0
  131. data/src/org/jbox2d/particle/ParticleColor.java +52 -0
  132. data/src/org/jbox2d/particle/ParticleContact.java +14 -0
  133. data/src/org/jbox2d/particle/ParticleDef.java +24 -0
  134. data/src/org/jbox2d/particle/ParticleGroup.java +154 -0
  135. data/src/org/jbox2d/particle/ParticleGroupDef.java +62 -0
  136. data/src/org/jbox2d/particle/ParticleGroupType.java +8 -0
  137. data/src/org/jbox2d/particle/ParticleSystem.java +2172 -0
  138. data/src/org/jbox2d/particle/ParticleType.java +28 -0
  139. data/src/org/jbox2d/particle/StackQueue.java +44 -0
  140. data/src/org/jbox2d/particle/VoronoiDiagram.java +209 -0
  141. data/src/org/jbox2d/pooling/IDynamicStack.java +47 -0
  142. data/src/org/jbox2d/pooling/IOrderedStack.java +57 -0
  143. data/src/org/jbox2d/pooling/IWorldPool.java +101 -0
  144. data/src/org/jbox2d/pooling/arrays/FloatArray.java +50 -0
  145. data/src/org/jbox2d/pooling/arrays/GeneratorArray.java +33 -0
  146. data/src/org/jbox2d/pooling/arrays/IntArray.java +53 -0
  147. data/src/org/jbox2d/pooling/arrays/Vec2Array.java +57 -0
  148. data/src/org/jbox2d/pooling/normal/CircleStack.java +77 -0
  149. data/src/org/jbox2d/pooling/normal/DefaultWorldPool.java +331 -0
  150. data/src/org/jbox2d/pooling/normal/MutableStack.java +72 -0
  151. data/src/org/jbox2d/pooling/normal/OrderedStack.java +73 -0
  152. data/src/org/jbox2d/pooling/stacks/DynamicIntStack.java +60 -0
  153. metadata +161 -14
  154. data/lib/jbox2d-library-2.3.1-SNAPSHOT.jar +0 -0
@@ -0,0 +1,808 @@
1
+ /*******************************************************************************
2
+ * Copyright (c) 2013, Daniel Murphy
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without modification,
6
+ * are permitted provided that the following conditions are met:
7
+ * * Redistributions of source code must retain the above copyright notice,
8
+ * this list of conditions and the following disclaimer.
9
+ * * Redistributions in binary form must reproduce the above copyright notice,
10
+ * this list of conditions and the following disclaimer in the documentation
11
+ * and/or other materials provided with the distribution.
12
+ *
13
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
17
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
19
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
20
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22
+ * POSSIBILITY OF SUCH DAMAGE.
23
+ ******************************************************************************/
24
+ package org.jbox2d.dynamics.joints;
25
+
26
+ import org.jbox2d.common.Mat22;
27
+ import org.jbox2d.common.Mat33;
28
+ import org.jbox2d.common.MathUtils;
29
+ import org.jbox2d.common.Rot;
30
+ import org.jbox2d.common.Settings;
31
+ import org.jbox2d.common.Vec2;
32
+ import org.jbox2d.common.Vec3;
33
+ import org.jbox2d.dynamics.Body;
34
+ import org.jbox2d.dynamics.SolverData;
35
+ import org.jbox2d.pooling.IWorldPool;
36
+
37
+ //Linear constraint (point-to-line)
38
+ //d = p2 - p1 = x2 + r2 - x1 - r1
39
+ //C = dot(perp, d)
40
+ //Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))
41
+ // = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)
42
+ //J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]
43
+ //
44
+ //Angular constraint
45
+ //C = a2 - a1 + a_initial
46
+ //Cdot = w2 - w1
47
+ //J = [0 0 -1 0 0 1]
48
+ //
49
+ //K = J * invM * JT
50
+ //
51
+ //J = [-a -s1 a s2]
52
+ // [0 -1 0 1]
53
+ //a = perp
54
+ //s1 = cross(d + r1, a) = cross(p2 - x1, a)
55
+ //s2 = cross(r2, a) = cross(p2 - x2, a)
56
+
57
+
58
+ //Motor/Limit linear constraint
59
+ //C = dot(ax1, d)
60
+ //Cdot = = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)
61
+ //J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]
62
+
63
+ //Block Solver
64
+ //We develop a block solver that includes the joint limit. This makes the limit stiff (inelastic) even
65
+ //when the mass has poor distribution (leading to large torques about the joint anchor points).
66
+ //
67
+ //The Jacobian has 3 rows:
68
+ //J = [-uT -s1 uT s2] // linear
69
+ // [0 -1 0 1] // angular
70
+ // [-vT -a1 vT a2] // limit
71
+ //
72
+ //u = perp
73
+ //v = axis
74
+ //s1 = cross(d + r1, u), s2 = cross(r2, u)
75
+ //a1 = cross(d + r1, v), a2 = cross(r2, v)
76
+
77
+ //M * (v2 - v1) = JT * df
78
+ //J * v2 = bias
79
+ //
80
+ //v2 = v1 + invM * JT * df
81
+ //J * (v1 + invM * JT * df) = bias
82
+ //K * df = bias - J * v1 = -Cdot
83
+ //K = J * invM * JT
84
+ //Cdot = J * v1 - bias
85
+ //
86
+ //Now solve for f2.
87
+ //df = f2 - f1
88
+ //K * (f2 - f1) = -Cdot
89
+ //f2 = invK * (-Cdot) + f1
90
+ //
91
+ //Clamp accumulated limit impulse.
92
+ //lower: f2(3) = max(f2(3), 0)
93
+ //upper: f2(3) = min(f2(3), 0)
94
+ //
95
+ //Solve for correct f2(1:2)
96
+ //K(1:2, 1:2) * f2(1:2) = -Cdot(1:2) - K(1:2,3) * f2(3) + K(1:2,1:3) * f1
97
+ // = -Cdot(1:2) - K(1:2,3) * f2(3) + K(1:2,1:2) * f1(1:2) + K(1:2,3) * f1(3)
98
+ //K(1:2, 1:2) * f2(1:2) = -Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3)) + K(1:2,1:2) * f1(1:2)
99
+ //f2(1:2) = invK(1:2,1:2) * (-Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3))) + f1(1:2)
100
+ //
101
+ //Now compute impulse to be applied:
102
+ //df = f2 - f1
103
+
104
+ /**
105
+ * A prismatic joint. This joint provides one degree of freedom: translation along an axis fixed in
106
+ * bodyA. Relative rotation is prevented. You can use a joint limit to restrict the range of motion
107
+ * and a joint motor to drive the motion or to model joint friction.
108
+ *
109
+ * @author Daniel
110
+ */
111
+ public class PrismaticJoint extends Joint {
112
+
113
+ // Solver shared
114
+ protected final Vec2 m_localAnchorA;
115
+ protected final Vec2 m_localAnchorB;
116
+ protected final Vec2 m_localXAxisA;
117
+ protected final Vec2 m_localYAxisA;
118
+ protected float m_referenceAngle;
119
+ private final Vec3 m_impulse;
120
+ private float m_motorImpulse;
121
+ private float m_lowerTranslation;
122
+ private float m_upperTranslation;
123
+ private float m_maxMotorForce;
124
+ private float m_motorSpeed;
125
+ private boolean m_enableLimit;
126
+ private boolean m_enableMotor;
127
+ private LimitState m_limitState;
128
+
129
+ // Solver temp
130
+ private int m_indexA;
131
+ private int m_indexB;
132
+ private final Vec2 m_localCenterA = new Vec2();
133
+ private final Vec2 m_localCenterB = new Vec2();
134
+ private float m_invMassA;
135
+ private float m_invMassB;
136
+ private float m_invIA;
137
+ private float m_invIB;
138
+ private final Vec2 m_axis, m_perp;
139
+ private float m_s1, m_s2;
140
+ private float m_a1, m_a2;
141
+ private final Mat33 m_K;
142
+ private float m_motorMass; // effective mass for motor/limit translational constraint.
143
+
144
+ protected PrismaticJoint(IWorldPool argWorld, PrismaticJointDef def) {
145
+ super(argWorld, def);
146
+ m_localAnchorA = new Vec2(def.localAnchorA);
147
+ m_localAnchorB = new Vec2(def.localAnchorB);
148
+ m_localXAxisA = new Vec2(def.localAxisA);
149
+ m_localXAxisA.normalize();
150
+ m_localYAxisA = new Vec2();
151
+ Vec2.crossToOutUnsafe(1f, m_localXAxisA, m_localYAxisA);
152
+ m_referenceAngle = def.referenceAngle;
153
+
154
+ m_impulse = new Vec3();
155
+ m_motorMass = 0.0f;
156
+ m_motorImpulse = 0.0f;
157
+
158
+ m_lowerTranslation = def.lowerTranslation;
159
+ m_upperTranslation = def.upperTranslation;
160
+ m_maxMotorForce = def.maxMotorForce;
161
+ m_motorSpeed = def.motorSpeed;
162
+ m_enableLimit = def.enableLimit;
163
+ m_enableMotor = def.enableMotor;
164
+ m_limitState = LimitState.INACTIVE;
165
+
166
+ m_K = new Mat33();
167
+ m_axis = new Vec2();
168
+ m_perp = new Vec2();
169
+ }
170
+
171
+ public Vec2 getLocalAnchorA() {
172
+ return m_localAnchorA;
173
+ }
174
+
175
+ public Vec2 getLocalAnchorB() {
176
+ return m_localAnchorB;
177
+ }
178
+
179
+ @Override
180
+ public void getAnchorA(Vec2 argOut) {
181
+ m_bodyA.getWorldPointToOut(m_localAnchorA, argOut);
182
+ }
183
+
184
+ @Override
185
+ public void getAnchorB(Vec2 argOut) {
186
+ m_bodyB.getWorldPointToOut(m_localAnchorB, argOut);
187
+ }
188
+
189
+ @Override
190
+ public void getReactionForce(float inv_dt, Vec2 argOut) {
191
+ Vec2 temp = pool.popVec2();
192
+ temp.set(m_axis).mulLocal(m_motorImpulse + m_impulse.z);
193
+ argOut.set(m_perp).mulLocal(m_impulse.x).addLocal(temp).mulLocal(inv_dt);
194
+ pool.pushVec2(1);
195
+ }
196
+
197
+ @Override
198
+ public float getReactionTorque(float inv_dt) {
199
+ return inv_dt * m_impulse.y;
200
+ }
201
+
202
+ /**
203
+ * Get the current joint translation, usually in meters.
204
+ */
205
+ public float getJointSpeed() {
206
+ Body bA = m_bodyA;
207
+ Body bB = m_bodyB;
208
+
209
+ Vec2 temp = pool.popVec2();
210
+ Vec2 rA = pool.popVec2();
211
+ Vec2 rB = pool.popVec2();
212
+ Vec2 p1 = pool.popVec2();
213
+ Vec2 p2 = pool.popVec2();
214
+ Vec2 d = pool.popVec2();
215
+ Vec2 axis = pool.popVec2();
216
+ Vec2 temp2 = pool.popVec2();
217
+ Vec2 temp3 = pool.popVec2();
218
+
219
+ temp.set(m_localAnchorA).subLocal(bA.m_sweep.localCenter);
220
+ Rot.mulToOutUnsafe(bA.m_xf.q, temp, rA);
221
+
222
+ temp.set(m_localAnchorB).subLocal(bB.m_sweep.localCenter);
223
+ Rot.mulToOutUnsafe(bB.m_xf.q, temp, rB);
224
+
225
+ p1.set(bA.m_sweep.c).addLocal(rA);
226
+ p2.set(bB.m_sweep.c).addLocal(rB);
227
+
228
+ d.set(p2).subLocal(p1);
229
+ Rot.mulToOutUnsafe(bA.m_xf.q, m_localXAxisA, axis);
230
+
231
+ Vec2 vA = bA.m_linearVelocity;
232
+ Vec2 vB = bB.m_linearVelocity;
233
+ float wA = bA.m_angularVelocity;
234
+ float wB = bB.m_angularVelocity;
235
+
236
+
237
+ Vec2.crossToOutUnsafe(wA, axis, temp);
238
+ Vec2.crossToOutUnsafe(wB, rB, temp2);
239
+ Vec2.crossToOutUnsafe(wA, rA, temp3);
240
+
241
+ temp2.addLocal(vB).subLocal(vA).subLocal(temp3);
242
+ float speed = Vec2.dot(d, temp) + Vec2.dot(axis, temp2);
243
+
244
+ pool.pushVec2(9);
245
+
246
+ return speed;
247
+ }
248
+
249
+ public float getJointTranslation() {
250
+ Vec2 pA = pool.popVec2(), pB = pool.popVec2(), axis = pool.popVec2();
251
+ m_bodyA.getWorldPointToOut(m_localAnchorA, pA);
252
+ m_bodyB.getWorldPointToOut(m_localAnchorB, pB);
253
+ m_bodyA.getWorldVectorToOutUnsafe(m_localXAxisA, axis);
254
+ pB.subLocal(pA);
255
+ float translation = Vec2.dot(pB, axis);
256
+ pool.pushVec2(3);
257
+ return translation;
258
+ }
259
+
260
+ /**
261
+ * Is the joint limit enabled?
262
+ *
263
+ * @return
264
+ */
265
+ public boolean isLimitEnabled() {
266
+ return m_enableLimit;
267
+ }
268
+
269
+ /**
270
+ * Enable/disable the joint limit.
271
+ *
272
+ * @param flag
273
+ */
274
+ public void enableLimit(boolean flag) {
275
+ if (flag != m_enableLimit) {
276
+ m_bodyA.setAwake(true);
277
+ m_bodyB.setAwake(true);
278
+ m_enableLimit = flag;
279
+ m_impulse.z = 0.0f;
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Get the lower joint limit, usually in meters.
285
+ *
286
+ * @return
287
+ */
288
+ public float getLowerLimit() {
289
+ return m_lowerTranslation;
290
+ }
291
+
292
+ /**
293
+ * Get the upper joint limit, usually in meters.
294
+ *
295
+ * @return
296
+ */
297
+ public float getUpperLimit() {
298
+ return m_upperTranslation;
299
+ }
300
+
301
+ /**
302
+ * Set the joint limits, usually in meters.
303
+ *
304
+ * @param lower
305
+ * @param upper
306
+ */
307
+ public void setLimits(float lower, float upper) {
308
+ assert (lower <= upper);
309
+ if (lower != m_lowerTranslation || upper != m_upperTranslation) {
310
+ m_bodyA.setAwake(true);
311
+ m_bodyB.setAwake(true);
312
+ m_lowerTranslation = lower;
313
+ m_upperTranslation = upper;
314
+ m_impulse.z = 0.0f;
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Is the joint motor enabled?
320
+ *
321
+ * @return
322
+ */
323
+ public boolean isMotorEnabled() {
324
+ return m_enableMotor;
325
+ }
326
+
327
+ /**
328
+ * Enable/disable the joint motor.
329
+ *
330
+ * @param flag
331
+ */
332
+ public void enableMotor(boolean flag) {
333
+ m_bodyA.setAwake(true);
334
+ m_bodyB.setAwake(true);
335
+ m_enableMotor = flag;
336
+ }
337
+
338
+ /**
339
+ * Set the motor speed, usually in meters per second.
340
+ *
341
+ * @param speed
342
+ */
343
+ public void setMotorSpeed(float speed) {
344
+ m_bodyA.setAwake(true);
345
+ m_bodyB.setAwake(true);
346
+ m_motorSpeed = speed;
347
+ }
348
+
349
+ /**
350
+ * Get the motor speed, usually in meters per second.
351
+ *
352
+ * @return
353
+ */
354
+ public float getMotorSpeed() {
355
+ return m_motorSpeed;
356
+ }
357
+
358
+ /**
359
+ * Set the maximum motor force, usually in N.
360
+ *
361
+ * @param force
362
+ */
363
+ public void setMaxMotorForce(float force) {
364
+ m_bodyA.setAwake(true);
365
+ m_bodyB.setAwake(true);
366
+ m_maxMotorForce = force;
367
+ }
368
+
369
+ /**
370
+ * Get the current motor force, usually in N.
371
+ *
372
+ * @param inv_dt
373
+ * @return
374
+ */
375
+ public float getMotorForce(float inv_dt) {
376
+ return m_motorImpulse * inv_dt;
377
+ }
378
+
379
+ public float getMaxMotorForce() {
380
+ return m_maxMotorForce;
381
+ }
382
+
383
+ public float getReferenceAngle() {
384
+ return m_referenceAngle;
385
+ }
386
+
387
+ public Vec2 getLocalAxisA() {
388
+ return m_localXAxisA;
389
+ }
390
+
391
+ @Override
392
+ public void initVelocityConstraints(final SolverData data) {
393
+ m_indexA = m_bodyA.m_islandIndex;
394
+ m_indexB = m_bodyB.m_islandIndex;
395
+ m_localCenterA.set(m_bodyA.m_sweep.localCenter);
396
+ m_localCenterB.set(m_bodyB.m_sweep.localCenter);
397
+ m_invMassA = m_bodyA.m_invMass;
398
+ m_invMassB = m_bodyB.m_invMass;
399
+ m_invIA = m_bodyA.m_invI;
400
+ m_invIB = m_bodyB.m_invI;
401
+
402
+ Vec2 cA = data.positions[m_indexA].c;
403
+ float aA = data.positions[m_indexA].a;
404
+ Vec2 vA = data.velocities[m_indexA].v;
405
+ float wA = data.velocities[m_indexA].w;
406
+
407
+ Vec2 cB = data.positions[m_indexB].c;
408
+ float aB = data.positions[m_indexB].a;
409
+ Vec2 vB = data.velocities[m_indexB].v;
410
+ float wB = data.velocities[m_indexB].w;
411
+
412
+ final Rot qA = pool.popRot();
413
+ final Rot qB = pool.popRot();
414
+ final Vec2 d = pool.popVec2();
415
+ final Vec2 temp = pool.popVec2();
416
+ final Vec2 rA = pool.popVec2();
417
+ final Vec2 rB = pool.popVec2();
418
+
419
+ qA.set(aA);
420
+ qB.set(aB);
421
+
422
+ // Compute the effective masses.
423
+ Rot.mulToOutUnsafe(qA, d.set(m_localAnchorA).subLocal(m_localCenterA), rA);
424
+ Rot.mulToOutUnsafe(qB, d.set(m_localAnchorB).subLocal(m_localCenterB), rB);
425
+ d.set(cB).subLocal(cA).addLocal(rB).subLocal(rA);
426
+
427
+ float mA = m_invMassA, mB = m_invMassB;
428
+ float iA = m_invIA, iB = m_invIB;
429
+
430
+ // Compute motor Jacobian and effective mass.
431
+ {
432
+ Rot.mulToOutUnsafe(qA, m_localXAxisA, m_axis);
433
+ temp.set(d).addLocal(rA);
434
+ m_a1 = Vec2.cross(temp, m_axis);
435
+ m_a2 = Vec2.cross(rB, m_axis);
436
+
437
+ m_motorMass = mA + mB + iA * m_a1 * m_a1 + iB * m_a2 * m_a2;
438
+ if (m_motorMass > 0.0f) {
439
+ m_motorMass = 1.0f / m_motorMass;
440
+ }
441
+ }
442
+
443
+ // Prismatic constraint.
444
+ {
445
+ Rot.mulToOutUnsafe(qA, m_localYAxisA, m_perp);
446
+
447
+ temp.set(d).addLocal(rA);
448
+ m_s1 = Vec2.cross(temp, m_perp);
449
+ m_s2 = Vec2.cross(rB, m_perp);
450
+
451
+ float k11 = mA + mB + iA * m_s1 * m_s1 + iB * m_s2 * m_s2;
452
+ float k12 = iA * m_s1 + iB * m_s2;
453
+ float k13 = iA * m_s1 * m_a1 + iB * m_s2 * m_a2;
454
+ float k22 = iA + iB;
455
+ if (k22 == 0.0f) {
456
+ // For bodies with fixed rotation.
457
+ k22 = 1.0f;
458
+ }
459
+ float k23 = iA * m_a1 + iB * m_a2;
460
+ float k33 = mA + mB + iA * m_a1 * m_a1 + iB * m_a2 * m_a2;
461
+
462
+ m_K.ex.set(k11, k12, k13);
463
+ m_K.ey.set(k12, k22, k23);
464
+ m_K.ez.set(k13, k23, k33);
465
+ }
466
+
467
+ // Compute motor and limit terms.
468
+ if (m_enableLimit) {
469
+
470
+ float jointTranslation = Vec2.dot(m_axis, d);
471
+ if (MathUtils.abs(m_upperTranslation - m_lowerTranslation) < 2.0f * Settings.linearSlop) {
472
+ m_limitState = LimitState.EQUAL;
473
+ } else if (jointTranslation <= m_lowerTranslation) {
474
+ if (m_limitState != LimitState.AT_LOWER) {
475
+ m_limitState = LimitState.AT_LOWER;
476
+ m_impulse.z = 0.0f;
477
+ }
478
+ } else if (jointTranslation >= m_upperTranslation) {
479
+ if (m_limitState != LimitState.AT_UPPER) {
480
+ m_limitState = LimitState.AT_UPPER;
481
+ m_impulse.z = 0.0f;
482
+ }
483
+ } else {
484
+ m_limitState = LimitState.INACTIVE;
485
+ m_impulse.z = 0.0f;
486
+ }
487
+ } else {
488
+ m_limitState = LimitState.INACTIVE;
489
+ m_impulse.z = 0.0f;
490
+ }
491
+
492
+ if (m_enableMotor == false) {
493
+ m_motorImpulse = 0.0f;
494
+ }
495
+
496
+ if (data.step.warmStarting) {
497
+ // Account for variable time step.
498
+ m_impulse.mulLocal(data.step.dtRatio);
499
+ m_motorImpulse *= data.step.dtRatio;
500
+
501
+ final Vec2 P = pool.popVec2();
502
+ temp.set(m_axis).mulLocal(m_motorImpulse + m_impulse.z);
503
+ P.set(m_perp).mulLocal(m_impulse.x).addLocal(temp);
504
+
505
+ float LA = m_impulse.x * m_s1 + m_impulse.y + (m_motorImpulse + m_impulse.z) * m_a1;
506
+ float LB = m_impulse.x * m_s2 + m_impulse.y + (m_motorImpulse + m_impulse.z) * m_a2;
507
+
508
+ vA.x -= mA * P.x;
509
+ vA.y -= mA * P.y;
510
+ wA -= iA * LA;
511
+
512
+ vB.x += mB * P.x;
513
+ vB.y += mB * P.y;
514
+ wB += iB * LB;
515
+
516
+ pool.pushVec2(1);
517
+ } else {
518
+ m_impulse.setZero();
519
+ m_motorImpulse = 0.0f;
520
+ }
521
+
522
+ // data.velocities[m_indexA].v.set(vA);
523
+ data.velocities[m_indexA].w = wA;
524
+ // data.velocities[m_indexB].v.set(vB);
525
+ data.velocities[m_indexB].w = wB;
526
+
527
+ pool.pushRot(2);
528
+ pool.pushVec2(4);
529
+ }
530
+
531
+ @Override
532
+ public void solveVelocityConstraints(final SolverData data) {
533
+ Vec2 vA = data.velocities[m_indexA].v;
534
+ float wA = data.velocities[m_indexA].w;
535
+ Vec2 vB = data.velocities[m_indexB].v;
536
+ float wB = data.velocities[m_indexB].w;
537
+
538
+ float mA = m_invMassA, mB = m_invMassB;
539
+ float iA = m_invIA, iB = m_invIB;
540
+
541
+ final Vec2 temp = pool.popVec2();
542
+
543
+ // Solve linear motor constraint.
544
+ if (m_enableMotor && m_limitState != LimitState.EQUAL) {
545
+ temp.set(vB).subLocal(vA);
546
+ float Cdot = Vec2.dot(m_axis, temp) + m_a2 * wB - m_a1 * wA;
547
+ float impulse = m_motorMass * (m_motorSpeed - Cdot);
548
+ float oldImpulse = m_motorImpulse;
549
+ float maxImpulse = data.step.dt * m_maxMotorForce;
550
+ m_motorImpulse = MathUtils.clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse);
551
+ impulse = m_motorImpulse - oldImpulse;
552
+
553
+ final Vec2 P = pool.popVec2();
554
+ P.set(m_axis).mulLocal(impulse);
555
+ float LA = impulse * m_a1;
556
+ float LB = impulse * m_a2;
557
+
558
+ vA.x -= mA * P.x;
559
+ vA.y -= mA * P.y;
560
+ wA -= iA * LA;
561
+
562
+ vB.x += mB * P.x;
563
+ vB.y += mB * P.y;
564
+ wB += iB * LB;
565
+
566
+ pool.pushVec2(1);
567
+ }
568
+
569
+ final Vec2 Cdot1 = pool.popVec2();
570
+ temp.set(vB).subLocal(vA);
571
+ Cdot1.x = Vec2.dot(m_perp, temp) + m_s2 * wB - m_s1 * wA;
572
+ Cdot1.y = wB - wA;
573
+ // System.out.println(Cdot1);
574
+
575
+ if (m_enableLimit && m_limitState != LimitState.INACTIVE) {
576
+ // Solve prismatic and limit constraint in block form.
577
+ float Cdot2;
578
+ temp.set(vB).subLocal(vA);
579
+ Cdot2 = Vec2.dot(m_axis, temp) + m_a2 * wB - m_a1 * wA;
580
+
581
+ final Vec3 Cdot = pool.popVec3();
582
+ Cdot.set(Cdot1.x, Cdot1.y, Cdot2);
583
+
584
+ final Vec3 f1 = pool.popVec3();
585
+ final Vec3 df = pool.popVec3();
586
+
587
+ f1.set(m_impulse);
588
+ m_K.solve33ToOut(Cdot.negateLocal(), df);
589
+ // Cdot.negateLocal(); not used anymore
590
+ m_impulse.addLocal(df);
591
+
592
+ if (m_limitState == LimitState.AT_LOWER) {
593
+ m_impulse.z = MathUtils.max(m_impulse.z, 0.0f);
594
+ } else if (m_limitState == LimitState.AT_UPPER) {
595
+ m_impulse.z = MathUtils.min(m_impulse.z, 0.0f);
596
+ }
597
+
598
+ // f2(1:2) = invK(1:2,1:2) * (-Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3))) +
599
+ // f1(1:2)
600
+ final Vec2 b = pool.popVec2();
601
+ final Vec2 f2r = pool.popVec2();
602
+
603
+ temp.set(m_K.ez.x, m_K.ez.y).mulLocal(m_impulse.z - f1.z);
604
+ b.set(Cdot1).negateLocal().subLocal(temp);
605
+
606
+ m_K.solve22ToOut(b, f2r);
607
+ f2r.addLocal(f1.x, f1.y);
608
+ m_impulse.x = f2r.x;
609
+ m_impulse.y = f2r.y;
610
+
611
+ df.set(m_impulse).subLocal(f1);
612
+
613
+ final Vec2 P = pool.popVec2();
614
+ temp.set(m_axis).mulLocal(df.z);
615
+ P.set(m_perp).mulLocal(df.x).addLocal(temp);
616
+
617
+ float LA = df.x * m_s1 + df.y + df.z * m_a1;
618
+ float LB = df.x * m_s2 + df.y + df.z * m_a2;
619
+
620
+ vA.x -= mA * P.x;
621
+ vA.y -= mA * P.y;
622
+ wA -= iA * LA;
623
+
624
+ vB.x += mB * P.x;
625
+ vB.y += mB * P.y;
626
+ wB += iB * LB;
627
+
628
+ pool.pushVec2(3);
629
+ pool.pushVec3(3);
630
+ } else {
631
+ // Limit is inactive, just solve the prismatic constraint in block form.
632
+ final Vec2 df = pool.popVec2();
633
+ m_K.solve22ToOut(Cdot1.negateLocal(), df);
634
+ Cdot1.negateLocal();
635
+
636
+ m_impulse.x += df.x;
637
+ m_impulse.y += df.y;
638
+
639
+ final Vec2 P = pool.popVec2();
640
+ P.set(m_perp).mulLocal(df.x);
641
+ float LA = df.x * m_s1 + df.y;
642
+ float LB = df.x * m_s2 + df.y;
643
+
644
+ vA.x -= mA * P.x;
645
+ vA.y -= mA * P.y;
646
+ wA -= iA * LA;
647
+
648
+ vB.x += mB * P.x;
649
+ vB.y += mB * P.y;
650
+ wB += iB * LB;
651
+
652
+ pool.pushVec2(2);
653
+ }
654
+
655
+ // data.velocities[m_indexA].v.set(vA);
656
+ data.velocities[m_indexA].w = wA;
657
+ // data.velocities[m_indexB].v.set(vB);
658
+ data.velocities[m_indexB].w = wB;
659
+
660
+ pool.pushVec2(2);
661
+ }
662
+
663
+
664
+ @Override
665
+ public boolean solvePositionConstraints(final SolverData data) {
666
+
667
+ final Rot qA = pool.popRot();
668
+ final Rot qB = pool.popRot();
669
+ final Vec2 rA = pool.popVec2();
670
+ final Vec2 rB = pool.popVec2();
671
+ final Vec2 d = pool.popVec2();
672
+ final Vec2 axis = pool.popVec2();
673
+ final Vec2 perp = pool.popVec2();
674
+ final Vec2 temp = pool.popVec2();
675
+ final Vec2 C1 = pool.popVec2();
676
+
677
+ final Vec3 impulse = pool.popVec3();
678
+
679
+ Vec2 cA = data.positions[m_indexA].c;
680
+ float aA = data.positions[m_indexA].a;
681
+ Vec2 cB = data.positions[m_indexB].c;
682
+ float aB = data.positions[m_indexB].a;
683
+
684
+ qA.set(aA);
685
+ qB.set(aB);
686
+
687
+ float mA = m_invMassA, mB = m_invMassB;
688
+ float iA = m_invIA, iB = m_invIB;
689
+
690
+ // Compute fresh Jacobians
691
+ Rot.mulToOutUnsafe(qA, temp.set(m_localAnchorA).subLocal(m_localCenterA), rA);
692
+ Rot.mulToOutUnsafe(qB, temp.set(m_localAnchorB).subLocal(m_localCenterB), rB);
693
+ d.set(cB).addLocal(rB).subLocal(cA).subLocal(rA);
694
+
695
+ Rot.mulToOutUnsafe(qA, m_localXAxisA, axis);
696
+ float a1 = Vec2.cross(temp.set(d).addLocal(rA), axis);
697
+ float a2 = Vec2.cross(rB, axis);
698
+ Rot.mulToOutUnsafe(qA, m_localYAxisA, perp);
699
+
700
+ float s1 = Vec2.cross(temp.set(d).addLocal(rA), perp);
701
+ float s2 = Vec2.cross(rB, perp);
702
+
703
+ C1.x = Vec2.dot(perp, d);
704
+ C1.y = aB - aA - m_referenceAngle;
705
+
706
+ float linearError = MathUtils.abs(C1.x);
707
+ float angularError = MathUtils.abs(C1.y);
708
+
709
+ boolean active = false;
710
+ float C2 = 0.0f;
711
+ if (m_enableLimit) {
712
+ float translation = Vec2.dot(axis, d);
713
+ if (MathUtils.abs(m_upperTranslation - m_lowerTranslation) < 2.0f * Settings.linearSlop) {
714
+ // Prevent large angular corrections
715
+ C2 =
716
+ MathUtils.clamp(translation, -Settings.maxLinearCorrection,
717
+ Settings.maxLinearCorrection);
718
+ linearError = MathUtils.max(linearError, MathUtils.abs(translation));
719
+ active = true;
720
+ } else if (translation <= m_lowerTranslation) {
721
+ // Prevent large linear corrections and allow some slop.
722
+ C2 =
723
+ MathUtils.clamp(translation - m_lowerTranslation + Settings.linearSlop,
724
+ -Settings.maxLinearCorrection, 0.0f);
725
+ linearError = MathUtils.max(linearError, m_lowerTranslation - translation);
726
+ active = true;
727
+ } else if (translation >= m_upperTranslation) {
728
+ // Prevent large linear corrections and allow some slop.
729
+ C2 =
730
+ MathUtils.clamp(translation - m_upperTranslation - Settings.linearSlop, 0.0f,
731
+ Settings.maxLinearCorrection);
732
+ linearError = MathUtils.max(linearError, translation - m_upperTranslation);
733
+ active = true;
734
+ }
735
+ }
736
+
737
+ if (active) {
738
+ float k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;
739
+ float k12 = iA * s1 + iB * s2;
740
+ float k13 = iA * s1 * a1 + iB * s2 * a2;
741
+ float k22 = iA + iB;
742
+ if (k22 == 0.0f) {
743
+ // For fixed rotation
744
+ k22 = 1.0f;
745
+ }
746
+ float k23 = iA * a1 + iB * a2;
747
+ float k33 = mA + mB + iA * a1 * a1 + iB * a2 * a2;
748
+
749
+ final Mat33 K = pool.popMat33();
750
+ K.ex.set(k11, k12, k13);
751
+ K.ey.set(k12, k22, k23);
752
+ K.ez.set(k13, k23, k33);
753
+
754
+ final Vec3 C = pool.popVec3();
755
+ C.x = C1.x;
756
+ C.y = C1.y;
757
+ C.z = C2;
758
+
759
+ K.solve33ToOut(C.negateLocal(), impulse);
760
+ pool.pushVec3(1);
761
+ pool.pushMat33(1);
762
+ } else {
763
+ float k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;
764
+ float k12 = iA * s1 + iB * s2;
765
+ float k22 = iA + iB;
766
+ if (k22 == 0.0f) {
767
+ k22 = 1.0f;
768
+ }
769
+
770
+ final Mat22 K = pool.popMat22();
771
+ K.ex.set(k11, k12);
772
+ K.ey.set(k12, k22);
773
+
774
+ // temp is impulse1
775
+ K.solveToOut(C1.negateLocal(), temp);
776
+ C1.negateLocal();
777
+
778
+ impulse.x = temp.x;
779
+ impulse.y = temp.y;
780
+ impulse.z = 0.0f;
781
+
782
+ pool.pushMat22(1);
783
+ }
784
+
785
+ float Px = impulse.x * perp.x + impulse.z * axis.x;
786
+ float Py = impulse.x * perp.y + impulse.z * axis.y;
787
+ float LA = impulse.x * s1 + impulse.y + impulse.z * a1;
788
+ float LB = impulse.x * s2 + impulse.y + impulse.z * a2;
789
+
790
+ cA.x -= mA * Px;
791
+ cA.y -= mA * Py;
792
+ aA -= iA * LA;
793
+ cB.x += mB * Px;
794
+ cB.y += mB * Py;
795
+ aB += iB * LB;
796
+
797
+ // data.positions[m_indexA].c.set(cA);
798
+ data.positions[m_indexA].a = aA;
799
+ // data.positions[m_indexB].c.set(cB);
800
+ data.positions[m_indexB].a = aB;
801
+
802
+ pool.pushVec2(7);
803
+ pool.pushVec3(1);
804
+ pool.pushRot(2);
805
+
806
+ return linearError <= Settings.linearSlop && angularError <= Settings.angularSlop;
807
+ }
808
+ }