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,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
+ }