annotate trunk/chipmunkd/cpArbiter.d @ 15:df4ebc8add66

rename/refactoring
author Extrawurst
date Sat, 04 Dec 2010 00:51:29 +0100
parents c03a41d47b60
children 4ceef5833c8c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
1
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
2 // written in the D programming language
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
3
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
4 module chipmunkd.cpArbiter;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
5
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
6 import chipmunkd.chipmunk;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
7 import chipmunkd.constraints.util;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
8
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
9 // Determines how fast penetrations resolve themselves.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
10 //extern cpFloat cp_bias_coef;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
11 // Amount of allowed penetration. Used to reduce vibrating contacts.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
12 //extern cpFloat cp_collision_slop;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
13
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
14 // Data structure for contact points.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
15 struct cpContact {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
16 // Contact point and normal.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
17 cpVect p, n;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
18 // Penetration distance.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
19 cpFloat dist;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
20
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
21 // Calculated by cpArbiterPreStep().
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
22 cpVect r1, r2;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
23 cpFloat nMass, tMass, bounce;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
24
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
25 // Persistant contact information.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
26 cpFloat jnAcc, jtAcc, jBias;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
27 cpFloat bias;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
28
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
29 // Hash value used to (mostly) uniquely identify a contact.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
30 cpHashValue hash;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
31 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
32
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
33 //// Contacts are always allocated in groups.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
34 //cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
35 //
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
36 //// Sum the contact impulses. (Can be used after cpSpaceStep() returns)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
37 //cpVect cpContactsSumImpulses(cpContact *contacts, int numContacts);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
38 //cpVect cpContactsSumImpulsesWithFriction(cpContact *contacts, int numContacts);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
39
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
40 enum cpArbiterState {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
41 cpArbiterStateNormal,
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
42 cpArbiterStateFirstColl,
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
43 cpArbiterStateIgnore,
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
44 cpArbiterStateSleep,
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
45 cpArbiterStateCached,
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
46 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
47
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
48 // Data structure for tracking collisions between shapes.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
49 struct cpArbiter {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
50 // Information on the contact points between the objects.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
51 int numContacts;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
52 cpContact *contacts;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
53
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
54 // The two shapes and bodies involved in the collision.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
55 // These variables are NOT in the order defined by the collision handler.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
56 // Using CP_ARBITER_GET_SHAPES and CP_ARBITER_GET_BODIES will save you from
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
57 // many headaches
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
58 cpShape* private_a;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
59 cpShape* private_b;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
60
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
61 // Calculated before calling the pre-solve collision handler
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
62 // Override them with custom values if you want specialized behavior
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
63 cpFloat e;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
64 cpFloat u;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
65 // Used for surface_v calculations, implementation may change
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
66 cpVect surface_vr;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
67
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
68 // Time stamp of the arbiter. (from cpSpace)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
69 cpTimestamp stamp;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
70
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
71 cpCollisionHandler *handler;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
72
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
73 // Are the shapes swapped in relation to the collision handler?
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
74 cpBool swappedColl;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
75 cpArbiterState state;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
76 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
77
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
78 //// Arbiters are allocated in large buffers by the space and don't require a destroy function
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
79 //cpArbiter* cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
80 //
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
81 //// These functions are all intended to be used internally.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
82 //// Inject new contact points into the arbiter while preserving contact history.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
83 //void cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, struct cpCollisionHandler *handler, cpShape *a, cpShape *b);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
84 //// Precalculate values used by the solver.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
85 //void cpArbiterPreStep(cpArbiter *arb, cpFloat dt_inv);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
86 //void cpArbiterApplyCachedImpulse(cpArbiter *arb);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
87 //// Run an iteration of the solver on the arbiter.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
88 //void cpArbiterApplyImpulse(cpArbiter *arb, cpFloat eCoef);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
89 //
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
90 //// Arbiter Helper Functions
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
91 //cpVect cpArbiterTotalImpulse(cpArbiter *arb);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
92 //cpVect cpArbiterTotalImpulseWithFriction(cpArbiter *arb);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
93 //void cpArbiterIgnore(cpArbiter *arb);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
94
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
95
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
96 static void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
97 cpArbiterGetShapes(/+const+/ cpArbiter *arb, cpShape **a, cpShape **b)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
98 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
99 if(arb.swappedColl){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
100 (*a) = arb.private_b, (*b) = arb.private_a;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
101 } else {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
102 (*a) = arb.private_a, (*b) = arb.private_b;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
103 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
104 }
13
c03a41d47b60 - finished all constraints properties
Extrawurst
parents: 4
diff changeset
105
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
106 template CP_ARBITER_GET_SHAPES(string arb,string a,string b)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
107 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
108 enum CP_ARBITER_GET_SHAPES = "cpShape* "~a~", "~b~";"~
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
109 "cpArbiterGetShapes("~arb~", &"~a~", &"~b~");";
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
110 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
111
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
112 static void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
113 cpArbiterGetBodies(/+const+/ cpArbiter *arb, cpBody **a, cpBody **b)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
114 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
115 //CP_ARBITER_GET_SHAPES(arb, shape_a, shape_b);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
116 cpShape *shape_a, shape_b; cpArbiterGetShapes(arb, &shape_a, &shape_b);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
117 (*a) = shape_a._body;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
118 (*b) = shape_b._body;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
119 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
120 //#define CP_ARBITER_GET_BODIES(arb, a, b) cpBody *a, *b; cpArbiterGetBodies(arb, &a, &b);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
121
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
122 static cpBool
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
123 cpArbiterIsFirstContact(const cpArbiter *arb)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
124 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
125 return arb.state == cpArbiterState.cpArbiterStateFirstColl;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
126 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
127
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
128 static cpVect
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
129 cpArbiterGetNormal(const cpArbiter *arb, int i)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
130 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
131 cpVect n = arb.contacts[i].n;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
132 return arb.swappedColl ? cpvneg(n) : n;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
133 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
134
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
135 static cpVect
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
136 cpArbiterGetPoint(const cpArbiter *arb, int i)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
137 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
138 return arb.contacts[i].p;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
139 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
140
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
141 cpFloat cp_bias_coef = 0.1f;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
142 cpFloat cp_collision_slop = 0.1f;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
143
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
144 cpContact*
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
145 cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
146 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
147 con.p = p;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
148 con.n = n;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
149 con.dist = dist;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
150
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
151 con.jnAcc = 0.0f;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
152 con.jtAcc = 0.0f;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
153 con.jBias = 0.0f;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
154
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
155 con.hash = hash;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
156
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
157 return con;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
158 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
159
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
160 cpVect
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
161 cpArbiterTotalImpulse(cpArbiter *arb)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
162 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
163 cpContact *contacts = arb.contacts;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
164 cpVect sum = cpvzero;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
165
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
166 for(int i=0, count=arb.numContacts; i<count; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
167 cpContact *con = &contacts[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
168 sum = cpvadd(sum, cpvmult(con.n, con.jnAcc));
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
169 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
170
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
171 return sum;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
172 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
173
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
174 cpVect
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
175 cpArbiterTotalImpulseWithFriction(cpArbiter *arb)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
176 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
177 cpContact *contacts = arb.contacts;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
178 cpVect sum = cpvzero;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
179
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
180 for(int i=0, count=arb.numContacts; i<count; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
181 cpContact *con = &contacts[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
182 sum = cpvadd(sum, cpvrotate(con.n, cpv(con.jnAcc, con.jtAcc)));
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
183 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
184
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
185 return sum;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
186 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
187
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
188 cpFloat
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
189 cpContactsEstimateCrushingImpulse(cpContact *contacts, int numContacts)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
190 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
191 cpFloat fsum = 0.0f;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
192 cpVect vsum = cpvzero;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
193
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
194 for(int i=0; i<numContacts; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
195 cpContact *con = &contacts[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
196 cpVect j = cpvrotate(con.n, cpv(con.jnAcc, con.jtAcc));
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
197
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
198 fsum += cpvlength(j);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
199 vsum = cpvadd(vsum, j);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
200 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
201
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
202 cpFloat vmag = cpvlength(vsum);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
203 return (1.0f - vmag/fsum);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
204 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
205
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
206 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
207 cpArbiterIgnore(cpArbiter *arb)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
208 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
209 arb.state = cpArbiterState.cpArbiterStateIgnore;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
210 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
211
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
212 cpArbiter*
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
213 cpArbiterAlloc()
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
214 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
215 return cast(cpArbiter *)cpcalloc(1, cpArbiter.sizeof);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
216 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
217
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
218 cpArbiter*
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
219 cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
220 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
221 arb.numContacts = 0;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
222 arb.contacts = null;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
223
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
224 arb.private_a = a;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
225 arb.private_b = b;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
226
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
227 arb.stamp = 0;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
228 arb.state = cpArbiterState.cpArbiterStateFirstColl;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
229
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
230 return arb;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
231 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
232
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
233 cpArbiter*
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
234 cpArbiterNew(cpShape *a, cpShape *b)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
235 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
236 return cpArbiterInit(cpArbiterAlloc(), a, b);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
237 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
238
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
239 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
240 cpArbiterDestroy(cpArbiter *arb)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
241 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
242 // if(arb.contacts) cpfree(arb.contacts);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
243 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
244
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
245 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
246 cpArbiterFree(cpArbiter *arb)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
247 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
248 if(arb){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
249 cpArbiterDestroy(arb);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
250 cpfree(arb);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
251 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
252 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
253
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
254 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
255 cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, cpCollisionHandler *handler, cpShape *a, cpShape *b)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
256 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
257 // Arbiters without contact data may exist if a collision function rejected the collision.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
258 if(arb.contacts){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
259 // Iterate over the possible pairs to look for hash value matches.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
260 for(int i=0; i<arb.numContacts; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
261 cpContact *old = &arb.contacts[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
262
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
263 for(int j=0; j<numContacts; j++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
264 cpContact *new_contact = &contacts[j];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
265
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
266 // This could trigger false positives, but is fairly unlikely nor serious if it does.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
267 if(new_contact.hash == old.hash){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
268 // Copy the persistant contact information.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
269 new_contact.jnAcc = old.jnAcc;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
270 new_contact.jtAcc = old.jtAcc;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
271 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
272 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
273 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
274
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
275 // cpfree(arb.contacts);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
276 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
277
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
278 arb.contacts = contacts;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
279 arb.numContacts = numContacts;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
280
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
281 arb.handler = handler;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
282 arb.swappedColl = (a.collision_type != handler.a);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
283
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
284 arb.e = a.e * b.e;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
285 arb.u = a.u * b.u;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
286 arb.surface_vr = cpvsub(a.surface_v, b.surface_v);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
287
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
288 // For collisions between two similar primitive types, the order could have been swapped.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
289 arb.private_a = a;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
290 arb.private_b = b;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
291
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
292 // mark it as new if it's been cached
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
293 if(arb.state == cpArbiterState.cpArbiterStateCached) arb.state = cpArbiterState.cpArbiterStateFirstColl;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
294 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
295
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
296 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
297 cpArbiterPreStep(cpArbiter *arb, cpFloat dt_inv)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
298 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
299 cpBody *a = arb.private_a._body;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
300 cpBody *b = arb.private_b._body;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
301
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
302 for(int i=0; i<arb.numContacts; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
303 cpContact *con = &arb.contacts[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
304
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
305 // Calculate the offsets.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
306 con.r1 = cpvsub(con.p, a.p);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
307 con.r2 = cpvsub(con.p, b.p);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
308
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
309 // Calculate the mass normal and mass tangent.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
310 con.nMass = 1.0f/k_scalar(a, b, con.r1, con.r2, con.n);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
311 con.tMass = 1.0f/k_scalar(a, b, con.r1, con.r2, cpvperp(con.n));
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
312
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
313 // Calculate the target bias velocity.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
314 con.bias = -cp_bias_coef*dt_inv*cpfmin(0.0f, con.dist + cp_collision_slop);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
315 con.jBias = 0.0f;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
316
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
317 // Calculate the target bounce velocity.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
318 con.bounce = normal_relative_velocity(a, b, con.r1, con.r2, con.n)*arb.e;//cpvdot(con.n, cpvsub(v2, v1))*e;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
319 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
320 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
321
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
322 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
323 cpArbiterApplyCachedImpulse(cpArbiter *arb)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
324 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
325 cpShape *shapea = arb.private_a;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
326 cpShape *shapeb = arb.private_b;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
327
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
328 arb.u = shapea.u * shapeb.u;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
329 arb.surface_vr = cpvsub(shapeb.surface_v, shapea.surface_v);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
330
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
331 cpBody *a = shapea._body;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
332 cpBody *b = shapeb._body;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
333
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
334 for(int i=0; i<arb.numContacts; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
335 cpContact *con = &arb.contacts[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
336 apply_impulses(a, b, con.r1, con.r2, cpvrotate(con.n, cpv(con.jnAcc, con.jtAcc)));
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
337 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
338 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
339
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
340 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
341 cpArbiterApplyImpulse(cpArbiter *arb, cpFloat eCoef)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
342 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
343 cpBody *a = arb.private_a._body;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
344 cpBody *b = arb.private_b._body;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
345
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
346 for(int i=0; i<arb.numContacts; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
347 cpContact *con = &arb.contacts[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
348 cpVect n = con.n;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
349 cpVect r1 = con.r1;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
350 cpVect r2 = con.r2;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
351
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
352 // Calculate the relative bias velocities.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
353 cpVect vb1 = cpvadd(a.v_bias, cpvmult(cpvperp(r1), a.w_bias));
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
354 cpVect vb2 = cpvadd(b.v_bias, cpvmult(cpvperp(r2), b.w_bias));
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
355 cpFloat vbn = cpvdot(cpvsub(vb2, vb1), n);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
356
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
357 // Calculate and clamp the bias impulse.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
358 cpFloat jbn = (con.bias - vbn)*con.nMass;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
359 cpFloat jbnOld = con.jBias;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
360 con.jBias = cpfmax(jbnOld + jbn, 0.0f);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
361 jbn = con.jBias - jbnOld;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
362
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
363 // Apply the bias impulse.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
364 apply_bias_impulses(a, b, r1, r2, cpvmult(n, jbn));
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
365
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
366 // Calculate the relative velocity.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
367 cpVect vr = relative_velocity(a, b, r1, r2);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
368 cpFloat vrn = cpvdot(vr, n);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
369
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
370 // Calculate and clamp the normal impulse.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
371 cpFloat jn = -(con.bounce*eCoef + vrn)*con.nMass;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
372 cpFloat jnOld = con.jnAcc;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
373 con.jnAcc = cpfmax(jnOld + jn, 0.0f);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
374 jn = con.jnAcc - jnOld;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
375
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
376 // Calculate the relative tangent velocity.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
377 cpFloat vrt = cpvdot(cpvadd(vr, arb.surface_vr), cpvperp(n));
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
378
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
379 // Calculate and clamp the friction impulse.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
380 cpFloat jtMax = arb.u*con.jnAcc;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
381 cpFloat jt = -vrt*con.tMass;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
382 cpFloat jtOld = con.jtAcc;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
383 con.jtAcc = cpfclamp(jtOld + jt, -jtMax, jtMax);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
384 jt = con.jtAcc - jtOld;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
385
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
386 // Apply the final impulse.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
387 apply_impulses(a, b, r1, r2, cpvrotate(n, cpv(jn, jt)));
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
388 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
389 }