13 typedef struct Contact Contact;
21 enum { CTSBLOCK = 64 };
27 colldect(Obj *a, Obj *b)
36 for(i = 0; i < ap->nvert; i++){
39 for(j = 0; j < bp->nvert; j++){
42 d = -(z->x - x->x) * (y->y - x->y) + (z->y - x->y) * (y->x - x->x);
44 if(d < -Slop) goto next;
49 cts = realloc(cts, sizeof(Contact) * (ncts += CTSBLOCK));
50 cts[icts] = (Contact){a, b, *z, vecnormal(vecsub(*x, *y)), d, 0, 0, 0};
51 }else if(d < 0) goto next;
62 Vec n, t, u, r0, r1, Δp;
63 double ut, un, α, γ, γt, γn, pt, mt, mn;
64 double r0n, r0t, r1n, r1t;
65 double mv, me, Iv, Ie;
69 mv = p->vo->tab->imass;
70 me = p->eo->tab->imass;
71 Iv = mv * p->vo->poly->invI;
72 Ie = me * p->eo->poly->invI;
73 r0 = vecsub(p->v, p->vo->p);
74 r1 = vecsub(p->v, p->eo->p);
75 Δp.x = -(t.x * p->impt + n.x * p->impn);
76 Δp.y = -(t.y * p->impt + n.y * p->impn);
77 p->vo->v = vecadd(p->vo->v, vecmul(Δp, mv));
78 p->vo->ω -= (Δp.x * r0.y - Δp.y * r0.x) * Iv;
79 p->eo->v = vecadd(p->eo->v, vecmul(Δp, -me));
80 p->eo->ω += (Δp.x * r1.y - Δp.y * r1.x) * Ie;
81 u.x = p->vo->v.x - p->vo->ω * r0.y - p->eo->v.x + p->eo->ω * r1.y;
82 u.y = p->vo->v.y + p->vo->ω * r0.x - p->eo->v.y - p->eo->ω * r1.x;
89 γ = 0; /* accumulated normal impulse */
90 pt = 0; /* accumulated transverse impulse */
95 if(un >= 0 && p->pen <= 0){
101 un -= Beta * p->pen / Dt;
103 mn = mv + r0t * r0t * Iv;
104 mn += me + r1t * r1t * Ie;
110 /* calculate α, the effective coefficient of friction */
112 α = r0t * r0n * Iv + r1t * r1n * Ie;
113 α /= mv + r0n * r0n * Iv + me + r1n * r1n * Ie;
115 else if(α < -μs) α = -μd;
117 α = ut < 0 ? μd : -μd;
119 mt = α * mv + (r0n * r0n * α - r0t * r0n) * Iv;
120 mt += α * me + (r1n * r1n * α - r1t * r1n) * Ie;
121 mn = mv + (r0t * r0t - r0n * r0t * α) * Iv;
122 mn += me + (r1t * r1t - r1n * r1t * α) * Ie;
123 /* determine events which would change α */
124 if(ut == 0) γt = Inf(1);
127 if(γt < γ) γt = Inf(1);
130 if(γn < γ) γn = Inf(1);
131 /* choose earlier one */
148 Δp.x = t.x * pt + n.x * γ;
149 Δp.y = t.y * pt + n.y * γ;
150 p->vo->v = vecadd(p->vo->v, vecmul(Δp, mv));
151 p->vo->ω -= (Δp.x * r0.y - Δp.y * r0.x) * Iv;
152 p->eo->v = vecadd(p->eo->v, vecmul(Δp, -me));
153 p->eo->ω += (Δp.x * r1.y - Δp.y * r1.x) * Ie;
156 extern Hinge *hinges;
163 double ma, mb, Ia, Ib;
164 double mxx, mxy, myy, det;
170 Ia = ma * a->poly->invI;
171 Ib = mb * b->poly->invI;
172 r0 = vecsub(h->p, a->p);
173 r1 = vecsub(h->cnext->p, b->p);
174 u.x = a->v.x - a->ω * r0.y - b->v.x + b->ω * r1.y;
175 u.y = a->v.y + a->ω * r0.x - b->v.y - b->ω * r1.x;
176 u.x += Beta * (h->p.x - h->cnext->p.x) / Dt;
177 u.y += Beta * (h->p.y - h->cnext->p.y) / Dt;
178 mxx = ma + Ia * r0.x * r0.x + mb + Ib * r1.x * r1.x;
179 mxy = Ia * r0.x * r0.y + Ib * r1.x * r1.y;
180 myy = ma + Ia * r0.y * r0.y + mb + Ib * r1.y * r1.y;
181 det = mxx * myy - mxy * mxy;
182 Δp.x = (mxx * u.x + mxy * u.y) / det;
183 Δp.y = (myy * u.y + mxy * u.x) / det;
184 a->v = vecadd(a->v, vecmul(Δp, -ma));
185 a->ω += (Δp.x * r0.y - Δp.y * r0.x) * Ia;
186 b->v = vecadd(b->v, vecmul(Δp, mb));
187 b->ω -= (Δp.x * r1.y - Δp.y * r1.x) * Ib;
188 u.x = a->v.x - a->ω * r0.y - b->v.x + b->ω * r1.y;
189 u.y = a->v.y + a->ω * r0.x - b->v.y - b->ω * r1.x;
199 for(k = 0; k < Steps; k++){
200 for(o = runo.next; o != &runo; o = o->next)
201 if(o->tab->imass != 0)
204 for(a = runo.next; a != &runo; a = a->next)
205 for(b = a->next; b != &runo; b = b->next){
206 if(!rectXrect(a->bbox, b->bbox) || a->poly == nil || b->poly == nil || hinged(a, b)) continue;
210 for(j = 0; j < 10; j++){
211 for(i = 0; i < icts; i++)
213 for(p = hinges; p != nil; p = p->anext)
216 for(o = runo.next; o != &runo; o = o->next)
217 o->tab->move(o, o->p.x + o->v.x * Dt, o->p.y + o->v.y * Dt, o->θ + o->ω * Dt / DEG);