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,773 @@
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.collision;
25
+
26
+ import org.jbox2d.collision.shapes.ChainShape;
27
+ import org.jbox2d.collision.shapes.CircleShape;
28
+ import org.jbox2d.collision.shapes.EdgeShape;
29
+ import org.jbox2d.collision.shapes.PolygonShape;
30
+ import org.jbox2d.collision.shapes.Shape;
31
+ import org.jbox2d.common.MathUtils;
32
+ import org.jbox2d.common.Rot;
33
+ import org.jbox2d.common.Settings;
34
+ import org.jbox2d.common.Vec2;
35
+ import org.jbox2d.common.Transform;
36
+
37
+ // updated to rev 100
38
+ /**
39
+ * This is non-static for faster pooling. To get an instance, use the {@link SingletonPool}, don't
40
+ * construct a distance object.
41
+ *
42
+ * @author Daniel Murphy
43
+ */
44
+ public class Distance {
45
+ public static final int MAX_ITERS = 20;
46
+
47
+ public static int GJK_CALLS = 0;
48
+ public static int GJK_ITERS = 0;
49
+ public static int GJK_MAX_ITERS = 20;
50
+
51
+ /**
52
+ * GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates.
53
+ */
54
+ private class SimplexVertex {
55
+ public final Vec2 wA = new Vec2(); // support point in shapeA
56
+ public final Vec2 wB = new Vec2(); // support point in shapeB
57
+ public final Vec2 w = new Vec2(); // wB - wA
58
+ public float a; // barycentric coordinate for closest point
59
+ public int indexA; // wA index
60
+ public int indexB; // wB index
61
+
62
+ public void set(SimplexVertex sv) {
63
+ wA.set(sv.wA);
64
+ wB.set(sv.wB);
65
+ w.set(sv.w);
66
+ a = sv.a;
67
+ indexA = sv.indexA;
68
+ indexB = sv.indexB;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Used to warm start Distance. Set count to zero on first call.
74
+ *
75
+ * @author daniel
76
+ */
77
+ public static class SimplexCache {
78
+ /** length or area */
79
+ public float metric;
80
+ public int count;
81
+ /** vertices on shape A */
82
+ public final int indexA[] = new int[3];
83
+ /** vertices on shape B */
84
+ public final int indexB[] = new int[3];
85
+
86
+ public SimplexCache() {
87
+ metric = 0;
88
+ count = 0;
89
+ indexA[0] = Integer.MAX_VALUE;
90
+ indexA[1] = Integer.MAX_VALUE;
91
+ indexA[2] = Integer.MAX_VALUE;
92
+ indexB[0] = Integer.MAX_VALUE;
93
+ indexB[1] = Integer.MAX_VALUE;
94
+ indexB[2] = Integer.MAX_VALUE;
95
+ }
96
+
97
+ public void set(SimplexCache sc) {
98
+ System.arraycopy(sc.indexA, 0, indexA, 0, indexA.length);
99
+ System.arraycopy(sc.indexB, 0, indexB, 0, indexB.length);
100
+ metric = sc.metric;
101
+ count = sc.count;
102
+ }
103
+ }
104
+
105
+ private class Simplex {
106
+ public final SimplexVertex m_v1 = new SimplexVertex();
107
+ public final SimplexVertex m_v2 = new SimplexVertex();
108
+ public final SimplexVertex m_v3 = new SimplexVertex();
109
+ public final SimplexVertex vertices[] = {m_v1, m_v2, m_v3};
110
+ public int m_count;
111
+
112
+ public void readCache(SimplexCache cache, DistanceProxy proxyA, Transform transformA,
113
+ DistanceProxy proxyB, Transform transformB) {
114
+ assert (cache.count <= 3);
115
+
116
+ // Copy data from cache.
117
+ m_count = cache.count;
118
+
119
+ for (int i = 0; i < m_count; ++i) {
120
+ SimplexVertex v = vertices[i];
121
+ v.indexA = cache.indexA[i];
122
+ v.indexB = cache.indexB[i];
123
+ Vec2 wALocal = proxyA.getVertex(v.indexA);
124
+ Vec2 wBLocal = proxyB.getVertex(v.indexB);
125
+ Transform.mulToOutUnsafe(transformA, wALocal, v.wA);
126
+ Transform.mulToOutUnsafe(transformB, wBLocal, v.wB);
127
+ v.w.set(v.wB).subLocal(v.wA);
128
+ v.a = 0.0f;
129
+ }
130
+
131
+ // Compute the new simplex metric, if it is substantially different than
132
+ // old metric then flush the simplex.
133
+ if (m_count > 1) {
134
+ float metric1 = cache.metric;
135
+ float metric2 = getMetric();
136
+ if (metric2 < 0.5f * metric1 || 2.0f * metric1 < metric2 || metric2 < Settings.EPSILON) {
137
+ // Reset the simplex.
138
+ m_count = 0;
139
+ }
140
+ }
141
+
142
+ // If the cache is empty or invalid ...
143
+ if (m_count == 0) {
144
+ SimplexVertex v = vertices[0];
145
+ v.indexA = 0;
146
+ v.indexB = 0;
147
+ Vec2 wALocal = proxyA.getVertex(0);
148
+ Vec2 wBLocal = proxyB.getVertex(0);
149
+ Transform.mulToOutUnsafe(transformA, wALocal, v.wA);
150
+ Transform.mulToOutUnsafe(transformB, wBLocal, v.wB);
151
+ v.w.set(v.wB).subLocal(v.wA);
152
+ m_count = 1;
153
+ }
154
+ }
155
+
156
+ public void writeCache(SimplexCache cache) {
157
+ cache.metric = getMetric();
158
+ cache.count = m_count;
159
+
160
+ for (int i = 0; i < m_count; ++i) {
161
+ cache.indexA[i] = (vertices[i].indexA);
162
+ cache.indexB[i] = (vertices[i].indexB);
163
+ }
164
+ }
165
+
166
+ private final Vec2 e12 = new Vec2();
167
+
168
+ public final void getSearchDirection(final Vec2 out) {
169
+ switch (m_count) {
170
+ case 1:
171
+ out.set(m_v1.w).negateLocal();
172
+ return;
173
+ case 2:
174
+ e12.set(m_v2.w).subLocal(m_v1.w);
175
+ // use out for a temp variable real quick
176
+ out.set(m_v1.w).negateLocal();
177
+ float sgn = Vec2.cross(e12, out);
178
+
179
+ if (sgn > 0f) {
180
+ // Origin is left of e12.
181
+ Vec2.crossToOutUnsafe(1f, e12, out);
182
+ return;
183
+ } else {
184
+ // Origin is right of e12.
185
+ Vec2.crossToOutUnsafe(e12, 1f, out);
186
+ return;
187
+ }
188
+ default:
189
+ assert (false);
190
+ out.setZero();
191
+ return;
192
+ }
193
+ }
194
+
195
+ // djm pooled
196
+ private final Vec2 case2 = new Vec2();
197
+ private final Vec2 case22 = new Vec2();
198
+
199
+ /**
200
+ * this returns pooled objects. don't keep or modify them
201
+ *
202
+ * @return
203
+ */
204
+ public void getClosestPoint(final Vec2 out) {
205
+ switch (m_count) {
206
+ case 0:
207
+ assert (false);
208
+ out.setZero();
209
+ return;
210
+ case 1:
211
+ out.set(m_v1.w);
212
+ return;
213
+ case 2:
214
+ case22.set(m_v2.w).mulLocal(m_v2.a);
215
+ case2.set(m_v1.w).mulLocal(m_v1.a).addLocal(case22);
216
+ out.set(case2);
217
+ return;
218
+ case 3:
219
+ out.setZero();
220
+ return;
221
+ default:
222
+ assert (false);
223
+ out.setZero();
224
+ return;
225
+ }
226
+ }
227
+
228
+ // djm pooled, and from above
229
+ private final Vec2 case3 = new Vec2();
230
+ private final Vec2 case33 = new Vec2();
231
+
232
+ public void getWitnessPoints(Vec2 pA, Vec2 pB) {
233
+ switch (m_count) {
234
+ case 0:
235
+ assert (false);
236
+ break;
237
+
238
+ case 1:
239
+ pA.set(m_v1.wA);
240
+ pB.set(m_v1.wB);
241
+ break;
242
+
243
+ case 2:
244
+ case2.set(m_v1.wA).mulLocal(m_v1.a);
245
+ pA.set(m_v2.wA).mulLocal(m_v2.a).addLocal(case2);
246
+ // m_v1.a * m_v1.wA + m_v2.a * m_v2.wA;
247
+ // *pB = m_v1.a * m_v1.wB + m_v2.a * m_v2.wB;
248
+ case2.set(m_v1.wB).mulLocal(m_v1.a);
249
+ pB.set(m_v2.wB).mulLocal(m_v2.a).addLocal(case2);
250
+
251
+ break;
252
+
253
+ case 3:
254
+ pA.set(m_v1.wA).mulLocal(m_v1.a);
255
+ case3.set(m_v2.wA).mulLocal(m_v2.a);
256
+ case33.set(m_v3.wA).mulLocal(m_v3.a);
257
+ pA.addLocal(case3).addLocal(case33);
258
+ pB.set(pA);
259
+ // *pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA + m_v3.a * m_v3.wA;
260
+ // *pB = *pA;
261
+ break;
262
+
263
+ default:
264
+ assert (false);
265
+ break;
266
+ }
267
+ }
268
+
269
+ // djm pooled, from above
270
+ public float getMetric() {
271
+ switch (m_count) {
272
+ case 0:
273
+ assert (false);
274
+ return 0.0f;
275
+
276
+ case 1:
277
+ return 0.0f;
278
+
279
+ case 2:
280
+ return MathUtils.distance(m_v1.w, m_v2.w);
281
+
282
+ case 3:
283
+ case3.set(m_v2.w).subLocal(m_v1.w);
284
+ case33.set(m_v3.w).subLocal(m_v1.w);
285
+ // return Vec2.cross(m_v2.w - m_v1.w, m_v3.w - m_v1.w);
286
+ return Vec2.cross(case3, case33);
287
+
288
+ default:
289
+ assert (false);
290
+ return 0.0f;
291
+ }
292
+ }
293
+
294
+ // djm pooled from above
295
+ /**
296
+ * Solve a line segment using barycentric coordinates.
297
+ */
298
+ public void solve2() {
299
+ // Solve a line segment using barycentric coordinates.
300
+ //
301
+ // p = a1 * w1 + a2 * w2
302
+ // a1 + a2 = 1
303
+ //
304
+ // The vector from the origin to the closest point on the line is
305
+ // perpendicular to the line.
306
+ // e12 = w2 - w1
307
+ // dot(p, e) = 0
308
+ // a1 * dot(w1, e) + a2 * dot(w2, e) = 0
309
+ //
310
+ // 2-by-2 linear system
311
+ // [1 1 ][a1] = [1]
312
+ // [w1.e12 w2.e12][a2] = [0]
313
+ //
314
+ // Define
315
+ // d12_1 = dot(w2, e12)
316
+ // d12_2 = -dot(w1, e12)
317
+ // d12 = d12_1 + d12_2
318
+ //
319
+ // Solution
320
+ // a1 = d12_1 / d12
321
+ // a2 = d12_2 / d12
322
+ final Vec2 w1 = m_v1.w;
323
+ final Vec2 w2 = m_v2.w;
324
+ e12.set(w2).subLocal(w1);
325
+
326
+ // w1 region
327
+ float d12_2 = -Vec2.dot(w1, e12);
328
+ if (d12_2 <= 0.0f) {
329
+ // a2 <= 0, so we clamp it to 0
330
+ m_v1.a = 1.0f;
331
+ m_count = 1;
332
+ return;
333
+ }
334
+
335
+ // w2 region
336
+ float d12_1 = Vec2.dot(w2, e12);
337
+ if (d12_1 <= 0.0f) {
338
+ // a1 <= 0, so we clamp it to 0
339
+ m_v2.a = 1.0f;
340
+ m_count = 1;
341
+ m_v1.set(m_v2);
342
+ return;
343
+ }
344
+
345
+ // Must be in e12 region.
346
+ float inv_d12 = 1.0f / (d12_1 + d12_2);
347
+ m_v1.a = d12_1 * inv_d12;
348
+ m_v2.a = d12_2 * inv_d12;
349
+ m_count = 2;
350
+ }
351
+
352
+ // djm pooled, and from above
353
+ private final Vec2 e13 = new Vec2();
354
+ private final Vec2 e23 = new Vec2();
355
+ private final Vec2 w1 = new Vec2();
356
+ private final Vec2 w2 = new Vec2();
357
+ private final Vec2 w3 = new Vec2();
358
+
359
+ /**
360
+ * Solve a line segment using barycentric coordinates.<br/>
361
+ * Possible regions:<br/>
362
+ * - points[2]<br/>
363
+ * - edge points[0]-points[2]<br/>
364
+ * - edge points[1]-points[2]<br/>
365
+ * - inside the triangle
366
+ */
367
+ public void solve3() {
368
+ w1.set(m_v1.w);
369
+ w2.set(m_v2.w);
370
+ w3.set(m_v3.w);
371
+
372
+ // Edge12
373
+ // [1 1 ][a1] = [1]
374
+ // [w1.e12 w2.e12][a2] = [0]
375
+ // a3 = 0
376
+ e12.set(w2).subLocal(w1);
377
+ float w1e12 = Vec2.dot(w1, e12);
378
+ float w2e12 = Vec2.dot(w2, e12);
379
+ float d12_1 = w2e12;
380
+ float d12_2 = -w1e12;
381
+
382
+ // Edge13
383
+ // [1 1 ][a1] = [1]
384
+ // [w1.e13 w3.e13][a3] = [0]
385
+ // a2 = 0
386
+ e13.set(w3).subLocal(w1);
387
+ float w1e13 = Vec2.dot(w1, e13);
388
+ float w3e13 = Vec2.dot(w3, e13);
389
+ float d13_1 = w3e13;
390
+ float d13_2 = -w1e13;
391
+
392
+ // Edge23
393
+ // [1 1 ][a2] = [1]
394
+ // [w2.e23 w3.e23][a3] = [0]
395
+ // a1 = 0
396
+ e23.set(w3).subLocal(w2);
397
+ float w2e23 = Vec2.dot(w2, e23);
398
+ float w3e23 = Vec2.dot(w3, e23);
399
+ float d23_1 = w3e23;
400
+ float d23_2 = -w2e23;
401
+
402
+ // Triangle123
403
+ float n123 = Vec2.cross(e12, e13);
404
+
405
+ float d123_1 = n123 * Vec2.cross(w2, w3);
406
+ float d123_2 = n123 * Vec2.cross(w3, w1);
407
+ float d123_3 = n123 * Vec2.cross(w1, w2);
408
+
409
+ // w1 region
410
+ if (d12_2 <= 0.0f && d13_2 <= 0.0f) {
411
+ m_v1.a = 1.0f;
412
+ m_count = 1;
413
+ return;
414
+ }
415
+
416
+ // e12
417
+ if (d12_1 > 0.0f && d12_2 > 0.0f && d123_3 <= 0.0f) {
418
+ float inv_d12 = 1.0f / (d12_1 + d12_2);
419
+ m_v1.a = d12_1 * inv_d12;
420
+ m_v2.a = d12_2 * inv_d12;
421
+ m_count = 2;
422
+ return;
423
+ }
424
+
425
+ // e13
426
+ if (d13_1 > 0.0f && d13_2 > 0.0f && d123_2 <= 0.0f) {
427
+ float inv_d13 = 1.0f / (d13_1 + d13_2);
428
+ m_v1.a = d13_1 * inv_d13;
429
+ m_v3.a = d13_2 * inv_d13;
430
+ m_count = 2;
431
+ m_v2.set(m_v3);
432
+ return;
433
+ }
434
+
435
+ // w2 region
436
+ if (d12_1 <= 0.0f && d23_2 <= 0.0f) {
437
+ m_v2.a = 1.0f;
438
+ m_count = 1;
439
+ m_v1.set(m_v2);
440
+ return;
441
+ }
442
+
443
+ // w3 region
444
+ if (d13_1 <= 0.0f && d23_1 <= 0.0f) {
445
+ m_v3.a = 1.0f;
446
+ m_count = 1;
447
+ m_v1.set(m_v3);
448
+ return;
449
+ }
450
+
451
+ // e23
452
+ if (d23_1 > 0.0f && d23_2 > 0.0f && d123_1 <= 0.0f) {
453
+ float inv_d23 = 1.0f / (d23_1 + d23_2);
454
+ m_v2.a = d23_1 * inv_d23;
455
+ m_v3.a = d23_2 * inv_d23;
456
+ m_count = 2;
457
+ m_v1.set(m_v3);
458
+ return;
459
+ }
460
+
461
+ // Must be in triangle123
462
+ float inv_d123 = 1.0f / (d123_1 + d123_2 + d123_3);
463
+ m_v1.a = d123_1 * inv_d123;
464
+ m_v2.a = d123_2 * inv_d123;
465
+ m_v3.a = d123_3 * inv_d123;
466
+ m_count = 3;
467
+ }
468
+ }
469
+
470
+ /**
471
+ * A distance proxy is used by the GJK algorithm. It encapsulates any shape. TODO: see if we can
472
+ * just do assignments with m_vertices, instead of copying stuff over
473
+ *
474
+ * @author daniel
475
+ */
476
+ public static class DistanceProxy {
477
+ public final Vec2[] m_vertices;
478
+ public int m_count;
479
+ public float m_radius;
480
+ public final Vec2[] m_buffer;
481
+
482
+ public DistanceProxy() {
483
+ m_vertices = new Vec2[Settings.maxPolygonVertices];
484
+ for (int i = 0; i < m_vertices.length; i++) {
485
+ m_vertices[i] = new Vec2();
486
+ }
487
+ m_buffer = new Vec2[2];
488
+ m_count = 0;
489
+ m_radius = 0f;
490
+ }
491
+
492
+ /**
493
+ * Initialize the proxy using the given shape. The shape must remain in scope while the proxy is
494
+ * in use.
495
+ */
496
+ public final void set(final Shape shape, int index) {
497
+ switch (shape.getType()) {
498
+ case CIRCLE:
499
+ final CircleShape circle = (CircleShape) shape;
500
+ m_vertices[0].set(circle.m_p);
501
+ m_count = 1;
502
+ m_radius = circle.m_radius;
503
+
504
+ break;
505
+ case POLYGON:
506
+ final PolygonShape poly = (PolygonShape) shape;
507
+ m_count = poly.m_count;
508
+ m_radius = poly.m_radius;
509
+ for (int i = 0; i < m_count; i++) {
510
+ m_vertices[i].set(poly.m_vertices[i]);
511
+ }
512
+ break;
513
+ case CHAIN:
514
+ final ChainShape chain = (ChainShape) shape;
515
+ assert (0 <= index && index < chain.m_count);
516
+
517
+ m_buffer[0] = chain.m_vertices[index];
518
+ if (index + 1 < chain.m_count) {
519
+ m_buffer[1] = chain.m_vertices[index + 1];
520
+ } else {
521
+ m_buffer[1] = chain.m_vertices[0];
522
+ }
523
+
524
+ m_vertices[0].set(m_buffer[0]);
525
+ m_vertices[1].set(m_buffer[1]);
526
+ m_count = 2;
527
+ m_radius = chain.m_radius;
528
+ break;
529
+ case EDGE:
530
+ EdgeShape edge = (EdgeShape) shape;
531
+ m_vertices[0].set(edge.m_vertex1);
532
+ m_vertices[1].set(edge.m_vertex2);
533
+ m_count = 2;
534
+ m_radius = edge.m_radius;
535
+ break;
536
+ default:
537
+ assert (false);
538
+ }
539
+ }
540
+
541
+ /**
542
+ * Get the supporting vertex index in the given direction.
543
+ *
544
+ * @param d
545
+ * @return
546
+ */
547
+ public final int getSupport(final Vec2 d) {
548
+ int bestIndex = 0;
549
+ float bestValue = Vec2.dot(m_vertices[0], d);
550
+ for (int i = 1; i < m_count; i++) {
551
+ float value = Vec2.dot(m_vertices[i], d);
552
+ if (value > bestValue) {
553
+ bestIndex = i;
554
+ bestValue = value;
555
+ }
556
+ }
557
+
558
+ return bestIndex;
559
+ }
560
+
561
+ /**
562
+ * Get the supporting vertex in the given direction.
563
+ *
564
+ * @param d
565
+ * @return
566
+ */
567
+ public final Vec2 getSupportVertex(final Vec2 d) {
568
+ int bestIndex = 0;
569
+ float bestValue = Vec2.dot(m_vertices[0], d);
570
+ for (int i = 1; i < m_count; i++) {
571
+ float value = Vec2.dot(m_vertices[i], d);
572
+ if (value > bestValue) {
573
+ bestIndex = i;
574
+ bestValue = value;
575
+ }
576
+ }
577
+
578
+ return m_vertices[bestIndex];
579
+ }
580
+
581
+ /**
582
+ * Get the vertex count.
583
+ *
584
+ * @return
585
+ */
586
+ public final int getVertexCount() {
587
+ return m_count;
588
+ }
589
+
590
+ /**
591
+ * Get a vertex by index. Used by Distance.
592
+ *
593
+ * @param index
594
+ * @return
595
+ */
596
+ public final Vec2 getVertex(int index) {
597
+ assert (0 <= index && index < m_count);
598
+ return m_vertices[index];
599
+ }
600
+ }
601
+
602
+ private Simplex simplex = new Simplex();
603
+ private int[] saveA = new int[3];
604
+ private int[] saveB = new int[3];
605
+ private Vec2 closestPoint = new Vec2();
606
+ private Vec2 d = new Vec2();
607
+ private Vec2 temp = new Vec2();
608
+ private Vec2 normal = new Vec2();
609
+
610
+ /**
611
+ * Compute the closest points between two shapes. Supports any combination of: CircleShape and
612
+ * PolygonShape. The simplex cache is input/output. On the first call set SimplexCache.count to
613
+ * zero.
614
+ *
615
+ * @param output
616
+ * @param cache
617
+ * @param input
618
+ */
619
+ public final void distance(final DistanceOutput output, final SimplexCache cache,
620
+ final DistanceInput input) {
621
+ GJK_CALLS++;
622
+
623
+ final DistanceProxy proxyA = input.proxyA;
624
+ final DistanceProxy proxyB = input.proxyB;
625
+
626
+ Transform transformA = input.transformA;
627
+ Transform transformB = input.transformB;
628
+
629
+ // Initialize the simplex.
630
+ simplex.readCache(cache, proxyA, transformA, proxyB, transformB);
631
+
632
+ // Get simplex vertices as an array.
633
+ SimplexVertex[] vertices = simplex.vertices;
634
+
635
+ // These store the vertices of the last simplex so that we
636
+ // can check for duplicates and prevent cycling.
637
+ // (pooled above)
638
+ int saveCount = 0;
639
+
640
+ simplex.getClosestPoint(closestPoint);
641
+ float distanceSqr1 = closestPoint.lengthSquared();
642
+ float distanceSqr2 = distanceSqr1;
643
+
644
+ // Main iteration loop
645
+ int iter = 0;
646
+ while (iter < MAX_ITERS) {
647
+
648
+ // Copy simplex so we can identify duplicates.
649
+ saveCount = simplex.m_count;
650
+ for (int i = 0; i < saveCount; i++) {
651
+ saveA[i] = vertices[i].indexA;
652
+ saveB[i] = vertices[i].indexB;
653
+ }
654
+
655
+ switch (simplex.m_count) {
656
+ case 1:
657
+ break;
658
+ case 2:
659
+ simplex.solve2();
660
+ break;
661
+ case 3:
662
+ simplex.solve3();
663
+ break;
664
+ default:
665
+ assert (false);
666
+ }
667
+
668
+ // If we have 3 points, then the origin is in the corresponding triangle.
669
+ if (simplex.m_count == 3) {
670
+ break;
671
+ }
672
+
673
+ // Compute closest point.
674
+ simplex.getClosestPoint(closestPoint);
675
+ distanceSqr2 = closestPoint.lengthSquared();
676
+
677
+ // ensure progress
678
+ if (distanceSqr2 >= distanceSqr1) {
679
+ // break;
680
+ }
681
+ distanceSqr1 = distanceSqr2;
682
+
683
+ // get search direction;
684
+ simplex.getSearchDirection(d);
685
+
686
+ // Ensure the search direction is numerically fit.
687
+ if (d.lengthSquared() < Settings.EPSILON * Settings.EPSILON) {
688
+ // The origin is probably contained by a line segment
689
+ // or triangle. Thus the shapes are overlapped.
690
+
691
+ // We can't return zero here even though there may be overlap.
692
+ // In case the simplex is a point, segment, or triangle it is difficult
693
+ // to determine if the origin is contained in the CSO or very close to it.
694
+ break;
695
+ }
696
+ /*
697
+ * SimplexVertex* vertex = vertices + simplex.m_count; vertex.indexA =
698
+ * proxyA.GetSupport(MulT(transformA.R, -d)); vertex.wA = Mul(transformA,
699
+ * proxyA.GetVertex(vertex.indexA)); Vec2 wBLocal; vertex.indexB =
700
+ * proxyB.GetSupport(MulT(transformB.R, d)); vertex.wB = Mul(transformB,
701
+ * proxyB.GetVertex(vertex.indexB)); vertex.w = vertex.wB - vertex.wA;
702
+ */
703
+
704
+ // Compute a tentative new simplex vertex using support points.
705
+ SimplexVertex vertex = vertices[simplex.m_count];
706
+
707
+ Rot.mulTransUnsafe(transformA.q, d.negateLocal(), temp);
708
+ vertex.indexA = proxyA.getSupport(temp);
709
+ Transform.mulToOutUnsafe(transformA, proxyA.getVertex(vertex.indexA), vertex.wA);
710
+ // Vec2 wBLocal;
711
+ Rot.mulTransUnsafe(transformB.q, d.negateLocal(), temp);
712
+ vertex.indexB = proxyB.getSupport(temp);
713
+ Transform.mulToOutUnsafe(transformB, proxyB.getVertex(vertex.indexB), vertex.wB);
714
+ vertex.w.set(vertex.wB).subLocal(vertex.wA);
715
+
716
+ // Iteration count is equated to the number of support point calls.
717
+ ++iter;
718
+ ++GJK_ITERS;
719
+
720
+ // Check for duplicate support points. This is the main termination criteria.
721
+ boolean duplicate = false;
722
+ for (int i = 0; i < saveCount; ++i) {
723
+ if (vertex.indexA == saveA[i] && vertex.indexB == saveB[i]) {
724
+ duplicate = true;
725
+ break;
726
+ }
727
+ }
728
+
729
+ // If we found a duplicate support point we must exit to avoid cycling.
730
+ if (duplicate) {
731
+ break;
732
+ }
733
+
734
+ // New vertex is ok and needed.
735
+ ++simplex.m_count;
736
+ }
737
+
738
+ GJK_MAX_ITERS = MathUtils.max(GJK_MAX_ITERS, iter);
739
+
740
+ // Prepare output.
741
+ simplex.getWitnessPoints(output.pointA, output.pointB);
742
+ output.distance = MathUtils.distance(output.pointA, output.pointB);
743
+ output.iterations = iter;
744
+
745
+ // Cache the simplex.
746
+ simplex.writeCache(cache);
747
+
748
+ // Apply radii if requested.
749
+ if (input.useRadii) {
750
+ float rA = proxyA.m_radius;
751
+ float rB = proxyB.m_radius;
752
+
753
+ if (output.distance > rA + rB && output.distance > Settings.EPSILON) {
754
+ // Shapes are still no overlapped.
755
+ // Move the witness points to the outer surface.
756
+ output.distance -= rA + rB;
757
+ normal.set(output.pointB).subLocal(output.pointA);
758
+ normal.normalize();
759
+ temp.set(normal).mulLocal(rA);
760
+ output.pointA.addLocal(temp);
761
+ temp.set(normal).mulLocal(rB);
762
+ output.pointB.subLocal(temp);
763
+ } else {
764
+ // Shapes are overlapped when radii are considered.
765
+ // Move the witness points to the middle.
766
+ // Vec2 p = 0.5f * (output.pointA + output.pointB);
767
+ output.pointA.addLocal(output.pointB).mulLocal(.5f);
768
+ output.pointB.set(output.pointA);
769
+ output.distance = 0.0f;
770
+ }
771
+ }
772
+ }
773
+ }