2 * Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
4 * Permission to use, copy, modify, distribute and sell this software
5 * and its documentation for any purpose is hereby granted without fee,
6 * provided that the above copyright notice appear in all copies.
7 * Erin Catto makes no representations about the suitability
8 * of this software for any purpose.
9 * It is provided "as is" without express or implied warranty.
14 import b2dlite
.arbiter
;
15 import b2dlite
.mathutils
;
19 private import b2dlite
.bbody
: Body
;
25 this (Body b1
, Body b2
) { if (b1
< b2
) { body1
= b1
; body2
= b2
; } else { body1
= b2
; body2
= b1
; } }
30 private import b2dlite
.bbody
, b2dlite
.joint
;
34 Arbiter
[ArbiterKey
] arbiters
;
37 Arbiter xarb
; // temporary
39 static bool accumulateImpulses
= true;
40 static bool warmStarting
= true;
41 static bool positionCorrection
= true;
44 this() (in auto ref Vec2 agravity
, int aiterations
) {
46 iterations
= aiterations
;
50 void Add (Body bbody
) {
51 if (bbody
!is null) bodies
~= bbody
;
54 void Add (Joint joint
) {
55 if (joint
!is null) joints
~= joint
;
64 void Step (VFloat
dt) {
65 VFloat inv_dt
= (dt > VFloatNum
!(0.0) ? VFloatNum
!(1.0)/dt : VFloatNum
!(0.0));
66 // determine overlapping bodies and update contact points
69 for (int i
= 0; i
< bodies
.length
; ++i
) {
71 if (b
.invMass
== VFloatNum
!(0.0)) continue;
72 b
.velocity
+= (gravity
+b
.force
*b
.invMass
)*dt;
73 b
.angularVelocity
+= dt*b
.invI
*b
.torque
;
76 foreach (Arbiter arb
; arbiters
.byValue
) arb
.PreStep(inv_dt
);
77 for (int i
= 0; i
< joints
.length
; ++i
) joints
[i
].PreStep(inv_dt
);
79 for (int i
= 0; i
< iterations
; ++i
) {
80 foreach (Arbiter arb
; arbiters
.byValue
) arb
.ApplyImpulse();
81 for (int j
= 0; j
< joints
.length
; ++j
) joints
[j
].ApplyImpulse();
83 // integrate velocities
84 for (int i
= 0; i
< bodies
.length
; ++i
) {
87 b
.position
+= b
.velocity
*dt;
88 b
.rotation
+= b
.angularVelocity
*dt;
90 b
.force
.set(VFloatNum
!(0.0), VFloatNum
!(0.0));
91 b
.torque
= VFloatNum
!(0.0);
97 for (int i
= 0; i
< bodies
.length
; ++i
) {
99 for (int j
= i
+1; j
< bodies
.length
; ++j
) {
101 if (bi
.invMass
== VFloatNum
!(0.0) && bj
.invMass
== VFloatNum
!(0.0)) continue;
102 if (auto arb
= ArbiterKey(bi
, bj
) in arbiters
) {
104 arb
.Update(xarb
.contacts
.ptr
, xarb
.numContacts
);
106 arbiters
[ArbiterKey(bi
, bj
)] = new Arbiter(bi
, bj
);