00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #define CP_DefineClassGetter(t) const cpConstraintClass * t##GetClass(void){return (cpConstraintClass *)&klass;}
00027
00028 void cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b);
00029
00030 static inline cpVect
00031 relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){
00032 cpVect v1_sum = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
00033 cpVect v2_sum = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
00034
00035 return cpvsub(v2_sum, v1_sum);
00036 }
00037
00038 static inline cpFloat
00039 normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){
00040 return cpvdot(relative_velocity(a, b, r1, r2), n);
00041 }
00042
00043 static inline void
00044 apply_impulse(cpBody *body, cpVect j, cpVect r){
00045 body->v = cpvadd(body->v, cpvmult(j, body->m_inv));
00046 body->w += body->i_inv*cpvcross(r, j);
00047 }
00048
00049 static inline void
00050 apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
00051 {
00052 apply_impulse(a, cpvneg(j), r1);
00053 apply_impulse(b, j, r2);
00054 }
00055
00056 static inline void
00057 apply_bias_impulse(cpBody *body, cpVect j, cpVect r)
00058 {
00059 body->CP_PRIVATE(v_bias) = cpvadd(body->CP_PRIVATE(v_bias), cpvmult(j, body->m_inv));
00060 body->CP_PRIVATE(w_bias) += body->i_inv*cpvcross(r, j);
00061 }
00062
00063 static inline void
00064 apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
00065 {
00066 apply_bias_impulse(a, cpvneg(j), r1);
00067 apply_bias_impulse(b, j, r2);
00068 }
00069
00070 static inline cpFloat
00071 k_scalar_body(cpBody *body, cpVect r, cpVect n)
00072 {
00073 cpFloat rcn = cpvcross(r, n);
00074 return body->m_inv + body->i_inv*rcn*rcn;
00075 }
00076
00077 static inline cpFloat
00078 k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)
00079 {
00080 cpFloat value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
00081 cpAssertSoft(value != 0.0, "Unsolvable collision or constraint.");
00082
00083 return value;
00084 }
00085
00086 static inline cpMat2x2
00087 k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2)
00088 {
00089 cpFloat m_sum = a->m_inv + b->m_inv;
00090
00091
00092 cpFloat k11 = m_sum, k12 = 0.0f;
00093 cpFloat k21 = 0.0f, k22 = m_sum;
00094
00095
00096 cpFloat a_i_inv = a->i_inv;
00097 cpFloat r1xsq = r1.x * r1.x * a_i_inv;
00098 cpFloat r1ysq = r1.y * r1.y * a_i_inv;
00099 cpFloat r1nxy = -r1.x * r1.y * a_i_inv;
00100 k11 += r1ysq; k12 += r1nxy;
00101 k21 += r1nxy; k22 += r1xsq;
00102
00103
00104 cpFloat b_i_inv = b->i_inv;
00105 cpFloat r2xsq = r2.x * r2.x * b_i_inv;
00106 cpFloat r2ysq = r2.y * r2.y * b_i_inv;
00107 cpFloat r2nxy = -r2.x * r2.y * b_i_inv;
00108 k11 += r2ysq; k12 += r2nxy;
00109 k21 += r2nxy; k22 += r2xsq;
00110
00111
00112 cpFloat det = k11*k22 - k12*k21;
00113 cpAssertSoft(det != 0.0, "Unsolvable constraint.");
00114
00115 cpFloat det_inv = 1.0f/det;
00116 return cpMat2x2New(
00117 k22*det_inv, -k12*det_inv,
00118 -k21*det_inv, k11*det_inv
00119 );
00120 }
00121
00122 static inline cpFloat
00123 bias_coef(cpFloat errorBias, cpFloat dt)
00124 {
00125 return 1.0f - cpfpow(errorBias, dt);
00126 }