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,718 @@
1
+ /**
2
+ * *****************************************************************************
3
+ * Copyright (c) 2013, Daniel Murphy
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without modification,
7
+ * are permitted provided that the following conditions are met:
8
+ * * Redistributions of source code must retain the above copyright notice,
9
+ * this list of conditions and the following disclaimer.
10
+ * * Redistributions in binary form must reproduce the above copyright notice,
11
+ * this list of conditions and the following disclaimer in the documentation
12
+ * and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23
+ * POSSIBILITY OF SUCH DAMAGE.
24
+ *****************************************************************************
25
+ */
26
+ package org.jbox2d.collision.shapes;
27
+
28
+ import org.jbox2d.collision.AABB;
29
+ import org.jbox2d.collision.RayCastInput;
30
+ import org.jbox2d.collision.RayCastOutput;
31
+ import org.jbox2d.common.MathUtils;
32
+ import org.jbox2d.common.Rot;
33
+ import org.jbox2d.common.Settings;
34
+ import org.jbox2d.common.Transform;
35
+ import org.jbox2d.common.Vec2;
36
+ import org.jbox2d.pooling.arrays.IntArray;
37
+ import org.jbox2d.pooling.arrays.Vec2Array;
38
+
39
+ /**
40
+ * A convex polygon shape. Polygons have a maximum number of vertices equal to
41
+ * _maxPolygonVertices. In most cases you should not need many vertices for a
42
+ * convex polygon.
43
+ */
44
+ public class PolygonShape extends Shape {
45
+
46
+ /**
47
+ * Dump lots of debug information.
48
+ */
49
+ private final static boolean M_DEBUG = false;
50
+
51
+ /**
52
+ * Local position of the shape centroid in parent body frame.
53
+ */
54
+ public final Vec2 m_centroid = new Vec2();
55
+
56
+ /**
57
+ * The vertices of the shape. Note: use getVertexCount(), not
58
+ * m_vertices.length, to get number of active vertices.
59
+ */
60
+ public final Vec2 m_vertices[];
61
+
62
+ /**
63
+ * The normals of the shape. Note: use getVertexCount(), not
64
+ * m_normals.length, to get number of active normals.
65
+ */
66
+ public final Vec2 m_normals[];
67
+
68
+ /**
69
+ * Number of active vertices in the shape.
70
+ */
71
+ public int m_count;
72
+
73
+ // pooling
74
+ private final Vec2 pool1 = new Vec2();
75
+ private final Vec2 pool2 = new Vec2();
76
+ private final Vec2 pool3 = new Vec2();
77
+ private final Vec2 pool4 = new Vec2();
78
+ private final Transform poolt1 = new Transform();
79
+
80
+ public PolygonShape() {
81
+ super(ShapeType.POLYGON);
82
+
83
+ m_count = 0;
84
+ m_vertices = new Vec2[Settings.maxPolygonVertices];
85
+ for (int i = 0; i < m_vertices.length; i++) {
86
+ m_vertices[i] = new Vec2();
87
+ }
88
+ m_normals = new Vec2[Settings.maxPolygonVertices];
89
+ for (int i = 0; i < m_normals.length; i++) {
90
+ m_normals[i] = new Vec2();
91
+ }
92
+ setRadius(Settings.polygonRadius);
93
+ m_centroid.setZero();
94
+ }
95
+
96
+ @Override
97
+ public final Shape clone() {
98
+ PolygonShape shape = new PolygonShape();
99
+ shape.m_centroid.set(this.m_centroid);
100
+ for (int i = 0; i < shape.m_normals.length; i++) {
101
+ shape.m_normals[i].set(m_normals[i]);
102
+ shape.m_vertices[i].set(m_vertices[i]);
103
+ }
104
+ shape.setRadius(this.getRadius());
105
+ shape.m_count = this.m_count;
106
+ return shape;
107
+ }
108
+
109
+ /**
110
+ * Create a convex hull from the given array of points. The count must be in
111
+ * the range [3, Settings.maxPolygonVertices].
112
+ *
113
+ * @param vertices
114
+ * @param count
115
+ * @warning the points may be re-ordered, even if they form a convex
116
+ * polygon.
117
+ * @warning collinear points are removed.
118
+ */
119
+ public final void set(final Vec2[] vertices, final int count) {
120
+ set(vertices, count, null, null);
121
+ }
122
+
123
+ /**
124
+ * Create a convex hull from the given array of points. The count must be in
125
+ * the range [3, Settings.maxPolygonVertices]. This method takes an
126
+ * arraypool for pooling.
127
+ *
128
+ * @param verts
129
+ * @param num
130
+ * @param vecPool
131
+ * @param intPool
132
+ * @warning the points may be re-ordered, even if they form a convex
133
+ * polygon.
134
+ * @warning collinear points are removed.
135
+ */
136
+ public final void set(final Vec2[] verts, final int num, final Vec2Array vecPool,
137
+ final IntArray intPool) {
138
+ assert (3 <= num && num <= Settings.maxPolygonVertices);
139
+ if (num < 3) {
140
+ setAsBox(1.0f, 1.0f);
141
+ return;
142
+ }
143
+
144
+ int n = MathUtils.min(num, Settings.maxPolygonVertices);
145
+
146
+ // Perform welding and copy vertices into local buffer.
147
+ Vec2[] ps
148
+ = (vecPool != null)
149
+ ? vecPool.get(Settings.maxPolygonVertices)
150
+ : new Vec2[Settings.maxPolygonVertices];
151
+ int tempCount = 0;
152
+ for (int i = 0; i < n; ++i) {
153
+ Vec2 v = verts[i];
154
+ boolean unique = true;
155
+ for (int j = 0; j < tempCount; ++j) {
156
+ if (MathUtils.distanceSquared(v, ps[j]) < 0.5f * Settings.linearSlop) {
157
+ unique = false;
158
+ break;
159
+ }
160
+ }
161
+
162
+ if (unique) {
163
+ ps[tempCount++] = v;
164
+ }
165
+ }
166
+
167
+ n = tempCount;
168
+ if (n < 3) {
169
+ // Polygon is degenerate.
170
+ assert (false);
171
+ setAsBox(1.0f, 1.0f);
172
+ return;
173
+ }
174
+
175
+ // Create the convex hull using the Gift wrapping algorithm
176
+ // http://en.wikipedia.org/wiki/Gift_wrapping_algorithm
177
+ // Find the right most point on the hull
178
+ int i0 = 0;
179
+ float x0 = ps[0].x;
180
+ for (int i = 1; i < n; ++i) {
181
+ float x = ps[i].x;
182
+ if (x > x0 || (x == x0 && ps[i].y < ps[i0].y)) {
183
+ i0 = i;
184
+ x0 = x;
185
+ }
186
+ }
187
+
188
+ int[] hull
189
+ = (intPool != null)
190
+ ? intPool.get(Settings.maxPolygonVertices)
191
+ : new int[Settings.maxPolygonVertices];
192
+ int m = 0;
193
+ int ih = i0;
194
+
195
+ while (true) {
196
+ hull[m] = ih;
197
+
198
+ int ie = 0;
199
+ for (int j = 1; j < n; ++j) {
200
+ if (ie == ih) {
201
+ ie = j;
202
+ continue;
203
+ }
204
+
205
+ Vec2 r = pool1.set(ps[ie]).subLocal(ps[hull[m]]);
206
+ Vec2 v = pool2.set(ps[j]).subLocal(ps[hull[m]]);
207
+ float c = Vec2.cross(r, v);
208
+ if (c < 0.0f) {
209
+ ie = j;
210
+ }
211
+
212
+ // Collinearity check
213
+ if (c == 0.0f && v.lengthSquared() > r.lengthSquared()) {
214
+ ie = j;
215
+ }
216
+ }
217
+
218
+ ++m;
219
+ ih = ie;
220
+
221
+ if (ie == i0) {
222
+ break;
223
+ }
224
+ }
225
+
226
+ this.m_count = m;
227
+
228
+ // Copy vertices.
229
+ for (int i = 0; i < m_count; ++i) {
230
+ if (m_vertices[i] == null) {
231
+ m_vertices[i] = new Vec2();
232
+ }
233
+ m_vertices[i].set(ps[hull[i]]);
234
+ }
235
+
236
+ final Vec2 edge = pool1;
237
+
238
+ // Compute normals. Ensure the edges have non-zero length.
239
+ for (int i = 0; i < m_count; ++i) {
240
+ final int i1 = i;
241
+ final int i2 = i + 1 < m_count ? i + 1 : 0;
242
+ edge.set(m_vertices[i2]).subLocal(m_vertices[i1]);
243
+
244
+ assert (edge.lengthSquared() > Settings.EPSILON * Settings.EPSILON);
245
+ Vec2.crossToOutUnsafe(edge, 1f, m_normals[i]);
246
+ m_normals[i].normalize();
247
+ }
248
+
249
+ // Compute the polygon centroid.
250
+ computeCentroidToOut(m_vertices, m_count, m_centroid);
251
+ }
252
+
253
+ /**
254
+ * Build vertices to represent an axis-aligned box.
255
+ *
256
+ * @param hx the half-width.
257
+ * @param hy the half-height.
258
+ */
259
+ public final void setAsBox(final float hx, final float hy) {
260
+ m_count = 4;
261
+ m_vertices[0].set(-hx, -hy);
262
+ m_vertices[1].set(hx, -hy);
263
+ m_vertices[2].set(hx, hy);
264
+ m_vertices[3].set(-hx, hy);
265
+ m_normals[0].set(0.0f, -1.0f);
266
+ m_normals[1].set(1.0f, 0.0f);
267
+ m_normals[2].set(0.0f, 1.0f);
268
+ m_normals[3].set(-1.0f, 0.0f);
269
+ m_centroid.setZero();
270
+ }
271
+
272
+ /**
273
+ * Build vertices to represent an oriented box.
274
+ *
275
+ * @param hx the half-width.
276
+ * @param hy the half-height.
277
+ * @param center the center of the box in local coordinates.
278
+ * @param angle the rotation of the box in local coordinates.
279
+ */
280
+ public final void setAsBox(final float hx, final float hy, final Vec2 center, final float angle) {
281
+ m_count = 4;
282
+ m_vertices[0].set(-hx, -hy);
283
+ m_vertices[1].set(hx, -hy);
284
+ m_vertices[2].set(hx, hy);
285
+ m_vertices[3].set(-hx, hy);
286
+ m_normals[0].set(0.0f, -1.0f);
287
+ m_normals[1].set(1.0f, 0.0f);
288
+ m_normals[2].set(0.0f, 1.0f);
289
+ m_normals[3].set(-1.0f, 0.0f);
290
+ m_centroid.set(center);
291
+
292
+ final Transform xf = poolt1;
293
+ xf.p.set(center);
294
+ xf.q.set(angle);
295
+
296
+ // Transform vertices and normals.
297
+ for (int i = 0; i < m_count; ++i) {
298
+ Transform.mulToOut(xf, m_vertices[i], m_vertices[i]);
299
+ Rot.mulToOut(xf.q, m_normals[i], m_normals[i]);
300
+ }
301
+ }
302
+
303
+ @Override
304
+ public int getChildCount() {
305
+ return 1;
306
+ }
307
+
308
+ @Override
309
+ public final boolean testPoint(final Transform xf, final Vec2 p) {
310
+ float tempx, tempy;
311
+ final Rot xfq = xf.q;
312
+
313
+ tempx = p.x - xf.p.x;
314
+ tempy = p.y - xf.p.y;
315
+ final float pLocalx = xfq.c * tempx + xfq.s * tempy;
316
+ final float pLocaly = -xfq.s * tempx + xfq.c * tempy;
317
+
318
+ if (M_DEBUG) {
319
+ System.out.println("--testPoint debug--");
320
+ System.out.println("Vertices: ");
321
+ for (int i = 0; i < m_count; ++i) {
322
+ System.out.println(m_vertices[i]);
323
+ }
324
+ System.out.println("pLocal: " + pLocalx + ", " + pLocaly);
325
+ }
326
+
327
+ for (int i = 0; i < m_count; ++i) {
328
+ Vec2 vertex = m_vertices[i];
329
+ Vec2 normal = m_normals[i];
330
+ tempx = pLocalx - vertex.x;
331
+ tempy = pLocaly - vertex.y;
332
+ final float dot = normal.x * tempx + normal.y * tempy;
333
+ if (dot > 0.0f) {
334
+ return false;
335
+ }
336
+ }
337
+
338
+ return true;
339
+ }
340
+
341
+ @Override
342
+ public final void computeAABB(final AABB aabb, final Transform xf, int childIndex) {
343
+ final Vec2 lower = aabb.lowerBound;
344
+ final Vec2 upper = aabb.upperBound;
345
+ final Vec2 v1 = m_vertices[0];
346
+ final float xfqc = xf.q.c;
347
+ final float xfqs = xf.q.s;
348
+ final float xfpx = xf.p.x;
349
+ final float xfpy = xf.p.y;
350
+ lower.x = (xfqc * v1.x - xfqs * v1.y) + xfpx;
351
+ lower.y = (xfqs * v1.x + xfqc * v1.y) + xfpy;
352
+ upper.x = lower.x;
353
+ upper.y = lower.y;
354
+
355
+ for (int i = 1; i < m_count; ++i) {
356
+ Vec2 v2 = m_vertices[i];
357
+ // Vec2 v = Mul(xf, m_vertices[i]);
358
+ float vx = (xfqc * v2.x - xfqs * v2.y) + xfpx;
359
+ float vy = (xfqs * v2.x + xfqc * v2.y) + xfpy;
360
+ lower.x = lower.x < vx ? lower.x : vx;
361
+ lower.y = lower.y < vy ? lower.y : vy;
362
+ upper.x = upper.x > vx ? upper.x : vx;
363
+ upper.y = upper.y > vy ? upper.y : vy;
364
+ }
365
+
366
+ lower.x -= m_radius;
367
+ lower.y -= m_radius;
368
+ upper.x += m_radius;
369
+ upper.y += m_radius;
370
+ }
371
+
372
+ /**
373
+ * Get the vertex count.
374
+ *
375
+ * @return
376
+ */
377
+ public final int getVertexCount() {
378
+ return m_count;
379
+ }
380
+
381
+ /**
382
+ * Get a vertex by index.
383
+ *
384
+ * @param index
385
+ * @return
386
+ */
387
+ public final Vec2 getVertex(final int index) {
388
+ assert (0 <= index && index < m_count);
389
+ return m_vertices[index];
390
+ }
391
+
392
+ @Override
393
+ public float computeDistanceToOut(Transform xf, Vec2 p, int childIndex, Vec2 normalOut) {
394
+ float xfqc = xf.q.c;
395
+ float xfqs = xf.q.s;
396
+ float tx = p.x - xf.p.x;
397
+ float ty = p.y - xf.p.y;
398
+ float pLocalx = xfqc * tx + xfqs * ty;
399
+ float pLocaly = -xfqs * tx + xfqc * ty;
400
+
401
+ float maxDistance = -Float.MAX_VALUE;
402
+ float normalForMaxDistanceX = pLocalx;
403
+ float normalForMaxDistanceY = pLocaly;
404
+
405
+ for (int i = 0; i < m_count; ++i) {
406
+ Vec2 vertex = m_vertices[i];
407
+ Vec2 normal = m_normals[i];
408
+ tx = pLocalx - vertex.x;
409
+ ty = pLocaly - vertex.y;
410
+ float dot = normal.x * tx + normal.y * ty;
411
+ if (dot > maxDistance) {
412
+ maxDistance = dot;
413
+ normalForMaxDistanceX = normal.x;
414
+ normalForMaxDistanceY = normal.y;
415
+ }
416
+ }
417
+
418
+ float distance;
419
+ if (maxDistance > 0) {
420
+ float minDistanceX = normalForMaxDistanceX;
421
+ float minDistanceY = normalForMaxDistanceY;
422
+ float minDistance2 = maxDistance * maxDistance;
423
+ for (int i = 0; i < m_count; ++i) {
424
+ Vec2 vertex = m_vertices[i];
425
+ float distanceVecX = pLocalx - vertex.x;
426
+ float distanceVecY = pLocaly - vertex.y;
427
+ float distance2 = (distanceVecX * distanceVecX + distanceVecY * distanceVecY);
428
+ if (minDistance2 > distance2) {
429
+ minDistanceX = distanceVecX;
430
+ minDistanceY = distanceVecY;
431
+ minDistance2 = distance2;
432
+ }
433
+ }
434
+ distance = MathUtils.sqrt(minDistance2);
435
+ normalOut.x = xfqc * minDistanceX - xfqs * minDistanceY;
436
+ normalOut.y = xfqs * minDistanceX + xfqc * minDistanceY;
437
+ normalOut.normalize();
438
+ } else {
439
+ distance = maxDistance;
440
+ normalOut.x = xfqc * normalForMaxDistanceX - xfqs * normalForMaxDistanceY;
441
+ normalOut.y = xfqs * normalForMaxDistanceX + xfqc * normalForMaxDistanceY;
442
+ }
443
+
444
+ return distance;
445
+ }
446
+
447
+ @Override
448
+ public final boolean raycast(RayCastOutput output, RayCastInput input, Transform xf,
449
+ int childIndex) {
450
+ final float xfqc = xf.q.c;
451
+ final float xfqs = xf.q.s;
452
+ final Vec2 xfp = xf.p;
453
+ float tempx, tempy;
454
+ // b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p);
455
+ // b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p);
456
+ tempx = input.p1.x - xfp.x;
457
+ tempy = input.p1.y - xfp.y;
458
+ final float p1x = xfqc * tempx + xfqs * tempy;
459
+ final float p1y = -xfqs * tempx + xfqc * tempy;
460
+
461
+ tempx = input.p2.x - xfp.x;
462
+ tempy = input.p2.y - xfp.y;
463
+ final float p2x = xfqc * tempx + xfqs * tempy;
464
+ final float p2y = -xfqs * tempx + xfqc * tempy;
465
+
466
+ final float dx = p2x - p1x;
467
+ final float dy = p2y - p1y;
468
+
469
+ float lower = 0, upper = input.maxFraction;
470
+
471
+ int index = -1;
472
+
473
+ for (int i = 0; i < m_count; ++i) {
474
+ Vec2 normal = m_normals[i];
475
+ Vec2 vertex = m_vertices[i];
476
+ // p = p1 + a * d
477
+ // dot(normal, p - v) = 0
478
+ // dot(normal, p1 - v) + a * dot(normal, d) = 0
479
+ float tempxn = vertex.x - p1x;
480
+ float tempyn = vertex.y - p1y;
481
+ final float numerator = normal.x * tempxn + normal.y * tempyn;
482
+ final float denominator = normal.x * dx + normal.y * dy;
483
+
484
+ if (denominator == 0.0f) {
485
+ if (numerator < 0.0f) {
486
+ return false;
487
+ }
488
+ } else // Note: we want this predicate without division:
489
+ // lower < numerator / denominator, where denominator < 0
490
+ // Since denominator < 0, we have to flip the inequality:
491
+ // lower < numerator / denominator <==> denominator * lower >
492
+ // numerator.
493
+ {
494
+ if (denominator < 0.0f && numerator < lower * denominator) {
495
+ // Increase lower.
496
+ // The segment enters this half-space.
497
+ lower = numerator / denominator;
498
+ index = i;
499
+ } else if (denominator > 0.0f && numerator < upper * denominator) {
500
+ // Decrease upper.
501
+ // The segment exits this half-space.
502
+ upper = numerator / denominator;
503
+ }
504
+ }
505
+
506
+ if (upper < lower) {
507
+ return false;
508
+ }
509
+ }
510
+
511
+ assert (0.0f <= lower && lower <= input.maxFraction);
512
+
513
+ if (index >= 0) {
514
+ output.fraction = lower;
515
+ // normal = Mul(xf.R, m_normals[index]);
516
+ Vec2 normal = m_normals[index];
517
+ Vec2 out = output.normal;
518
+ out.x = xfqc * normal.x - xfqs * normal.y;
519
+ out.y = xfqs * normal.x + xfqc * normal.y;
520
+ return true;
521
+ }
522
+ return false;
523
+ }
524
+
525
+ public final void computeCentroidToOut(final Vec2[] vs, final int count, final Vec2 out) {
526
+ assert (count >= 3);
527
+
528
+ out.set(0.0f, 0.0f);
529
+ float area = 0.0f;
530
+
531
+ // pRef is the reference point for forming triangles.
532
+ // It's location doesn't change the result (except for rounding error).
533
+ final Vec2 pRef = pool1;
534
+ pRef.setZero();
535
+
536
+ final Vec2 e1 = pool2;
537
+ final Vec2 e2 = pool3;
538
+
539
+ final float inv3 = 1.0f / 3.0f;
540
+
541
+ for (int i = 0; i < count; ++i) {
542
+ // Triangle vertices.
543
+ final Vec2 p1 = pRef;
544
+ final Vec2 p2 = vs[i];
545
+ final Vec2 p3 = i + 1 < count ? vs[i + 1] : vs[0];
546
+
547
+ e1.set(p2).subLocal(p1);
548
+ e2.set(p3).subLocal(p1);
549
+
550
+ final float D = Vec2.cross(e1, e2);
551
+
552
+ final float triangleArea = 0.5f * D;
553
+ area += triangleArea;
554
+
555
+ // Area weighted centroid
556
+ e1.set(p1).addLocal(p2).addLocal(p3).mulLocal(triangleArea * inv3);
557
+ out.addLocal(e1);
558
+ }
559
+
560
+ // Centroid
561
+ assert (area > Settings.EPSILON);
562
+ out.mulLocal(1.0f / area);
563
+ }
564
+
565
+ @Override
566
+ public void computeMass(final MassData massData, float density) {
567
+ // Polygon mass, centroid, and inertia.
568
+ // Let rho be the polygon density in mass per unit area.
569
+ // Then:
570
+ // mass = rho * int(dA)
571
+ // centroid.x = (1/mass) * rho * int(x * dA)
572
+ // centroid.y = (1/mass) * rho * int(y * dA)
573
+ // I = rho * int((x*x + y*y) * dA)
574
+ //
575
+ // We can compute these integrals by summing all the integrals
576
+ // for each triangle of the polygon. To evaluate the integral
577
+ // for a single triangle, we make a change of variables to
578
+ // the (u,v) coordinates of the triangle:
579
+ // x = x0 + e1x * u + e2x * v
580
+ // y = y0 + e1y * u + e2y * v
581
+ // where 0 <= u && 0 <= v && u + v <= 1.
582
+ //
583
+ // We integrate u from [0,1-v] and then v from [0,1].
584
+ // We also need to use the Jacobian of the transformation:
585
+ // D = cross(e1, e2)
586
+ //
587
+ // Simplification: triangle centroid = (1/3) * (p1 + p2 + p3)
588
+ //
589
+ // The rest of the derivation is handled by computer algebra.
590
+
591
+ assert (m_count >= 3);
592
+
593
+ final Vec2 center = pool1;
594
+ center.setZero();
595
+ float area = 0.0f;
596
+ float I = 0.0f;
597
+
598
+ // pRef is the reference point for forming triangles.
599
+ // It's location doesn't change the result (except for rounding error).
600
+ final Vec2 s = pool2;
601
+ s.setZero();
602
+ // This code would put the reference point inside the polygon.
603
+ for (int i = 0; i < m_count; ++i) {
604
+ s.addLocal(m_vertices[i]);
605
+ }
606
+ s.mulLocal(1.0f / m_count);
607
+
608
+ final float k_inv3 = 1.0f / 3.0f;
609
+
610
+ final Vec2 e1 = pool3;
611
+ final Vec2 e2 = pool4;
612
+
613
+ for (int i = 0; i < m_count; ++i) {
614
+ // Triangle vertices.
615
+ e1.set(m_vertices[i]).subLocal(s);
616
+ e2.set(s).negateLocal().addLocal(i + 1 < m_count ? m_vertices[i + 1] : m_vertices[0]);
617
+
618
+ final float D = Vec2.cross(e1, e2);
619
+
620
+ final float triangleArea = 0.5f * D;
621
+ area += triangleArea;
622
+
623
+ // Area weighted centroid
624
+ center.x += triangleArea * k_inv3 * (e1.x + e2.x);
625
+ center.y += triangleArea * k_inv3 * (e1.y + e2.y);
626
+
627
+ final float ex1 = e1.x, ey1 = e1.y;
628
+ final float ex2 = e2.x, ey2 = e2.y;
629
+
630
+ float intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;
631
+ float inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;
632
+
633
+ I += (0.25f * k_inv3 * D) * (intx2 + inty2);
634
+ }
635
+
636
+ // Total mass
637
+ massData.mass = density * area;
638
+
639
+ // Center of mass
640
+ assert (area > Settings.EPSILON);
641
+ center.mulLocal(1.0f / area);
642
+ massData.center.set(center).addLocal(s);
643
+
644
+ // Inertia tensor relative to the local origin (point s)
645
+ massData.I = I * density;
646
+
647
+ // Shift to center of mass then to original body origin.
648
+ massData.I += massData.mass * (Vec2.dot(massData.center, massData.center));
649
+ }
650
+
651
+ /**
652
+ * Validate convexity. This is a very time consuming operation.
653
+ *
654
+ * @return
655
+ */
656
+ public boolean validate() {
657
+ for (int i = 0; i < m_count; ++i) {
658
+ int i1 = i;
659
+ int i2 = i < m_count - 1 ? i1 + 1 : 0;
660
+ Vec2 p = m_vertices[i1];
661
+ Vec2 e = pool1.set(m_vertices[i2]).subLocal(p);
662
+
663
+ for (int j = 0; j < m_count; ++j) {
664
+ if (j == i1 || j == i2) {
665
+ continue;
666
+ }
667
+
668
+ Vec2 v = pool2.set(m_vertices[j]).subLocal(p);
669
+ float c = Vec2.cross(e, v);
670
+ if (c < 0.0f) {
671
+ return false;
672
+ }
673
+ }
674
+ }
675
+
676
+ return true;
677
+ }
678
+
679
+ /**
680
+ * Get the vertices in local coordinates.
681
+ *
682
+ * @return
683
+ */
684
+ public Vec2[] getVertices() {
685
+ return m_vertices;
686
+ }
687
+
688
+ /**
689
+ * Get the edge normal vectors. There is one for each vertex.
690
+ *
691
+ * @return
692
+ */
693
+ public Vec2[] getNormals() {
694
+ return m_normals;
695
+ }
696
+
697
+ /**
698
+ * Get the centroid and apply the supplied transform.
699
+ *
700
+ * @param xf
701
+ * @return
702
+ */
703
+ public Vec2 centroid(final Transform xf) {
704
+ return Transform.mul(xf, m_centroid);
705
+ }
706
+
707
+ /**
708
+ * Get the centroid and apply the supplied transform.
709
+ *
710
+ * @param xf
711
+ * @param out
712
+ * @return
713
+ */
714
+ public Vec2 centroidToOut(final Transform xf, final Vec2 out) {
715
+ Transform.mulToOutUnsafe(xf, m_centroid, out);
716
+ return out;
717
+ }
718
+ }