Mercurial > projects > chipmunkd
comparison trunk/chipmunkd/constraints/cpGrooveJoint.d @ 6:707dd4e10c28
ported rest of the constraints (chipmunk 5.3.2)
author | Extrawurst |
---|---|
date | Thu, 02 Dec 2010 22:26:04 +0100 |
parents | |
children | b68f10432182 |
comparison
equal
deleted
inserted
replaced
5:6dd4bcf20f03 | 6:707dd4e10c28 |
---|---|
1 | |
2 // written in the D programming language | |
3 | |
4 module chipmunkd.constraints.cpGrooveJoint; | |
5 | |
6 import chipmunkd.chipmunk; | |
7 import chipmunkd.constraints.util; | |
8 | |
9 //const cpConstraintClass *cpGrooveJointGetClass(); | |
10 | |
11 struct cpGrooveJoint { | |
12 cpConstraint constraint; | |
13 cpVect grv_n, grv_a, grv_b; | |
14 cpVect anchr2; | |
15 | |
16 cpVect grv_tn; | |
17 cpFloat clamp; | |
18 cpVect r1, r2; | |
19 cpVect k1, k2; | |
20 | |
21 cpVect jAcc; | |
22 cpFloat jMaxLen; | |
23 cpVect bias; | |
24 } | |
25 | |
26 //cpGrooveJoint *cpGrooveJointAlloc(void); | |
27 //cpGrooveJoint *cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2); | |
28 //cpConstraint *cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2); | |
29 // | |
30 // | |
31 //CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_a, GrooveA); | |
32 //void cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect value); | |
33 //CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_b, GrooveB); | |
34 //void cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect value); | |
35 //CP_DefineConstraintProperty(cpGrooveJoint, cpVect, anchr2, Anchr2); | |
36 | |
37 // cpGrooveJoint.c --------------------------------- | |
38 | |
39 static void | |
40 preStep(cpGrooveJoint *joint, cpFloat dt, cpFloat dt_inv) | |
41 { | |
42 mixin(CONSTRAINT_BEGIN!("joint", "a", "b")); | |
43 | |
44 // calculate endpoints in worldspace | |
45 cpVect ta = cpBodyLocal2World(a, joint.grv_a); | |
46 cpVect tb = cpBodyLocal2World(a, joint.grv_b); | |
47 | |
48 // calculate axis | |
49 cpVect n = cpvrotate(joint.grv_n, a.rot); | |
50 cpFloat d = cpvdot(ta, n); | |
51 | |
52 joint.grv_tn = n; | |
53 joint.r2 = cpvrotate(joint.anchr2, b.rot); | |
54 | |
55 // calculate tangential distance along the axis of r2 | |
56 cpFloat td = cpvcross(cpvadd(b.p, joint.r2), n); | |
57 // calculate clamping factor and r2 | |
58 if(td <= cpvcross(ta, n)){ | |
59 joint.clamp = 1.0f; | |
60 joint.r1 = cpvsub(ta, a.p); | |
61 } else if(td >= cpvcross(tb, n)){ | |
62 joint.clamp = -1.0f; | |
63 joint.r1 = cpvsub(tb, a.p); | |
64 } else { | |
65 joint.clamp = 0.0f; | |
66 joint.r1 = cpvsub(cpvadd(cpvmult(cpvperp(n), -td), cpvmult(n, d)), a.p); | |
67 } | |
68 | |
69 // Calculate mass tensor | |
70 k_tensor(a, b, joint.r1, joint.r2, &joint.k1, &joint.k2); | |
71 | |
72 // compute max impulse | |
73 joint.jMaxLen = mixin(J_MAX!("joint", "dt")); | |
74 | |
75 // calculate bias velocity | |
76 cpVect delta = cpvsub(cpvadd(b.p, joint.r2), cpvadd(a.p, joint.r1)); | |
77 joint.bias = cpvclamp(cpvmult(delta, -joint.constraint.biasCoef*dt_inv), joint.constraint.maxBias); | |
78 | |
79 // apply accumulated impulse | |
80 apply_impulses(a, b, joint.r1, joint.r2, joint.jAcc); | |
81 } | |
82 | |
83 static cpVect | |
84 grooveConstrain(cpGrooveJoint *joint, cpVect j){ | |
85 cpVect n = joint.grv_tn; | |
86 cpVect jClamp = (joint.clamp*cpvcross(j, n) > 0.0f) ? j : cpvproject(j, n); | |
87 return cpvclamp(jClamp, joint.jMaxLen); | |
88 } | |
89 | |
90 static void | |
91 applyImpulse(cpGrooveJoint *joint) | |
92 { | |
93 mixin(CONSTRAINT_BEGIN!("joint", "a", "b")); | |
94 | |
95 cpVect r1 = joint.r1; | |
96 cpVect r2 = joint.r2; | |
97 | |
98 // compute impulse | |
99 cpVect vr = relative_velocity(a, b, r1, r2); | |
100 | |
101 cpVect j = mult_k(cpvsub(joint.bias, vr), joint.k1, joint.k2); | |
102 cpVect jOld = joint.jAcc; | |
103 joint.jAcc = grooveConstrain(joint, cpvadd(jOld, j)); | |
104 j = cpvsub(joint.jAcc, jOld); | |
105 | |
106 // apply impulse | |
107 apply_impulses(a, b, joint.r1, joint.r2, j); | |
108 } | |
109 | |
110 static cpFloat | |
111 getImpulse(cpGrooveJoint *joint) | |
112 { | |
113 return cpvlength(joint.jAcc); | |
114 } | |
115 | |
116 static /+const+/ cpConstraintClass klass = { | |
117 cast(cpConstraintPreStepFunction)&preStep, | |
118 cast(cpConstraintApplyImpulseFunction)&applyImpulse, | |
119 cast(cpConstraintGetImpulseFunction)&getImpulse, | |
120 }; | |
121 mixin(CP_DefineClassGetter!("cpGrooveJoint")); | |
122 | |
123 cpGrooveJoint * | |
124 cpGrooveJointAlloc() | |
125 { | |
126 return cast(cpGrooveJoint *)cpmalloc(cpGrooveJoint.sizeof); | |
127 } | |
128 | |
129 cpGrooveJoint * | |
130 cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2) | |
131 { | |
132 cpConstraintInit(cast(cpConstraint *)joint, &klass, a, b); | |
133 | |
134 joint.grv_a = groove_a; | |
135 joint.grv_b = groove_b; | |
136 joint.grv_n = cpvperp(cpvnormalize(cpvsub(groove_b, groove_a))); | |
137 joint.anchr2 = anchr2; | |
138 | |
139 joint.jAcc = cpvzero; | |
140 | |
141 return joint; | |
142 } | |
143 | |
144 cpConstraint * | |
145 cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2) | |
146 { | |
147 return cast(cpConstraint *)cpGrooveJointInit(cpGrooveJointAlloc(), a, b, groove_a, groove_b, anchr2); | |
148 } | |
149 | |
150 void | |
151 cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect value) | |
152 { | |
153 cpGrooveJoint *g = cast(cpGrooveJoint *)constraint; | |
154 //TODO: | |
155 //cpConstraintCheckCast(constraint, cpGrooveJoint); | |
156 | |
157 g.grv_a = value; | |
158 g.grv_n = cpvperp(cpvnormalize(cpvsub(g.grv_b, value))); | |
159 | |
160 cpConstraintActivateBodies(constraint); | |
161 } | |
162 | |
163 void | |
164 cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect value) | |
165 { | |
166 cpGrooveJoint *g = cast(cpGrooveJoint *)constraint; | |
167 //TODO: | |
168 //cpConstraintCheckCast(constraint, cpGrooveJoint); | |
169 | |
170 g.grv_b = value; | |
171 g.grv_n = cpvperp(cpvnormalize(cpvsub(value, g.grv_a))); | |
172 | |
173 cpConstraintActivateBodies(constraint); | |
174 } | |
175 |