pbox2d 0.6.0-java → 0.8.0-java

Sign up to get free protection for your applications and to get access to all the features.
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
+ }