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 #define J_MAX(constraint, dt) (((cpConstraint *)constraint)->maxForce*(dt))
00031
00032 static inline cpVect
00033 relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){
00034 cpVect v1_sum = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
00035 cpVect v2_sum = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
00036
00037 return cpvsub(v2_sum, v1_sum);
00038 }
00039
00040 static inline cpFloat
00041 normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){
00042 return cpvdot(relative_velocity(a, b, r1, r2), n);
00043 }
00044
00045 static inline void
00046 apply_impulse(cpBody *body, cpVect j, cpVect r){
00047 body->v = cpvadd(body->v, cpvmult(j, body->m_inv));
00048 body->w += body->i_inv*cpvcross(r, j);
00049 }
00050
00051 static inline void
00052 apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
00053 {
00054 apply_impulse(a, cpvneg(j), r1);
00055 apply_impulse(b, j, r2);
00056 }
00057
00058 static inline void
00059 apply_bias_impulse(cpBody *body, cpVect j, cpVect r)
00060 {
00061 body->CP_PRIVATE(v_bias) = cpvadd(body->CP_PRIVATE(v_bias), cpvmult(j, body->m_inv));
00062 body->CP_PRIVATE(w_bias) += body->i_inv*cpvcross(r, j);
00063 }
00064
00065 static inline void
00066 apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
00067 {
00068 apply_bias_impulse(a, cpvneg(j), r1);
00069 apply_bias_impulse(b, j, r2);
00070 }
00071
00072 static inline cpFloat
00073 k_scalar_body(cpBody *body, cpVect r, cpVect n)
00074 {
00075 cpFloat rcn = cpvcross(r, n);
00076 return body->m_inv + body->i_inv*rcn*rcn;
00077 }
00078
00079 static inline cpFloat
00080 k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)
00081 {
00082 cpFloat value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
00083 cpAssertSoft(value != 0.0, "Unsolvable collision or constraint.");
00084
00085 return value;
00086 }
00087
00088 static inline void
00089 k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect *k1, cpVect *k2)
00090 {
00091
00092
00093 cpFloat k11, k12, k21, k22;
00094 cpFloat m_sum = a->m_inv + b->m_inv;
00095
00096
00097 k11 = m_sum; k12 = 0.0f;
00098 k21 = 0.0f; k22 = m_sum;
00099
00100
00101 cpFloat a_i_inv = a->i_inv;
00102 cpFloat r1xsq = r1.x * r1.x * a_i_inv;
00103 cpFloat r1ysq = r1.y * r1.y * a_i_inv;
00104 cpFloat r1nxy = -r1.x * r1.y * a_i_inv;
00105 k11 += r1ysq; k12 += r1nxy;
00106 k21 += r1nxy; k22 += r1xsq;
00107
00108
00109 cpFloat b_i_inv = b->i_inv;
00110 cpFloat r2xsq = r2.x * r2.x * b_i_inv;
00111 cpFloat r2ysq = r2.y * r2.y * b_i_inv;
00112 cpFloat r2nxy = -r2.x * r2.y * b_i_inv;
00113 k11 += r2ysq; k12 += r2nxy;
00114 k21 += r2nxy; k22 += r2xsq;
00115
00116
00117 cpFloat determinant = k11*k22 - k12*k21;
00118 cpAssertSoft(determinant != 0.0, "Unsolvable constraint.");
00119
00120 cpFloat det_inv = 1.0f/determinant;
00121 *k1 = cpv( k22*det_inv, -k12*det_inv);
00122 *k2 = cpv(-k21*det_inv, k11*det_inv);
00123 }
00124
00125 static inline cpVect
00126 mult_k(cpVect vr, cpVect k1, cpVect k2)
00127 {
00128 return cpv(cpvdot(vr, k1), cpvdot(vr, k2));
00129 }
00130
00131 static inline cpFloat
00132 bias_coef(cpFloat errorBias, cpFloat dt)
00133 {
00134 return 1.0f - cpfpow(errorBias, dt);
00135 }