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.
- checksums.yaml +4 -4
- data/.mvn/extensions.xml +8 -0
- data/.mvn/wrapper/maven-wrapper.properties +1 -0
- data/.travis.yml +23 -0
- data/CHANGELOG.md +8 -0
- data/README.md +7 -7
- data/Rakefile +1 -2
- data/lib/box2d.jar +0 -0
- data/lib/pbox2d/version.rb +1 -1
- data/lib/pbox2d.rb +1 -0
- data/pbox2d.gemspec +6 -11
- data/pom.rb +59 -0
- data/pom.xml +82 -73
- data/src/org/jbox2d/JBox2D.gwt.xml +12 -0
- data/src/org/jbox2d/callbacks/ContactAdaptor.java +27 -0
- data/src/org/jbox2d/callbacks/ContactFilter.java +59 -0
- data/src/org/jbox2d/callbacks/ContactImpulse.java +42 -0
- data/src/org/jbox2d/callbacks/ContactListener.java +87 -0
- data/src/org/jbox2d/callbacks/DebugDraw.java +297 -0
- data/src/org/jbox2d/callbacks/DestructionListener.java +53 -0
- data/src/org/jbox2d/callbacks/PairCallback.java +29 -0
- data/src/org/jbox2d/callbacks/ParticleDestructionListener.java +20 -0
- data/src/org/jbox2d/callbacks/ParticleQueryCallback.java +19 -0
- data/src/org/jbox2d/callbacks/ParticleRaycastCallback.java +19 -0
- data/src/org/jbox2d/callbacks/QueryCallback.java +45 -0
- data/src/org/jbox2d/callbacks/RayCastCallback.java +55 -0
- data/src/org/jbox2d/callbacks/TreeCallback.java +42 -0
- data/src/org/jbox2d/callbacks/TreeRayCastCallback.java +44 -0
- data/src/org/jbox2d/collision/AABB.java +338 -0
- data/src/org/jbox2d/collision/Collision.java +1444 -0
- data/src/org/jbox2d/collision/ContactID.java +106 -0
- data/src/org/jbox2d/collision/Distance.java +773 -0
- data/src/org/jbox2d/collision/DistanceInput.java +41 -0
- data/src/org/jbox2d/collision/DistanceOutput.java +43 -0
- data/src/org/jbox2d/collision/Manifold.java +116 -0
- data/src/org/jbox2d/collision/ManifoldPoint.java +104 -0
- data/src/org/jbox2d/collision/RayCastInput.java +47 -0
- data/src/org/jbox2d/collision/RayCastOutput.java +46 -0
- data/src/org/jbox2d/collision/TimeOfImpact.java +526 -0
- data/src/org/jbox2d/collision/WorldManifold.java +200 -0
- data/src/org/jbox2d/collision/broadphase/BroadPhase.java +92 -0
- data/src/org/jbox2d/collision/broadphase/BroadPhaseStrategy.java +88 -0
- data/src/org/jbox2d/collision/broadphase/DefaultBroadPhaseBuffer.java +268 -0
- data/src/org/jbox2d/collision/broadphase/DynamicTree.java +883 -0
- data/src/org/jbox2d/collision/broadphase/DynamicTreeFlatNodes.java +873 -0
- data/src/org/jbox2d/collision/broadphase/DynamicTreeNode.java +54 -0
- data/src/org/jbox2d/collision/broadphase/Pair.java +46 -0
- data/src/org/jbox2d/collision/shapes/ChainShape.java +264 -0
- data/src/org/jbox2d/collision/shapes/CircleShape.java +207 -0
- data/src/org/jbox2d/collision/shapes/EdgeShape.java +254 -0
- data/src/org/jbox2d/collision/shapes/MassData.java +105 -0
- data/src/org/jbox2d/collision/shapes/PolygonShape.java +718 -0
- data/src/org/jbox2d/collision/shapes/Shape.java +136 -0
- data/src/org/jbox2d/collision/shapes/ShapeType.java +32 -0
- data/src/org/jbox2d/common/BufferUtils.java +209 -0
- data/src/org/jbox2d/common/Color3f.java +88 -0
- data/src/org/jbox2d/common/IViewportTransform.java +133 -0
- data/src/org/jbox2d/common/Mat22.java +609 -0
- data/src/org/jbox2d/common/Mat33.java +290 -0
- data/src/org/jbox2d/common/MathUtils.java +335 -0
- data/src/org/jbox2d/common/OBBViewportTransform.java +174 -0
- data/src/org/jbox2d/common/PlatformMathUtils.java +46 -0
- data/src/org/jbox2d/common/RaycastResult.java +37 -0
- data/src/org/jbox2d/common/Rot.java +150 -0
- data/src/org/jbox2d/common/Settings.java +246 -0
- data/src/org/jbox2d/common/Sweep.java +116 -0
- data/src/org/jbox2d/common/Timer.java +46 -0
- data/src/org/jbox2d/common/Transform.java +203 -0
- data/src/org/jbox2d/common/Vec2.java +388 -0
- data/src/org/jbox2d/common/Vec3.java +170 -0
- data/src/org/jbox2d/dynamics/Body.java +1246 -0
- data/src/org/jbox2d/dynamics/BodyDef.java +382 -0
- data/src/org/jbox2d/dynamics/BodyType.java +41 -0
- data/src/org/jbox2d/dynamics/ContactManager.java +293 -0
- data/src/org/jbox2d/dynamics/Filter.java +62 -0
- data/src/org/jbox2d/dynamics/Fixture.java +454 -0
- data/src/org/jbox2d/dynamics/FixtureDef.java +214 -0
- data/src/org/jbox2d/dynamics/FixtureProxy.java +38 -0
- data/src/org/jbox2d/dynamics/Island.java +602 -0
- data/src/org/jbox2d/dynamics/Profile.java +97 -0
- data/src/org/jbox2d/dynamics/SolverData.java +33 -0
- data/src/org/jbox2d/dynamics/TimeStep.java +46 -0
- data/src/org/jbox2d/dynamics/World.java +2075 -0
- data/src/org/jbox2d/dynamics/contacts/ChainAndCircleContact.java +57 -0
- data/src/org/jbox2d/dynamics/contacts/ChainAndPolygonContact.java +57 -0
- data/src/org/jbox2d/dynamics/contacts/CircleContact.java +50 -0
- data/src/org/jbox2d/dynamics/contacts/Contact.java +365 -0
- data/src/org/jbox2d/dynamics/contacts/ContactCreator.java +35 -0
- data/src/org/jbox2d/dynamics/contacts/ContactEdge.java +56 -0
- data/src/org/jbox2d/dynamics/contacts/ContactPositionConstraint.java +49 -0
- data/src/org/jbox2d/dynamics/contacts/ContactRegister.java +31 -0
- data/src/org/jbox2d/dynamics/contacts/ContactSolver.java +1104 -0
- data/src/org/jbox2d/dynamics/contacts/ContactVelocityConstraint.java +60 -0
- data/src/org/jbox2d/dynamics/contacts/EdgeAndCircleContact.java +52 -0
- data/src/org/jbox2d/dynamics/contacts/EdgeAndPolygonContact.java +52 -0
- data/src/org/jbox2d/dynamics/contacts/PolygonAndCircleContact.java +51 -0
- data/src/org/jbox2d/dynamics/contacts/PolygonContact.java +50 -0
- data/src/org/jbox2d/dynamics/contacts/Position.java +31 -0
- data/src/org/jbox2d/dynamics/contacts/Velocity.java +31 -0
- data/src/org/jbox2d/dynamics/joints/ConstantVolumeJoint.java +258 -0
- data/src/org/jbox2d/dynamics/joints/ConstantVolumeJointDef.java +75 -0
- data/src/org/jbox2d/dynamics/joints/DistanceJoint.java +356 -0
- data/src/org/jbox2d/dynamics/joints/DistanceJointDef.java +106 -0
- data/src/org/jbox2d/dynamics/joints/FrictionJoint.java +294 -0
- data/src/org/jbox2d/dynamics/joints/FrictionJointDef.java +78 -0
- data/src/org/jbox2d/dynamics/joints/GearJoint.java +520 -0
- data/src/org/jbox2d/dynamics/joints/GearJointDef.java +58 -0
- data/src/org/jbox2d/dynamics/joints/Jacobian.java +32 -0
- data/src/org/jbox2d/dynamics/joints/Joint.java +235 -0
- data/src/org/jbox2d/dynamics/joints/JointDef.java +65 -0
- data/src/org/jbox2d/dynamics/joints/JointEdge.java +57 -0
- data/src/org/jbox2d/dynamics/joints/JointType.java +28 -0
- data/src/org/jbox2d/dynamics/joints/LimitState.java +28 -0
- data/src/org/jbox2d/dynamics/joints/MotorJoint.java +339 -0
- data/src/org/jbox2d/dynamics/joints/MotorJointDef.java +55 -0
- data/src/org/jbox2d/dynamics/joints/MouseJoint.java +262 -0
- data/src/org/jbox2d/dynamics/joints/MouseJointDef.java +62 -0
- data/src/org/jbox2d/dynamics/joints/PrismaticJoint.java +808 -0
- data/src/org/jbox2d/dynamics/joints/PrismaticJointDef.java +120 -0
- data/src/org/jbox2d/dynamics/joints/PulleyJoint.java +393 -0
- data/src/org/jbox2d/dynamics/joints/PulleyJointDef.java +105 -0
- data/src/org/jbox2d/dynamics/joints/RevoluteJoint.java +554 -0
- data/src/org/jbox2d/dynamics/joints/RevoluteJointDef.java +137 -0
- data/src/org/jbox2d/dynamics/joints/RopeJoint.java +276 -0
- data/src/org/jbox2d/dynamics/joints/RopeJointDef.java +34 -0
- data/src/org/jbox2d/dynamics/joints/WeldJoint.java +424 -0
- data/src/org/jbox2d/dynamics/joints/WeldJointDef.java +85 -0
- data/src/org/jbox2d/dynamics/joints/WheelJoint.java +498 -0
- data/src/org/jbox2d/dynamics/joints/WheelJointDef.java +98 -0
- data/src/org/jbox2d/particle/ParticleBodyContact.java +17 -0
- data/src/org/jbox2d/particle/ParticleColor.java +52 -0
- data/src/org/jbox2d/particle/ParticleContact.java +14 -0
- data/src/org/jbox2d/particle/ParticleDef.java +24 -0
- data/src/org/jbox2d/particle/ParticleGroup.java +154 -0
- data/src/org/jbox2d/particle/ParticleGroupDef.java +62 -0
- data/src/org/jbox2d/particle/ParticleGroupType.java +8 -0
- data/src/org/jbox2d/particle/ParticleSystem.java +2172 -0
- data/src/org/jbox2d/particle/ParticleType.java +28 -0
- data/src/org/jbox2d/particle/StackQueue.java +44 -0
- data/src/org/jbox2d/particle/VoronoiDiagram.java +209 -0
- data/src/org/jbox2d/pooling/IDynamicStack.java +47 -0
- data/src/org/jbox2d/pooling/IOrderedStack.java +57 -0
- data/src/org/jbox2d/pooling/IWorldPool.java +101 -0
- data/src/org/jbox2d/pooling/arrays/FloatArray.java +50 -0
- data/src/org/jbox2d/pooling/arrays/GeneratorArray.java +33 -0
- data/src/org/jbox2d/pooling/arrays/IntArray.java +53 -0
- data/src/org/jbox2d/pooling/arrays/Vec2Array.java +57 -0
- data/src/org/jbox2d/pooling/normal/CircleStack.java +77 -0
- data/src/org/jbox2d/pooling/normal/DefaultWorldPool.java +331 -0
- data/src/org/jbox2d/pooling/normal/MutableStack.java +72 -0
- data/src/org/jbox2d/pooling/normal/OrderedStack.java +73 -0
- data/src/org/jbox2d/pooling/stacks/DynamicIntStack.java +60 -0
- metadata +161 -14
- data/lib/jbox2d-library-2.3.1-SNAPSHOT.jar +0 -0
@@ -0,0 +1,200 @@
|
|
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.common.MathUtils;
|
27
|
+
import org.jbox2d.common.Rot;
|
28
|
+
import org.jbox2d.common.Settings;
|
29
|
+
import org.jbox2d.common.Transform;
|
30
|
+
import org.jbox2d.common.Vec2;
|
31
|
+
|
32
|
+
/**
|
33
|
+
* This is used to compute the current state of a contact manifold.
|
34
|
+
*
|
35
|
+
* @author daniel
|
36
|
+
*/
|
37
|
+
public class WorldManifold {
|
38
|
+
/**
|
39
|
+
* World vector pointing from A to B
|
40
|
+
*/
|
41
|
+
public final Vec2 normal;
|
42
|
+
|
43
|
+
/**
|
44
|
+
* World contact point (point of intersection)
|
45
|
+
*/
|
46
|
+
public final Vec2[] points;
|
47
|
+
|
48
|
+
/**
|
49
|
+
* A negative value indicates overlap, in meters.
|
50
|
+
*/
|
51
|
+
public final float[] separations;
|
52
|
+
|
53
|
+
public WorldManifold() {
|
54
|
+
normal = new Vec2();
|
55
|
+
points = new Vec2[Settings.maxManifoldPoints];
|
56
|
+
separations = new float[Settings.maxManifoldPoints];
|
57
|
+
for (int i = 0; i < Settings.maxManifoldPoints; i++) {
|
58
|
+
points[i] = new Vec2();
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
private final Vec2 pool3 = new Vec2();
|
63
|
+
private final Vec2 pool4 = new Vec2();
|
64
|
+
|
65
|
+
public final void initialize(final Manifold manifold, final Transform xfA, float radiusA,
|
66
|
+
final Transform xfB, float radiusB) {
|
67
|
+
if (manifold.pointCount == 0) {
|
68
|
+
return;
|
69
|
+
}
|
70
|
+
|
71
|
+
switch (manifold.type) {
|
72
|
+
case CIRCLES: {
|
73
|
+
final Vec2 pointA = pool3;
|
74
|
+
final Vec2 pointB = pool4;
|
75
|
+
|
76
|
+
normal.x = 1;
|
77
|
+
normal.y = 0;
|
78
|
+
Vec2 v = manifold.localPoint;
|
79
|
+
// Transform.mulToOutUnsafe(xfA, manifold.localPoint, pointA);
|
80
|
+
// Transform.mulToOutUnsafe(xfB, manifold.points[0].localPoint, pointB);
|
81
|
+
pointA.x = (xfA.q.c * v.x - xfA.q.s * v.y) + xfA.p.x;
|
82
|
+
pointA.y = (xfA.q.s * v.x + xfA.q.c * v.y) + xfA.p.y;
|
83
|
+
Vec2 mp0p = manifold.points[0].localPoint;
|
84
|
+
pointB.x = (xfB.q.c * mp0p.x - xfB.q.s * mp0p.y) + xfB.p.x;
|
85
|
+
pointB.y = (xfB.q.s * mp0p.x + xfB.q.c * mp0p.y) + xfB.p.y;
|
86
|
+
|
87
|
+
if (MathUtils.distanceSquared(pointA, pointB) > Settings.EPSILON * Settings.EPSILON) {
|
88
|
+
normal.x = pointB.x - pointA.x;
|
89
|
+
normal.y = pointB.y - pointA.y;
|
90
|
+
normal.normalize();
|
91
|
+
}
|
92
|
+
|
93
|
+
final float cAx = normal.x * radiusA + pointA.x;
|
94
|
+
final float cAy = normal.y * radiusA + pointA.y;
|
95
|
+
|
96
|
+
final float cBx = -normal.x * radiusB + pointB.x;
|
97
|
+
final float cBy = -normal.y * radiusB + pointB.y;
|
98
|
+
|
99
|
+
points[0].x = (cAx + cBx) * .5f;
|
100
|
+
points[0].y = (cAy + cBy) * .5f;
|
101
|
+
separations[0] = (cBx - cAx) * normal.x + (cBy - cAy) * normal.y;
|
102
|
+
}
|
103
|
+
break;
|
104
|
+
case FACE_A: {
|
105
|
+
final Vec2 planePoint = pool3;
|
106
|
+
|
107
|
+
Rot.mulToOutUnsafe(xfA.q, manifold.localNormal, normal);
|
108
|
+
Transform.mulToOut(xfA, manifold.localPoint, planePoint);
|
109
|
+
|
110
|
+
final Vec2 clipPoint = pool4;
|
111
|
+
|
112
|
+
for (int i = 0; i < manifold.pointCount; i++) {
|
113
|
+
// b2Vec2 clipPoint = b2Mul(xfB, manifold->points[i].localPoint);
|
114
|
+
// b2Vec2 cA = clipPoint + (radiusA - b2Dot(clipPoint - planePoint,
|
115
|
+
// normal)) * normal;
|
116
|
+
// b2Vec2 cB = clipPoint - radiusB * normal;
|
117
|
+
// points[i] = 0.5f * (cA + cB);
|
118
|
+
Transform.mulToOut(xfB, manifold.points[i].localPoint, clipPoint);
|
119
|
+
// use cA as temporary for now
|
120
|
+
// cA.set(clipPoint).subLocal(planePoint);
|
121
|
+
// float scalar = radiusA - Vec2.dot(cA, normal);
|
122
|
+
// cA.set(normal).mulLocal(scalar).addLocal(clipPoint);
|
123
|
+
// cB.set(normal).mulLocal(radiusB).subLocal(clipPoint).negateLocal();
|
124
|
+
// points[i].set(cA).addLocal(cB).mulLocal(0.5f);
|
125
|
+
|
126
|
+
final float scalar =
|
127
|
+
radiusA
|
128
|
+
- ((clipPoint.x - planePoint.x) * normal.x + (clipPoint.y - planePoint.y)
|
129
|
+
* normal.y);
|
130
|
+
|
131
|
+
final float cAx = normal.x * scalar + clipPoint.x;
|
132
|
+
final float cAy = normal.y * scalar + clipPoint.y;
|
133
|
+
|
134
|
+
final float cBx = -normal.x * radiusB + clipPoint.x;
|
135
|
+
final float cBy = -normal.y * radiusB + clipPoint.y;
|
136
|
+
|
137
|
+
points[i].x = (cAx + cBx) * .5f;
|
138
|
+
points[i].y = (cAy + cBy) * .5f;
|
139
|
+
separations[i] = (cBx - cAx) * normal.x + (cBy - cAy) * normal.y;
|
140
|
+
}
|
141
|
+
}
|
142
|
+
break;
|
143
|
+
case FACE_B:
|
144
|
+
final Vec2 planePoint = pool3;
|
145
|
+
Rot.mulToOutUnsafe(xfB.q, manifold.localNormal, normal);
|
146
|
+
Transform.mulToOut(xfB, manifold.localPoint, planePoint);
|
147
|
+
|
148
|
+
// final Mat22 R = xfB.q;
|
149
|
+
// normal.x = R.ex.x * manifold.localNormal.x + R.ey.x * manifold.localNormal.y;
|
150
|
+
// normal.y = R.ex.y * manifold.localNormal.x + R.ey.y * manifold.localNormal.y;
|
151
|
+
// final Vec2 v = manifold.localPoint;
|
152
|
+
// planePoint.x = xfB.p.x + xfB.q.ex.x * v.x + xfB.q.ey.x * v.y;
|
153
|
+
// planePoint.y = xfB.p.y + xfB.q.ex.y * v.x + xfB.q.ey.y * v.y;
|
154
|
+
|
155
|
+
final Vec2 clipPoint = pool4;
|
156
|
+
|
157
|
+
for (int i = 0; i < manifold.pointCount; i++) {
|
158
|
+
// b2Vec2 clipPoint = b2Mul(xfA, manifold->points[i].localPoint);
|
159
|
+
// b2Vec2 cB = clipPoint + (radiusB - b2Dot(clipPoint - planePoint,
|
160
|
+
// normal)) * normal;
|
161
|
+
// b2Vec2 cA = clipPoint - radiusA * normal;
|
162
|
+
// points[i] = 0.5f * (cA + cB);
|
163
|
+
|
164
|
+
Transform.mulToOut(xfA, manifold.points[i].localPoint, clipPoint);
|
165
|
+
// cB.set(clipPoint).subLocal(planePoint);
|
166
|
+
// float scalar = radiusB - Vec2.dot(cB, normal);
|
167
|
+
// cB.set(normal).mulLocal(scalar).addLocal(clipPoint);
|
168
|
+
// cA.set(normal).mulLocal(radiusA).subLocal(clipPoint).negateLocal();
|
169
|
+
// points[i].set(cA).addLocal(cB).mulLocal(0.5f);
|
170
|
+
|
171
|
+
// points[i] = 0.5f * (cA + cB);
|
172
|
+
|
173
|
+
//
|
174
|
+
// clipPoint.x = xfA.p.x + xfA.q.ex.x * manifold.points[i].localPoint.x + xfA.q.ey.x *
|
175
|
+
// manifold.points[i].localPoint.y;
|
176
|
+
// clipPoint.y = xfA.p.y + xfA.q.ex.y * manifold.points[i].localPoint.x + xfA.q.ey.y *
|
177
|
+
// manifold.points[i].localPoint.y;
|
178
|
+
|
179
|
+
final float scalar =
|
180
|
+
radiusB
|
181
|
+
- ((clipPoint.x - planePoint.x) * normal.x + (clipPoint.y - planePoint.y)
|
182
|
+
* normal.y);
|
183
|
+
|
184
|
+
final float cBx = normal.x * scalar + clipPoint.x;
|
185
|
+
final float cBy = normal.y * scalar + clipPoint.y;
|
186
|
+
|
187
|
+
final float cAx = -normal.x * radiusA + clipPoint.x;
|
188
|
+
final float cAy = -normal.y * radiusA + clipPoint.y;
|
189
|
+
|
190
|
+
points[i].x = (cAx + cBx) * .5f;
|
191
|
+
points[i].y = (cAy + cBy) * .5f;
|
192
|
+
separations[i] = (cAx - cBx) * normal.x + (cAy - cBy) * normal.y;
|
193
|
+
}
|
194
|
+
// Ensure normal points from A to B.
|
195
|
+
normal.x = -normal.x;
|
196
|
+
normal.y = -normal.y;
|
197
|
+
break;
|
198
|
+
}
|
199
|
+
}
|
200
|
+
}
|
@@ -0,0 +1,92 @@
|
|
1
|
+
package org.jbox2d.collision.broadphase;
|
2
|
+
|
3
|
+
import org.jbox2d.callbacks.DebugDraw;
|
4
|
+
import org.jbox2d.callbacks.PairCallback;
|
5
|
+
import org.jbox2d.callbacks.TreeCallback;
|
6
|
+
import org.jbox2d.callbacks.TreeRayCastCallback;
|
7
|
+
import org.jbox2d.collision.AABB;
|
8
|
+
import org.jbox2d.collision.RayCastInput;
|
9
|
+
import org.jbox2d.common.Vec2;
|
10
|
+
|
11
|
+
|
12
|
+
public interface BroadPhase {
|
13
|
+
|
14
|
+
public static final int NULL_PROXY = -1;
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Create a proxy with an initial AABB. Pairs are not reported until updatePairs is called.
|
18
|
+
*
|
19
|
+
* @param aabb
|
20
|
+
* @param userData
|
21
|
+
* @return
|
22
|
+
*/
|
23
|
+
int createProxy(AABB aabb, Object userData);
|
24
|
+
|
25
|
+
/**
|
26
|
+
* Destroy a proxy. It is up to the client to remove any pairs.
|
27
|
+
*
|
28
|
+
* @param proxyId
|
29
|
+
*/
|
30
|
+
void destroyProxy(int proxyId);
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Call MoveProxy as many times as you like, then when you are done call UpdatePairs to finalized
|
34
|
+
* the proxy pairs (for your time step).
|
35
|
+
*/
|
36
|
+
void moveProxy(int proxyId, AABB aabb, Vec2 displacement);
|
37
|
+
|
38
|
+
void touchProxy(int proxyId);
|
39
|
+
|
40
|
+
Object getUserData(int proxyId);
|
41
|
+
|
42
|
+
AABB getFatAABB(int proxyId);
|
43
|
+
|
44
|
+
boolean testOverlap(int proxyIdA, int proxyIdB);
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Get the number of proxies.
|
48
|
+
*
|
49
|
+
* @return
|
50
|
+
*/
|
51
|
+
int getProxyCount();
|
52
|
+
|
53
|
+
void drawTree(DebugDraw argDraw);
|
54
|
+
|
55
|
+
/**
|
56
|
+
* Update the pairs. This results in pair callbacks. This can only add pairs.
|
57
|
+
*
|
58
|
+
* @param callback
|
59
|
+
*/
|
60
|
+
void updatePairs(PairCallback callback);
|
61
|
+
|
62
|
+
/**
|
63
|
+
* Query an AABB for overlapping proxies. The callback class is called for each proxy that
|
64
|
+
* overlaps the supplied AABB.
|
65
|
+
*
|
66
|
+
* @param callback
|
67
|
+
* @param aabb
|
68
|
+
*/
|
69
|
+
void query(TreeCallback callback, AABB aabb);
|
70
|
+
|
71
|
+
/**
|
72
|
+
* Ray-cast against the proxies in the tree. This relies on the callback to perform a exact
|
73
|
+
* ray-cast in the case were the proxy contains a shape. The callback also performs the any
|
74
|
+
* collision filtering. This has performance roughly equal to k * log(n), where k is the number of
|
75
|
+
* collisions and n is the number of proxies in the tree.
|
76
|
+
*
|
77
|
+
* @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
|
78
|
+
* @param callback a callback class that is called for each proxy that is hit by the ray.
|
79
|
+
*/
|
80
|
+
void raycast(TreeRayCastCallback callback, RayCastInput input);
|
81
|
+
|
82
|
+
/**
|
83
|
+
* Get the height of the embedded tree.
|
84
|
+
*
|
85
|
+
* @return
|
86
|
+
*/
|
87
|
+
int getTreeHeight();
|
88
|
+
|
89
|
+
int getTreeBalance();
|
90
|
+
|
91
|
+
float getTreeQuality();
|
92
|
+
}
|
@@ -0,0 +1,88 @@
|
|
1
|
+
package org.jbox2d.collision.broadphase;
|
2
|
+
|
3
|
+
import org.jbox2d.callbacks.DebugDraw;
|
4
|
+
import org.jbox2d.callbacks.TreeCallback;
|
5
|
+
import org.jbox2d.callbacks.TreeRayCastCallback;
|
6
|
+
import org.jbox2d.collision.AABB;
|
7
|
+
import org.jbox2d.collision.RayCastInput;
|
8
|
+
import org.jbox2d.common.Vec2;
|
9
|
+
|
10
|
+
public interface BroadPhaseStrategy {
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Create a proxy. Provide a tight fitting AABB and a userData pointer.
|
14
|
+
*
|
15
|
+
* @param aabb
|
16
|
+
* @param userData
|
17
|
+
* @return
|
18
|
+
*/
|
19
|
+
int createProxy(AABB aabb, Object userData);
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Destroy a proxy
|
23
|
+
*
|
24
|
+
* @param proxyId
|
25
|
+
*/
|
26
|
+
void destroyProxy(int proxyId);
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Move a proxy with a swepted AABB. If the proxy has moved outside of its fattened AABB, then the
|
30
|
+
* proxy is removed from the tree and re-inserted. Otherwise the function returns immediately.
|
31
|
+
*
|
32
|
+
* @return true if the proxy was re-inserted.
|
33
|
+
*/
|
34
|
+
boolean moveProxy(int proxyId, AABB aabb, Vec2 displacement);
|
35
|
+
|
36
|
+
Object getUserData(int proxyId);
|
37
|
+
|
38
|
+
AABB getFatAABB(int proxyId);
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Query an AABB for overlapping proxies. The callback class is called for each proxy that
|
42
|
+
* overlaps the supplied AABB.
|
43
|
+
*
|
44
|
+
* @param callback
|
45
|
+
* @param araabbgAABB
|
46
|
+
*/
|
47
|
+
void query(TreeCallback callback, AABB aabb);
|
48
|
+
|
49
|
+
/**
|
50
|
+
* Ray-cast against the proxies in the tree. This relies on the callback to perform a exact
|
51
|
+
* ray-cast in the case were the proxy contains a shape. The callback also performs the any
|
52
|
+
* collision filtering. This has performance roughly equal to k * log(n), where k is the number of
|
53
|
+
* collisions and n is the number of proxies in the tree.
|
54
|
+
*
|
55
|
+
* @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
|
56
|
+
* @param callback a callback class that is called for each proxy that is hit by the ray.
|
57
|
+
*/
|
58
|
+
void raycast(TreeRayCastCallback callback, RayCastInput input);
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Compute the height of the tree.
|
62
|
+
*/
|
63
|
+
int computeHeight();
|
64
|
+
|
65
|
+
/**
|
66
|
+
* Compute the height of the binary tree in O(N) time. Should not be called often.
|
67
|
+
*
|
68
|
+
* @return
|
69
|
+
*/
|
70
|
+
int getHeight();
|
71
|
+
|
72
|
+
/**
|
73
|
+
* Get the maximum balance of an node in the tree. The balance is the difference in height of the
|
74
|
+
* two children of a node.
|
75
|
+
*
|
76
|
+
* @return
|
77
|
+
*/
|
78
|
+
int getMaxBalance();
|
79
|
+
|
80
|
+
/**
|
81
|
+
* Get the ratio of the sum of the node areas to the root area.
|
82
|
+
*
|
83
|
+
* @return
|
84
|
+
*/
|
85
|
+
float getAreaRatio();
|
86
|
+
|
87
|
+
void drawTree(DebugDraw draw);
|
88
|
+
}
|
@@ -0,0 +1,268 @@
|
|
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.broadphase;
|
25
|
+
|
26
|
+
import java.util.Arrays;
|
27
|
+
|
28
|
+
import org.jbox2d.callbacks.DebugDraw;
|
29
|
+
import org.jbox2d.callbacks.PairCallback;
|
30
|
+
import org.jbox2d.callbacks.TreeCallback;
|
31
|
+
import org.jbox2d.callbacks.TreeRayCastCallback;
|
32
|
+
import org.jbox2d.collision.AABB;
|
33
|
+
import org.jbox2d.collision.RayCastInput;
|
34
|
+
import org.jbox2d.common.Vec2;
|
35
|
+
|
36
|
+
/**
|
37
|
+
* The broad-phase is used for computing pairs and performing volume queries and ray casts. This
|
38
|
+
* broad-phase does not persist pairs. Instead, this reports potentially new pairs. It is up to the
|
39
|
+
* client to consume the new pairs and to track subsequent overlap.
|
40
|
+
*
|
41
|
+
* @author Daniel Murphy
|
42
|
+
*/
|
43
|
+
public class DefaultBroadPhaseBuffer implements TreeCallback, BroadPhase {
|
44
|
+
|
45
|
+
private final BroadPhaseStrategy m_tree;
|
46
|
+
|
47
|
+
private int m_proxyCount;
|
48
|
+
|
49
|
+
private int[] m_moveBuffer;
|
50
|
+
private int m_moveCapacity;
|
51
|
+
private int m_moveCount;
|
52
|
+
|
53
|
+
private Pair[] m_pairBuffer;
|
54
|
+
private int m_pairCapacity;
|
55
|
+
private int m_pairCount;
|
56
|
+
|
57
|
+
private int m_queryProxyId;
|
58
|
+
|
59
|
+
public DefaultBroadPhaseBuffer(BroadPhaseStrategy strategy) {
|
60
|
+
m_proxyCount = 0;
|
61
|
+
|
62
|
+
m_pairCapacity = 16;
|
63
|
+
m_pairCount = 0;
|
64
|
+
m_pairBuffer = new Pair[m_pairCapacity];
|
65
|
+
for (int i = 0; i < m_pairCapacity; i++) {
|
66
|
+
m_pairBuffer[i] = new Pair();
|
67
|
+
}
|
68
|
+
|
69
|
+
m_moveCapacity = 16;
|
70
|
+
m_moveCount = 0;
|
71
|
+
m_moveBuffer = new int[m_moveCapacity];
|
72
|
+
|
73
|
+
m_tree = strategy;
|
74
|
+
m_queryProxyId = NULL_PROXY;
|
75
|
+
}
|
76
|
+
|
77
|
+
@Override
|
78
|
+
public final int createProxy(final AABB aabb, Object userData) {
|
79
|
+
int proxyId = m_tree.createProxy(aabb, userData);
|
80
|
+
++m_proxyCount;
|
81
|
+
bufferMove(proxyId);
|
82
|
+
return proxyId;
|
83
|
+
}
|
84
|
+
|
85
|
+
@Override
|
86
|
+
public final void destroyProxy(int proxyId) {
|
87
|
+
unbufferMove(proxyId);
|
88
|
+
--m_proxyCount;
|
89
|
+
m_tree.destroyProxy(proxyId);
|
90
|
+
}
|
91
|
+
|
92
|
+
@Override
|
93
|
+
public final void moveProxy(int proxyId, final AABB aabb, final Vec2 displacement) {
|
94
|
+
boolean buffer = m_tree.moveProxy(proxyId, aabb, displacement);
|
95
|
+
if (buffer) {
|
96
|
+
bufferMove(proxyId);
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
@Override
|
101
|
+
public void touchProxy(int proxyId) {
|
102
|
+
bufferMove(proxyId);
|
103
|
+
}
|
104
|
+
|
105
|
+
@Override
|
106
|
+
public Object getUserData(int proxyId) {
|
107
|
+
return m_tree.getUserData(proxyId);
|
108
|
+
}
|
109
|
+
|
110
|
+
@Override
|
111
|
+
public AABB getFatAABB(int proxyId) {
|
112
|
+
return m_tree.getFatAABB(proxyId);
|
113
|
+
}
|
114
|
+
|
115
|
+
@Override
|
116
|
+
public boolean testOverlap(int proxyIdA, int proxyIdB) {
|
117
|
+
// return AABB.testOverlap(proxyA.aabb, proxyB.aabb);
|
118
|
+
// return m_tree.overlap(proxyIdA, proxyIdB);
|
119
|
+
final AABB a = m_tree.getFatAABB(proxyIdA);
|
120
|
+
final AABB b = m_tree.getFatAABB(proxyIdB);
|
121
|
+
if (b.lowerBound.x - a.upperBound.x > 0.0f || b.lowerBound.y - a.upperBound.y > 0.0f) {
|
122
|
+
return false;
|
123
|
+
}
|
124
|
+
|
125
|
+
if (a.lowerBound.x - b.upperBound.x > 0.0f || a.lowerBound.y - b.upperBound.y > 0.0f) {
|
126
|
+
return false;
|
127
|
+
}
|
128
|
+
|
129
|
+
return true;
|
130
|
+
}
|
131
|
+
|
132
|
+
@Override
|
133
|
+
public final int getProxyCount() {
|
134
|
+
return m_proxyCount;
|
135
|
+
}
|
136
|
+
|
137
|
+
@Override
|
138
|
+
public void drawTree(DebugDraw argDraw) {
|
139
|
+
m_tree.drawTree(argDraw);
|
140
|
+
}
|
141
|
+
|
142
|
+
@Override
|
143
|
+
public final void updatePairs(PairCallback callback) {
|
144
|
+
// Reset pair buffer
|
145
|
+
m_pairCount = 0;
|
146
|
+
|
147
|
+
// Perform tree queries for all moving proxies.
|
148
|
+
for (int i = 0; i < m_moveCount; ++i) {
|
149
|
+
m_queryProxyId = m_moveBuffer[i];
|
150
|
+
if (m_queryProxyId == NULL_PROXY) {
|
151
|
+
continue;
|
152
|
+
}
|
153
|
+
|
154
|
+
// We have to query the tree with the fat AABB so that
|
155
|
+
// we don't fail to create a pair that may touch later.
|
156
|
+
final AABB fatAABB = m_tree.getFatAABB(m_queryProxyId);
|
157
|
+
|
158
|
+
// Query tree, create pairs and add them pair buffer.
|
159
|
+
// log.debug("quering aabb: "+m_queryProxy.aabb);
|
160
|
+
m_tree.query(this, fatAABB);
|
161
|
+
}
|
162
|
+
// log.debug("Number of pairs found: "+m_pairCount);
|
163
|
+
|
164
|
+
// Reset move buffer
|
165
|
+
m_moveCount = 0;
|
166
|
+
|
167
|
+
// Sort the pair buffer to expose duplicates.
|
168
|
+
Arrays.sort(m_pairBuffer, 0, m_pairCount);
|
169
|
+
|
170
|
+
// Send the pairs back to the client.
|
171
|
+
int i = 0;
|
172
|
+
while (i < m_pairCount) {
|
173
|
+
Pair primaryPair = m_pairBuffer[i];
|
174
|
+
Object userDataA = m_tree.getUserData(primaryPair.proxyIdA);
|
175
|
+
Object userDataB = m_tree.getUserData(primaryPair.proxyIdB);
|
176
|
+
|
177
|
+
// log.debug("returning pair: "+userDataA+", "+userDataB);
|
178
|
+
callback.addPair(userDataA, userDataB);
|
179
|
+
++i;
|
180
|
+
|
181
|
+
// Skip any duplicate pairs.
|
182
|
+
while (i < m_pairCount) {
|
183
|
+
Pair pair = m_pairBuffer[i];
|
184
|
+
if (pair.proxyIdA != primaryPair.proxyIdA || pair.proxyIdB != primaryPair.proxyIdB) {
|
185
|
+
break;
|
186
|
+
}
|
187
|
+
++i;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
@Override
|
193
|
+
public final void query(final TreeCallback callback, final AABB aabb) {
|
194
|
+
m_tree.query(callback, aabb);
|
195
|
+
}
|
196
|
+
|
197
|
+
@Override
|
198
|
+
public final void raycast(final TreeRayCastCallback callback, final RayCastInput input) {
|
199
|
+
m_tree.raycast(callback, input);
|
200
|
+
}
|
201
|
+
|
202
|
+
@Override
|
203
|
+
public final int getTreeHeight() {
|
204
|
+
return m_tree.getHeight();
|
205
|
+
}
|
206
|
+
|
207
|
+
@Override
|
208
|
+
public int getTreeBalance() {
|
209
|
+
return m_tree.getMaxBalance();
|
210
|
+
}
|
211
|
+
|
212
|
+
@Override
|
213
|
+
public float getTreeQuality() {
|
214
|
+
return m_tree.getAreaRatio();
|
215
|
+
}
|
216
|
+
|
217
|
+
protected final void bufferMove(int proxyId) {
|
218
|
+
if (m_moveCount == m_moveCapacity) {
|
219
|
+
int[] old = m_moveBuffer;
|
220
|
+
m_moveCapacity *= 2;
|
221
|
+
m_moveBuffer = new int[m_moveCapacity];
|
222
|
+
System.arraycopy(old, 0, m_moveBuffer, 0, old.length);
|
223
|
+
}
|
224
|
+
|
225
|
+
m_moveBuffer[m_moveCount] = proxyId;
|
226
|
+
++m_moveCount;
|
227
|
+
}
|
228
|
+
|
229
|
+
protected final void unbufferMove(int proxyId) {
|
230
|
+
for (int i = 0; i < m_moveCount; i++) {
|
231
|
+
if (m_moveBuffer[i] == proxyId) {
|
232
|
+
m_moveBuffer[i] = NULL_PROXY;
|
233
|
+
}
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
/**
|
238
|
+
* This is called from DynamicTree::query when we are gathering pairs.
|
239
|
+
*/
|
240
|
+
public final boolean treeCallback(int proxyId) {
|
241
|
+
// A proxy cannot form a pair with itself.
|
242
|
+
if (proxyId == m_queryProxyId) {
|
243
|
+
return true;
|
244
|
+
}
|
245
|
+
|
246
|
+
// Grow the pair buffer as needed.
|
247
|
+
if (m_pairCount == m_pairCapacity) {
|
248
|
+
Pair[] oldBuffer = m_pairBuffer;
|
249
|
+
m_pairCapacity *= 2;
|
250
|
+
m_pairBuffer = new Pair[m_pairCapacity];
|
251
|
+
System.arraycopy(oldBuffer, 0, m_pairBuffer, 0, oldBuffer.length);
|
252
|
+
for (int i = oldBuffer.length; i < m_pairCapacity; i++) {
|
253
|
+
m_pairBuffer[i] = new Pair();
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
if (proxyId < m_queryProxyId) {
|
258
|
+
m_pairBuffer[m_pairCount].proxyIdA = proxyId;
|
259
|
+
m_pairBuffer[m_pairCount].proxyIdB = m_queryProxyId;
|
260
|
+
} else {
|
261
|
+
m_pairBuffer[m_pairCount].proxyIdA = m_queryProxyId;
|
262
|
+
m_pairBuffer[m_pairCount].proxyIdB = proxyId;
|
263
|
+
}
|
264
|
+
|
265
|
+
++m_pairCount;
|
266
|
+
return true;
|
267
|
+
}
|
268
|
+
}
|