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,808 @@
|
|
1
|
+
/*******************************************************************************
|
2
|
+
* Copyright (c) 2013, Daniel Murphy
|
3
|
+
* All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
6
|
+
* are permitted provided that the following conditions are met:
|
7
|
+
* * Redistributions of source code must retain the above copyright notice,
|
8
|
+
* this list of conditions and the following disclaimer.
|
9
|
+
* * Redistributions in binary form must reproduce the above copyright notice,
|
10
|
+
* this list of conditions and the following disclaimer in the documentation
|
11
|
+
* and/or other materials provided with the distribution.
|
12
|
+
*
|
13
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
14
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
15
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
16
|
+
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
17
|
+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
18
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
19
|
+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
20
|
+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
21
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
22
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
23
|
+
******************************************************************************/
|
24
|
+
package org.jbox2d.dynamics.joints;
|
25
|
+
|
26
|
+
import org.jbox2d.common.Mat22;
|
27
|
+
import org.jbox2d.common.Mat33;
|
28
|
+
import org.jbox2d.common.MathUtils;
|
29
|
+
import org.jbox2d.common.Rot;
|
30
|
+
import org.jbox2d.common.Settings;
|
31
|
+
import org.jbox2d.common.Vec2;
|
32
|
+
import org.jbox2d.common.Vec3;
|
33
|
+
import org.jbox2d.dynamics.Body;
|
34
|
+
import org.jbox2d.dynamics.SolverData;
|
35
|
+
import org.jbox2d.pooling.IWorldPool;
|
36
|
+
|
37
|
+
//Linear constraint (point-to-line)
|
38
|
+
//d = p2 - p1 = x2 + r2 - x1 - r1
|
39
|
+
//C = dot(perp, d)
|
40
|
+
//Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1))
|
41
|
+
// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2)
|
42
|
+
//J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)]
|
43
|
+
//
|
44
|
+
//Angular constraint
|
45
|
+
//C = a2 - a1 + a_initial
|
46
|
+
//Cdot = w2 - w1
|
47
|
+
//J = [0 0 -1 0 0 1]
|
48
|
+
//
|
49
|
+
//K = J * invM * JT
|
50
|
+
//
|
51
|
+
//J = [-a -s1 a s2]
|
52
|
+
// [0 -1 0 1]
|
53
|
+
//a = perp
|
54
|
+
//s1 = cross(d + r1, a) = cross(p2 - x1, a)
|
55
|
+
//s2 = cross(r2, a) = cross(p2 - x2, a)
|
56
|
+
|
57
|
+
|
58
|
+
//Motor/Limit linear constraint
|
59
|
+
//C = dot(ax1, d)
|
60
|
+
//Cdot = = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2)
|
61
|
+
//J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)]
|
62
|
+
|
63
|
+
//Block Solver
|
64
|
+
//We develop a block solver that includes the joint limit. This makes the limit stiff (inelastic) even
|
65
|
+
//when the mass has poor distribution (leading to large torques about the joint anchor points).
|
66
|
+
//
|
67
|
+
//The Jacobian has 3 rows:
|
68
|
+
//J = [-uT -s1 uT s2] // linear
|
69
|
+
// [0 -1 0 1] // angular
|
70
|
+
// [-vT -a1 vT a2] // limit
|
71
|
+
//
|
72
|
+
//u = perp
|
73
|
+
//v = axis
|
74
|
+
//s1 = cross(d + r1, u), s2 = cross(r2, u)
|
75
|
+
//a1 = cross(d + r1, v), a2 = cross(r2, v)
|
76
|
+
|
77
|
+
//M * (v2 - v1) = JT * df
|
78
|
+
//J * v2 = bias
|
79
|
+
//
|
80
|
+
//v2 = v1 + invM * JT * df
|
81
|
+
//J * (v1 + invM * JT * df) = bias
|
82
|
+
//K * df = bias - J * v1 = -Cdot
|
83
|
+
//K = J * invM * JT
|
84
|
+
//Cdot = J * v1 - bias
|
85
|
+
//
|
86
|
+
//Now solve for f2.
|
87
|
+
//df = f2 - f1
|
88
|
+
//K * (f2 - f1) = -Cdot
|
89
|
+
//f2 = invK * (-Cdot) + f1
|
90
|
+
//
|
91
|
+
//Clamp accumulated limit impulse.
|
92
|
+
//lower: f2(3) = max(f2(3), 0)
|
93
|
+
//upper: f2(3) = min(f2(3), 0)
|
94
|
+
//
|
95
|
+
//Solve for correct f2(1:2)
|
96
|
+
//K(1:2, 1:2) * f2(1:2) = -Cdot(1:2) - K(1:2,3) * f2(3) + K(1:2,1:3) * f1
|
97
|
+
// = -Cdot(1:2) - K(1:2,3) * f2(3) + K(1:2,1:2) * f1(1:2) + K(1:2,3) * f1(3)
|
98
|
+
//K(1:2, 1:2) * f2(1:2) = -Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3)) + K(1:2,1:2) * f1(1:2)
|
99
|
+
//f2(1:2) = invK(1:2,1:2) * (-Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3))) + f1(1:2)
|
100
|
+
//
|
101
|
+
//Now compute impulse to be applied:
|
102
|
+
//df = f2 - f1
|
103
|
+
|
104
|
+
/**
|
105
|
+
* A prismatic joint. This joint provides one degree of freedom: translation along an axis fixed in
|
106
|
+
* bodyA. Relative rotation is prevented. You can use a joint limit to restrict the range of motion
|
107
|
+
* and a joint motor to drive the motion or to model joint friction.
|
108
|
+
*
|
109
|
+
* @author Daniel
|
110
|
+
*/
|
111
|
+
public class PrismaticJoint extends Joint {
|
112
|
+
|
113
|
+
// Solver shared
|
114
|
+
protected final Vec2 m_localAnchorA;
|
115
|
+
protected final Vec2 m_localAnchorB;
|
116
|
+
protected final Vec2 m_localXAxisA;
|
117
|
+
protected final Vec2 m_localYAxisA;
|
118
|
+
protected float m_referenceAngle;
|
119
|
+
private final Vec3 m_impulse;
|
120
|
+
private float m_motorImpulse;
|
121
|
+
private float m_lowerTranslation;
|
122
|
+
private float m_upperTranslation;
|
123
|
+
private float m_maxMotorForce;
|
124
|
+
private float m_motorSpeed;
|
125
|
+
private boolean m_enableLimit;
|
126
|
+
private boolean m_enableMotor;
|
127
|
+
private LimitState m_limitState;
|
128
|
+
|
129
|
+
// Solver temp
|
130
|
+
private int m_indexA;
|
131
|
+
private int m_indexB;
|
132
|
+
private final Vec2 m_localCenterA = new Vec2();
|
133
|
+
private final Vec2 m_localCenterB = new Vec2();
|
134
|
+
private float m_invMassA;
|
135
|
+
private float m_invMassB;
|
136
|
+
private float m_invIA;
|
137
|
+
private float m_invIB;
|
138
|
+
private final Vec2 m_axis, m_perp;
|
139
|
+
private float m_s1, m_s2;
|
140
|
+
private float m_a1, m_a2;
|
141
|
+
private final Mat33 m_K;
|
142
|
+
private float m_motorMass; // effective mass for motor/limit translational constraint.
|
143
|
+
|
144
|
+
protected PrismaticJoint(IWorldPool argWorld, PrismaticJointDef def) {
|
145
|
+
super(argWorld, def);
|
146
|
+
m_localAnchorA = new Vec2(def.localAnchorA);
|
147
|
+
m_localAnchorB = new Vec2(def.localAnchorB);
|
148
|
+
m_localXAxisA = new Vec2(def.localAxisA);
|
149
|
+
m_localXAxisA.normalize();
|
150
|
+
m_localYAxisA = new Vec2();
|
151
|
+
Vec2.crossToOutUnsafe(1f, m_localXAxisA, m_localYAxisA);
|
152
|
+
m_referenceAngle = def.referenceAngle;
|
153
|
+
|
154
|
+
m_impulse = new Vec3();
|
155
|
+
m_motorMass = 0.0f;
|
156
|
+
m_motorImpulse = 0.0f;
|
157
|
+
|
158
|
+
m_lowerTranslation = def.lowerTranslation;
|
159
|
+
m_upperTranslation = def.upperTranslation;
|
160
|
+
m_maxMotorForce = def.maxMotorForce;
|
161
|
+
m_motorSpeed = def.motorSpeed;
|
162
|
+
m_enableLimit = def.enableLimit;
|
163
|
+
m_enableMotor = def.enableMotor;
|
164
|
+
m_limitState = LimitState.INACTIVE;
|
165
|
+
|
166
|
+
m_K = new Mat33();
|
167
|
+
m_axis = new Vec2();
|
168
|
+
m_perp = new Vec2();
|
169
|
+
}
|
170
|
+
|
171
|
+
public Vec2 getLocalAnchorA() {
|
172
|
+
return m_localAnchorA;
|
173
|
+
}
|
174
|
+
|
175
|
+
public Vec2 getLocalAnchorB() {
|
176
|
+
return m_localAnchorB;
|
177
|
+
}
|
178
|
+
|
179
|
+
@Override
|
180
|
+
public void getAnchorA(Vec2 argOut) {
|
181
|
+
m_bodyA.getWorldPointToOut(m_localAnchorA, argOut);
|
182
|
+
}
|
183
|
+
|
184
|
+
@Override
|
185
|
+
public void getAnchorB(Vec2 argOut) {
|
186
|
+
m_bodyB.getWorldPointToOut(m_localAnchorB, argOut);
|
187
|
+
}
|
188
|
+
|
189
|
+
@Override
|
190
|
+
public void getReactionForce(float inv_dt, Vec2 argOut) {
|
191
|
+
Vec2 temp = pool.popVec2();
|
192
|
+
temp.set(m_axis).mulLocal(m_motorImpulse + m_impulse.z);
|
193
|
+
argOut.set(m_perp).mulLocal(m_impulse.x).addLocal(temp).mulLocal(inv_dt);
|
194
|
+
pool.pushVec2(1);
|
195
|
+
}
|
196
|
+
|
197
|
+
@Override
|
198
|
+
public float getReactionTorque(float inv_dt) {
|
199
|
+
return inv_dt * m_impulse.y;
|
200
|
+
}
|
201
|
+
|
202
|
+
/**
|
203
|
+
* Get the current joint translation, usually in meters.
|
204
|
+
*/
|
205
|
+
public float getJointSpeed() {
|
206
|
+
Body bA = m_bodyA;
|
207
|
+
Body bB = m_bodyB;
|
208
|
+
|
209
|
+
Vec2 temp = pool.popVec2();
|
210
|
+
Vec2 rA = pool.popVec2();
|
211
|
+
Vec2 rB = pool.popVec2();
|
212
|
+
Vec2 p1 = pool.popVec2();
|
213
|
+
Vec2 p2 = pool.popVec2();
|
214
|
+
Vec2 d = pool.popVec2();
|
215
|
+
Vec2 axis = pool.popVec2();
|
216
|
+
Vec2 temp2 = pool.popVec2();
|
217
|
+
Vec2 temp3 = pool.popVec2();
|
218
|
+
|
219
|
+
temp.set(m_localAnchorA).subLocal(bA.m_sweep.localCenter);
|
220
|
+
Rot.mulToOutUnsafe(bA.m_xf.q, temp, rA);
|
221
|
+
|
222
|
+
temp.set(m_localAnchorB).subLocal(bB.m_sweep.localCenter);
|
223
|
+
Rot.mulToOutUnsafe(bB.m_xf.q, temp, rB);
|
224
|
+
|
225
|
+
p1.set(bA.m_sweep.c).addLocal(rA);
|
226
|
+
p2.set(bB.m_sweep.c).addLocal(rB);
|
227
|
+
|
228
|
+
d.set(p2).subLocal(p1);
|
229
|
+
Rot.mulToOutUnsafe(bA.m_xf.q, m_localXAxisA, axis);
|
230
|
+
|
231
|
+
Vec2 vA = bA.m_linearVelocity;
|
232
|
+
Vec2 vB = bB.m_linearVelocity;
|
233
|
+
float wA = bA.m_angularVelocity;
|
234
|
+
float wB = bB.m_angularVelocity;
|
235
|
+
|
236
|
+
|
237
|
+
Vec2.crossToOutUnsafe(wA, axis, temp);
|
238
|
+
Vec2.crossToOutUnsafe(wB, rB, temp2);
|
239
|
+
Vec2.crossToOutUnsafe(wA, rA, temp3);
|
240
|
+
|
241
|
+
temp2.addLocal(vB).subLocal(vA).subLocal(temp3);
|
242
|
+
float speed = Vec2.dot(d, temp) + Vec2.dot(axis, temp2);
|
243
|
+
|
244
|
+
pool.pushVec2(9);
|
245
|
+
|
246
|
+
return speed;
|
247
|
+
}
|
248
|
+
|
249
|
+
public float getJointTranslation() {
|
250
|
+
Vec2 pA = pool.popVec2(), pB = pool.popVec2(), axis = pool.popVec2();
|
251
|
+
m_bodyA.getWorldPointToOut(m_localAnchorA, pA);
|
252
|
+
m_bodyB.getWorldPointToOut(m_localAnchorB, pB);
|
253
|
+
m_bodyA.getWorldVectorToOutUnsafe(m_localXAxisA, axis);
|
254
|
+
pB.subLocal(pA);
|
255
|
+
float translation = Vec2.dot(pB, axis);
|
256
|
+
pool.pushVec2(3);
|
257
|
+
return translation;
|
258
|
+
}
|
259
|
+
|
260
|
+
/**
|
261
|
+
* Is the joint limit enabled?
|
262
|
+
*
|
263
|
+
* @return
|
264
|
+
*/
|
265
|
+
public boolean isLimitEnabled() {
|
266
|
+
return m_enableLimit;
|
267
|
+
}
|
268
|
+
|
269
|
+
/**
|
270
|
+
* Enable/disable the joint limit.
|
271
|
+
*
|
272
|
+
* @param flag
|
273
|
+
*/
|
274
|
+
public void enableLimit(boolean flag) {
|
275
|
+
if (flag != m_enableLimit) {
|
276
|
+
m_bodyA.setAwake(true);
|
277
|
+
m_bodyB.setAwake(true);
|
278
|
+
m_enableLimit = flag;
|
279
|
+
m_impulse.z = 0.0f;
|
280
|
+
}
|
281
|
+
}
|
282
|
+
|
283
|
+
/**
|
284
|
+
* Get the lower joint limit, usually in meters.
|
285
|
+
*
|
286
|
+
* @return
|
287
|
+
*/
|
288
|
+
public float getLowerLimit() {
|
289
|
+
return m_lowerTranslation;
|
290
|
+
}
|
291
|
+
|
292
|
+
/**
|
293
|
+
* Get the upper joint limit, usually in meters.
|
294
|
+
*
|
295
|
+
* @return
|
296
|
+
*/
|
297
|
+
public float getUpperLimit() {
|
298
|
+
return m_upperTranslation;
|
299
|
+
}
|
300
|
+
|
301
|
+
/**
|
302
|
+
* Set the joint limits, usually in meters.
|
303
|
+
*
|
304
|
+
* @param lower
|
305
|
+
* @param upper
|
306
|
+
*/
|
307
|
+
public void setLimits(float lower, float upper) {
|
308
|
+
assert (lower <= upper);
|
309
|
+
if (lower != m_lowerTranslation || upper != m_upperTranslation) {
|
310
|
+
m_bodyA.setAwake(true);
|
311
|
+
m_bodyB.setAwake(true);
|
312
|
+
m_lowerTranslation = lower;
|
313
|
+
m_upperTranslation = upper;
|
314
|
+
m_impulse.z = 0.0f;
|
315
|
+
}
|
316
|
+
}
|
317
|
+
|
318
|
+
/**
|
319
|
+
* Is the joint motor enabled?
|
320
|
+
*
|
321
|
+
* @return
|
322
|
+
*/
|
323
|
+
public boolean isMotorEnabled() {
|
324
|
+
return m_enableMotor;
|
325
|
+
}
|
326
|
+
|
327
|
+
/**
|
328
|
+
* Enable/disable the joint motor.
|
329
|
+
*
|
330
|
+
* @param flag
|
331
|
+
*/
|
332
|
+
public void enableMotor(boolean flag) {
|
333
|
+
m_bodyA.setAwake(true);
|
334
|
+
m_bodyB.setAwake(true);
|
335
|
+
m_enableMotor = flag;
|
336
|
+
}
|
337
|
+
|
338
|
+
/**
|
339
|
+
* Set the motor speed, usually in meters per second.
|
340
|
+
*
|
341
|
+
* @param speed
|
342
|
+
*/
|
343
|
+
public void setMotorSpeed(float speed) {
|
344
|
+
m_bodyA.setAwake(true);
|
345
|
+
m_bodyB.setAwake(true);
|
346
|
+
m_motorSpeed = speed;
|
347
|
+
}
|
348
|
+
|
349
|
+
/**
|
350
|
+
* Get the motor speed, usually in meters per second.
|
351
|
+
*
|
352
|
+
* @return
|
353
|
+
*/
|
354
|
+
public float getMotorSpeed() {
|
355
|
+
return m_motorSpeed;
|
356
|
+
}
|
357
|
+
|
358
|
+
/**
|
359
|
+
* Set the maximum motor force, usually in N.
|
360
|
+
*
|
361
|
+
* @param force
|
362
|
+
*/
|
363
|
+
public void setMaxMotorForce(float force) {
|
364
|
+
m_bodyA.setAwake(true);
|
365
|
+
m_bodyB.setAwake(true);
|
366
|
+
m_maxMotorForce = force;
|
367
|
+
}
|
368
|
+
|
369
|
+
/**
|
370
|
+
* Get the current motor force, usually in N.
|
371
|
+
*
|
372
|
+
* @param inv_dt
|
373
|
+
* @return
|
374
|
+
*/
|
375
|
+
public float getMotorForce(float inv_dt) {
|
376
|
+
return m_motorImpulse * inv_dt;
|
377
|
+
}
|
378
|
+
|
379
|
+
public float getMaxMotorForce() {
|
380
|
+
return m_maxMotorForce;
|
381
|
+
}
|
382
|
+
|
383
|
+
public float getReferenceAngle() {
|
384
|
+
return m_referenceAngle;
|
385
|
+
}
|
386
|
+
|
387
|
+
public Vec2 getLocalAxisA() {
|
388
|
+
return m_localXAxisA;
|
389
|
+
}
|
390
|
+
|
391
|
+
@Override
|
392
|
+
public void initVelocityConstraints(final SolverData data) {
|
393
|
+
m_indexA = m_bodyA.m_islandIndex;
|
394
|
+
m_indexB = m_bodyB.m_islandIndex;
|
395
|
+
m_localCenterA.set(m_bodyA.m_sweep.localCenter);
|
396
|
+
m_localCenterB.set(m_bodyB.m_sweep.localCenter);
|
397
|
+
m_invMassA = m_bodyA.m_invMass;
|
398
|
+
m_invMassB = m_bodyB.m_invMass;
|
399
|
+
m_invIA = m_bodyA.m_invI;
|
400
|
+
m_invIB = m_bodyB.m_invI;
|
401
|
+
|
402
|
+
Vec2 cA = data.positions[m_indexA].c;
|
403
|
+
float aA = data.positions[m_indexA].a;
|
404
|
+
Vec2 vA = data.velocities[m_indexA].v;
|
405
|
+
float wA = data.velocities[m_indexA].w;
|
406
|
+
|
407
|
+
Vec2 cB = data.positions[m_indexB].c;
|
408
|
+
float aB = data.positions[m_indexB].a;
|
409
|
+
Vec2 vB = data.velocities[m_indexB].v;
|
410
|
+
float wB = data.velocities[m_indexB].w;
|
411
|
+
|
412
|
+
final Rot qA = pool.popRot();
|
413
|
+
final Rot qB = pool.popRot();
|
414
|
+
final Vec2 d = pool.popVec2();
|
415
|
+
final Vec2 temp = pool.popVec2();
|
416
|
+
final Vec2 rA = pool.popVec2();
|
417
|
+
final Vec2 rB = pool.popVec2();
|
418
|
+
|
419
|
+
qA.set(aA);
|
420
|
+
qB.set(aB);
|
421
|
+
|
422
|
+
// Compute the effective masses.
|
423
|
+
Rot.mulToOutUnsafe(qA, d.set(m_localAnchorA).subLocal(m_localCenterA), rA);
|
424
|
+
Rot.mulToOutUnsafe(qB, d.set(m_localAnchorB).subLocal(m_localCenterB), rB);
|
425
|
+
d.set(cB).subLocal(cA).addLocal(rB).subLocal(rA);
|
426
|
+
|
427
|
+
float mA = m_invMassA, mB = m_invMassB;
|
428
|
+
float iA = m_invIA, iB = m_invIB;
|
429
|
+
|
430
|
+
// Compute motor Jacobian and effective mass.
|
431
|
+
{
|
432
|
+
Rot.mulToOutUnsafe(qA, m_localXAxisA, m_axis);
|
433
|
+
temp.set(d).addLocal(rA);
|
434
|
+
m_a1 = Vec2.cross(temp, m_axis);
|
435
|
+
m_a2 = Vec2.cross(rB, m_axis);
|
436
|
+
|
437
|
+
m_motorMass = mA + mB + iA * m_a1 * m_a1 + iB * m_a2 * m_a2;
|
438
|
+
if (m_motorMass > 0.0f) {
|
439
|
+
m_motorMass = 1.0f / m_motorMass;
|
440
|
+
}
|
441
|
+
}
|
442
|
+
|
443
|
+
// Prismatic constraint.
|
444
|
+
{
|
445
|
+
Rot.mulToOutUnsafe(qA, m_localYAxisA, m_perp);
|
446
|
+
|
447
|
+
temp.set(d).addLocal(rA);
|
448
|
+
m_s1 = Vec2.cross(temp, m_perp);
|
449
|
+
m_s2 = Vec2.cross(rB, m_perp);
|
450
|
+
|
451
|
+
float k11 = mA + mB + iA * m_s1 * m_s1 + iB * m_s2 * m_s2;
|
452
|
+
float k12 = iA * m_s1 + iB * m_s2;
|
453
|
+
float k13 = iA * m_s1 * m_a1 + iB * m_s2 * m_a2;
|
454
|
+
float k22 = iA + iB;
|
455
|
+
if (k22 == 0.0f) {
|
456
|
+
// For bodies with fixed rotation.
|
457
|
+
k22 = 1.0f;
|
458
|
+
}
|
459
|
+
float k23 = iA * m_a1 + iB * m_a2;
|
460
|
+
float k33 = mA + mB + iA * m_a1 * m_a1 + iB * m_a2 * m_a2;
|
461
|
+
|
462
|
+
m_K.ex.set(k11, k12, k13);
|
463
|
+
m_K.ey.set(k12, k22, k23);
|
464
|
+
m_K.ez.set(k13, k23, k33);
|
465
|
+
}
|
466
|
+
|
467
|
+
// Compute motor and limit terms.
|
468
|
+
if (m_enableLimit) {
|
469
|
+
|
470
|
+
float jointTranslation = Vec2.dot(m_axis, d);
|
471
|
+
if (MathUtils.abs(m_upperTranslation - m_lowerTranslation) < 2.0f * Settings.linearSlop) {
|
472
|
+
m_limitState = LimitState.EQUAL;
|
473
|
+
} else if (jointTranslation <= m_lowerTranslation) {
|
474
|
+
if (m_limitState != LimitState.AT_LOWER) {
|
475
|
+
m_limitState = LimitState.AT_LOWER;
|
476
|
+
m_impulse.z = 0.0f;
|
477
|
+
}
|
478
|
+
} else if (jointTranslation >= m_upperTranslation) {
|
479
|
+
if (m_limitState != LimitState.AT_UPPER) {
|
480
|
+
m_limitState = LimitState.AT_UPPER;
|
481
|
+
m_impulse.z = 0.0f;
|
482
|
+
}
|
483
|
+
} else {
|
484
|
+
m_limitState = LimitState.INACTIVE;
|
485
|
+
m_impulse.z = 0.0f;
|
486
|
+
}
|
487
|
+
} else {
|
488
|
+
m_limitState = LimitState.INACTIVE;
|
489
|
+
m_impulse.z = 0.0f;
|
490
|
+
}
|
491
|
+
|
492
|
+
if (m_enableMotor == false) {
|
493
|
+
m_motorImpulse = 0.0f;
|
494
|
+
}
|
495
|
+
|
496
|
+
if (data.step.warmStarting) {
|
497
|
+
// Account for variable time step.
|
498
|
+
m_impulse.mulLocal(data.step.dtRatio);
|
499
|
+
m_motorImpulse *= data.step.dtRatio;
|
500
|
+
|
501
|
+
final Vec2 P = pool.popVec2();
|
502
|
+
temp.set(m_axis).mulLocal(m_motorImpulse + m_impulse.z);
|
503
|
+
P.set(m_perp).mulLocal(m_impulse.x).addLocal(temp);
|
504
|
+
|
505
|
+
float LA = m_impulse.x * m_s1 + m_impulse.y + (m_motorImpulse + m_impulse.z) * m_a1;
|
506
|
+
float LB = m_impulse.x * m_s2 + m_impulse.y + (m_motorImpulse + m_impulse.z) * m_a2;
|
507
|
+
|
508
|
+
vA.x -= mA * P.x;
|
509
|
+
vA.y -= mA * P.y;
|
510
|
+
wA -= iA * LA;
|
511
|
+
|
512
|
+
vB.x += mB * P.x;
|
513
|
+
vB.y += mB * P.y;
|
514
|
+
wB += iB * LB;
|
515
|
+
|
516
|
+
pool.pushVec2(1);
|
517
|
+
} else {
|
518
|
+
m_impulse.setZero();
|
519
|
+
m_motorImpulse = 0.0f;
|
520
|
+
}
|
521
|
+
|
522
|
+
// data.velocities[m_indexA].v.set(vA);
|
523
|
+
data.velocities[m_indexA].w = wA;
|
524
|
+
// data.velocities[m_indexB].v.set(vB);
|
525
|
+
data.velocities[m_indexB].w = wB;
|
526
|
+
|
527
|
+
pool.pushRot(2);
|
528
|
+
pool.pushVec2(4);
|
529
|
+
}
|
530
|
+
|
531
|
+
@Override
|
532
|
+
public void solveVelocityConstraints(final SolverData data) {
|
533
|
+
Vec2 vA = data.velocities[m_indexA].v;
|
534
|
+
float wA = data.velocities[m_indexA].w;
|
535
|
+
Vec2 vB = data.velocities[m_indexB].v;
|
536
|
+
float wB = data.velocities[m_indexB].w;
|
537
|
+
|
538
|
+
float mA = m_invMassA, mB = m_invMassB;
|
539
|
+
float iA = m_invIA, iB = m_invIB;
|
540
|
+
|
541
|
+
final Vec2 temp = pool.popVec2();
|
542
|
+
|
543
|
+
// Solve linear motor constraint.
|
544
|
+
if (m_enableMotor && m_limitState != LimitState.EQUAL) {
|
545
|
+
temp.set(vB).subLocal(vA);
|
546
|
+
float Cdot = Vec2.dot(m_axis, temp) + m_a2 * wB - m_a1 * wA;
|
547
|
+
float impulse = m_motorMass * (m_motorSpeed - Cdot);
|
548
|
+
float oldImpulse = m_motorImpulse;
|
549
|
+
float maxImpulse = data.step.dt * m_maxMotorForce;
|
550
|
+
m_motorImpulse = MathUtils.clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse);
|
551
|
+
impulse = m_motorImpulse - oldImpulse;
|
552
|
+
|
553
|
+
final Vec2 P = pool.popVec2();
|
554
|
+
P.set(m_axis).mulLocal(impulse);
|
555
|
+
float LA = impulse * m_a1;
|
556
|
+
float LB = impulse * m_a2;
|
557
|
+
|
558
|
+
vA.x -= mA * P.x;
|
559
|
+
vA.y -= mA * P.y;
|
560
|
+
wA -= iA * LA;
|
561
|
+
|
562
|
+
vB.x += mB * P.x;
|
563
|
+
vB.y += mB * P.y;
|
564
|
+
wB += iB * LB;
|
565
|
+
|
566
|
+
pool.pushVec2(1);
|
567
|
+
}
|
568
|
+
|
569
|
+
final Vec2 Cdot1 = pool.popVec2();
|
570
|
+
temp.set(vB).subLocal(vA);
|
571
|
+
Cdot1.x = Vec2.dot(m_perp, temp) + m_s2 * wB - m_s1 * wA;
|
572
|
+
Cdot1.y = wB - wA;
|
573
|
+
// System.out.println(Cdot1);
|
574
|
+
|
575
|
+
if (m_enableLimit && m_limitState != LimitState.INACTIVE) {
|
576
|
+
// Solve prismatic and limit constraint in block form.
|
577
|
+
float Cdot2;
|
578
|
+
temp.set(vB).subLocal(vA);
|
579
|
+
Cdot2 = Vec2.dot(m_axis, temp) + m_a2 * wB - m_a1 * wA;
|
580
|
+
|
581
|
+
final Vec3 Cdot = pool.popVec3();
|
582
|
+
Cdot.set(Cdot1.x, Cdot1.y, Cdot2);
|
583
|
+
|
584
|
+
final Vec3 f1 = pool.popVec3();
|
585
|
+
final Vec3 df = pool.popVec3();
|
586
|
+
|
587
|
+
f1.set(m_impulse);
|
588
|
+
m_K.solve33ToOut(Cdot.negateLocal(), df);
|
589
|
+
// Cdot.negateLocal(); not used anymore
|
590
|
+
m_impulse.addLocal(df);
|
591
|
+
|
592
|
+
if (m_limitState == LimitState.AT_LOWER) {
|
593
|
+
m_impulse.z = MathUtils.max(m_impulse.z, 0.0f);
|
594
|
+
} else if (m_limitState == LimitState.AT_UPPER) {
|
595
|
+
m_impulse.z = MathUtils.min(m_impulse.z, 0.0f);
|
596
|
+
}
|
597
|
+
|
598
|
+
// f2(1:2) = invK(1:2,1:2) * (-Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3))) +
|
599
|
+
// f1(1:2)
|
600
|
+
final Vec2 b = pool.popVec2();
|
601
|
+
final Vec2 f2r = pool.popVec2();
|
602
|
+
|
603
|
+
temp.set(m_K.ez.x, m_K.ez.y).mulLocal(m_impulse.z - f1.z);
|
604
|
+
b.set(Cdot1).negateLocal().subLocal(temp);
|
605
|
+
|
606
|
+
m_K.solve22ToOut(b, f2r);
|
607
|
+
f2r.addLocal(f1.x, f1.y);
|
608
|
+
m_impulse.x = f2r.x;
|
609
|
+
m_impulse.y = f2r.y;
|
610
|
+
|
611
|
+
df.set(m_impulse).subLocal(f1);
|
612
|
+
|
613
|
+
final Vec2 P = pool.popVec2();
|
614
|
+
temp.set(m_axis).mulLocal(df.z);
|
615
|
+
P.set(m_perp).mulLocal(df.x).addLocal(temp);
|
616
|
+
|
617
|
+
float LA = df.x * m_s1 + df.y + df.z * m_a1;
|
618
|
+
float LB = df.x * m_s2 + df.y + df.z * m_a2;
|
619
|
+
|
620
|
+
vA.x -= mA * P.x;
|
621
|
+
vA.y -= mA * P.y;
|
622
|
+
wA -= iA * LA;
|
623
|
+
|
624
|
+
vB.x += mB * P.x;
|
625
|
+
vB.y += mB * P.y;
|
626
|
+
wB += iB * LB;
|
627
|
+
|
628
|
+
pool.pushVec2(3);
|
629
|
+
pool.pushVec3(3);
|
630
|
+
} else {
|
631
|
+
// Limit is inactive, just solve the prismatic constraint in block form.
|
632
|
+
final Vec2 df = pool.popVec2();
|
633
|
+
m_K.solve22ToOut(Cdot1.negateLocal(), df);
|
634
|
+
Cdot1.negateLocal();
|
635
|
+
|
636
|
+
m_impulse.x += df.x;
|
637
|
+
m_impulse.y += df.y;
|
638
|
+
|
639
|
+
final Vec2 P = pool.popVec2();
|
640
|
+
P.set(m_perp).mulLocal(df.x);
|
641
|
+
float LA = df.x * m_s1 + df.y;
|
642
|
+
float LB = df.x * m_s2 + df.y;
|
643
|
+
|
644
|
+
vA.x -= mA * P.x;
|
645
|
+
vA.y -= mA * P.y;
|
646
|
+
wA -= iA * LA;
|
647
|
+
|
648
|
+
vB.x += mB * P.x;
|
649
|
+
vB.y += mB * P.y;
|
650
|
+
wB += iB * LB;
|
651
|
+
|
652
|
+
pool.pushVec2(2);
|
653
|
+
}
|
654
|
+
|
655
|
+
// data.velocities[m_indexA].v.set(vA);
|
656
|
+
data.velocities[m_indexA].w = wA;
|
657
|
+
// data.velocities[m_indexB].v.set(vB);
|
658
|
+
data.velocities[m_indexB].w = wB;
|
659
|
+
|
660
|
+
pool.pushVec2(2);
|
661
|
+
}
|
662
|
+
|
663
|
+
|
664
|
+
@Override
|
665
|
+
public boolean solvePositionConstraints(final SolverData data) {
|
666
|
+
|
667
|
+
final Rot qA = pool.popRot();
|
668
|
+
final Rot qB = pool.popRot();
|
669
|
+
final Vec2 rA = pool.popVec2();
|
670
|
+
final Vec2 rB = pool.popVec2();
|
671
|
+
final Vec2 d = pool.popVec2();
|
672
|
+
final Vec2 axis = pool.popVec2();
|
673
|
+
final Vec2 perp = pool.popVec2();
|
674
|
+
final Vec2 temp = pool.popVec2();
|
675
|
+
final Vec2 C1 = pool.popVec2();
|
676
|
+
|
677
|
+
final Vec3 impulse = pool.popVec3();
|
678
|
+
|
679
|
+
Vec2 cA = data.positions[m_indexA].c;
|
680
|
+
float aA = data.positions[m_indexA].a;
|
681
|
+
Vec2 cB = data.positions[m_indexB].c;
|
682
|
+
float aB = data.positions[m_indexB].a;
|
683
|
+
|
684
|
+
qA.set(aA);
|
685
|
+
qB.set(aB);
|
686
|
+
|
687
|
+
float mA = m_invMassA, mB = m_invMassB;
|
688
|
+
float iA = m_invIA, iB = m_invIB;
|
689
|
+
|
690
|
+
// Compute fresh Jacobians
|
691
|
+
Rot.mulToOutUnsafe(qA, temp.set(m_localAnchorA).subLocal(m_localCenterA), rA);
|
692
|
+
Rot.mulToOutUnsafe(qB, temp.set(m_localAnchorB).subLocal(m_localCenterB), rB);
|
693
|
+
d.set(cB).addLocal(rB).subLocal(cA).subLocal(rA);
|
694
|
+
|
695
|
+
Rot.mulToOutUnsafe(qA, m_localXAxisA, axis);
|
696
|
+
float a1 = Vec2.cross(temp.set(d).addLocal(rA), axis);
|
697
|
+
float a2 = Vec2.cross(rB, axis);
|
698
|
+
Rot.mulToOutUnsafe(qA, m_localYAxisA, perp);
|
699
|
+
|
700
|
+
float s1 = Vec2.cross(temp.set(d).addLocal(rA), perp);
|
701
|
+
float s2 = Vec2.cross(rB, perp);
|
702
|
+
|
703
|
+
C1.x = Vec2.dot(perp, d);
|
704
|
+
C1.y = aB - aA - m_referenceAngle;
|
705
|
+
|
706
|
+
float linearError = MathUtils.abs(C1.x);
|
707
|
+
float angularError = MathUtils.abs(C1.y);
|
708
|
+
|
709
|
+
boolean active = false;
|
710
|
+
float C2 = 0.0f;
|
711
|
+
if (m_enableLimit) {
|
712
|
+
float translation = Vec2.dot(axis, d);
|
713
|
+
if (MathUtils.abs(m_upperTranslation - m_lowerTranslation) < 2.0f * Settings.linearSlop) {
|
714
|
+
// Prevent large angular corrections
|
715
|
+
C2 =
|
716
|
+
MathUtils.clamp(translation, -Settings.maxLinearCorrection,
|
717
|
+
Settings.maxLinearCorrection);
|
718
|
+
linearError = MathUtils.max(linearError, MathUtils.abs(translation));
|
719
|
+
active = true;
|
720
|
+
} else if (translation <= m_lowerTranslation) {
|
721
|
+
// Prevent large linear corrections and allow some slop.
|
722
|
+
C2 =
|
723
|
+
MathUtils.clamp(translation - m_lowerTranslation + Settings.linearSlop,
|
724
|
+
-Settings.maxLinearCorrection, 0.0f);
|
725
|
+
linearError = MathUtils.max(linearError, m_lowerTranslation - translation);
|
726
|
+
active = true;
|
727
|
+
} else if (translation >= m_upperTranslation) {
|
728
|
+
// Prevent large linear corrections and allow some slop.
|
729
|
+
C2 =
|
730
|
+
MathUtils.clamp(translation - m_upperTranslation - Settings.linearSlop, 0.0f,
|
731
|
+
Settings.maxLinearCorrection);
|
732
|
+
linearError = MathUtils.max(linearError, translation - m_upperTranslation);
|
733
|
+
active = true;
|
734
|
+
}
|
735
|
+
}
|
736
|
+
|
737
|
+
if (active) {
|
738
|
+
float k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;
|
739
|
+
float k12 = iA * s1 + iB * s2;
|
740
|
+
float k13 = iA * s1 * a1 + iB * s2 * a2;
|
741
|
+
float k22 = iA + iB;
|
742
|
+
if (k22 == 0.0f) {
|
743
|
+
// For fixed rotation
|
744
|
+
k22 = 1.0f;
|
745
|
+
}
|
746
|
+
float k23 = iA * a1 + iB * a2;
|
747
|
+
float k33 = mA + mB + iA * a1 * a1 + iB * a2 * a2;
|
748
|
+
|
749
|
+
final Mat33 K = pool.popMat33();
|
750
|
+
K.ex.set(k11, k12, k13);
|
751
|
+
K.ey.set(k12, k22, k23);
|
752
|
+
K.ez.set(k13, k23, k33);
|
753
|
+
|
754
|
+
final Vec3 C = pool.popVec3();
|
755
|
+
C.x = C1.x;
|
756
|
+
C.y = C1.y;
|
757
|
+
C.z = C2;
|
758
|
+
|
759
|
+
K.solve33ToOut(C.negateLocal(), impulse);
|
760
|
+
pool.pushVec3(1);
|
761
|
+
pool.pushMat33(1);
|
762
|
+
} else {
|
763
|
+
float k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;
|
764
|
+
float k12 = iA * s1 + iB * s2;
|
765
|
+
float k22 = iA + iB;
|
766
|
+
if (k22 == 0.0f) {
|
767
|
+
k22 = 1.0f;
|
768
|
+
}
|
769
|
+
|
770
|
+
final Mat22 K = pool.popMat22();
|
771
|
+
K.ex.set(k11, k12);
|
772
|
+
K.ey.set(k12, k22);
|
773
|
+
|
774
|
+
// temp is impulse1
|
775
|
+
K.solveToOut(C1.negateLocal(), temp);
|
776
|
+
C1.negateLocal();
|
777
|
+
|
778
|
+
impulse.x = temp.x;
|
779
|
+
impulse.y = temp.y;
|
780
|
+
impulse.z = 0.0f;
|
781
|
+
|
782
|
+
pool.pushMat22(1);
|
783
|
+
}
|
784
|
+
|
785
|
+
float Px = impulse.x * perp.x + impulse.z * axis.x;
|
786
|
+
float Py = impulse.x * perp.y + impulse.z * axis.y;
|
787
|
+
float LA = impulse.x * s1 + impulse.y + impulse.z * a1;
|
788
|
+
float LB = impulse.x * s2 + impulse.y + impulse.z * a2;
|
789
|
+
|
790
|
+
cA.x -= mA * Px;
|
791
|
+
cA.y -= mA * Py;
|
792
|
+
aA -= iA * LA;
|
793
|
+
cB.x += mB * Px;
|
794
|
+
cB.y += mB * Py;
|
795
|
+
aB += iB * LB;
|
796
|
+
|
797
|
+
// data.positions[m_indexA].c.set(cA);
|
798
|
+
data.positions[m_indexA].a = aA;
|
799
|
+
// data.positions[m_indexB].c.set(cB);
|
800
|
+
data.positions[m_indexB].a = aB;
|
801
|
+
|
802
|
+
pool.pushVec2(7);
|
803
|
+
pool.pushVec3(1);
|
804
|
+
pool.pushRot(2);
|
805
|
+
|
806
|
+
return linearError <= Settings.linearSlop && angularError <= Settings.angularSlop;
|
807
|
+
}
|
808
|
+
}
|