Mercurial > projects > chipmunkd
diff trunk/chipmunkd/constraints/cpSlideJoint.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/chipmunkd/constraints/cpSlideJoint.d Thu Dec 02 22:26:04 2010 +0100 @@ -0,0 +1,137 @@ + +// written in the D programming language + +module chipmunkd.constraints.cpSlideJoint; + +import chipmunkd.chipmunk; +import chipmunkd.constraints.util; + +//const cpConstraintClass *cpSlideJointGetClass(); + +struct cpSlideJoint { + cpConstraint constraint; + cpVect anchr1, anchr2; + cpFloat min, max; + + cpVect r1, r2; + cpVect n; + cpFloat nMass; + + cpFloat jnAcc, jnMax; + cpFloat bias; +} + +//cpSlideJoint *cpSlideJointAlloc(void); +//cpSlideJoint *cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max); +//cpConstraint *cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max); +// +//CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr1, Anchr1); +//CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr2, Anchr2); +//CP_DefineConstraintProperty(cpSlideJoint, cpFloat, min, Min); +//CP_DefineConstraintProperty(cpSlideJoint, cpFloat, max, Max); + +// cpSlideJoint.c --------------------------------- + +static void +preStep(cpSlideJoint *joint, cpFloat dt, cpFloat dt_inv) +{ + mixin(CONSTRAINT_BEGIN!("joint", "a", "b")); + + joint.r1 = cpvrotate(joint.anchr1, a.rot); + joint.r2 = cpvrotate(joint.anchr2, b.rot); + + cpVect delta = cpvsub(cpvadd(b.p, joint.r2), cpvadd(a.p, joint.r1)); + cpFloat dist = cpvlength(delta); + cpFloat pdist = 0.0f; + if(dist > joint.max) { + pdist = dist - joint.max; + } else if(dist < joint.min) { + pdist = joint.min - dist; + dist = -dist; + } + joint.n = cpvmult(delta, 1.0f/(dist ? dist : cast(cpFloat)INFINITY)); + + // calculate mass normal + joint.nMass = 1.0f/k_scalar(a, b, joint.r1, joint.r2, joint.n); + + // calculate bias velocity + cpFloat maxBias = joint.constraint.maxBias; + joint.bias = cpfclamp(-joint.constraint.biasCoef*dt_inv*(pdist), -maxBias, maxBias); + + // compute max impulse + joint.jnMax = mixin(J_MAX!("joint", "dt")); + + // apply accumulated impulse + if(!joint.bias) //{ + // if bias is 0, then the joint is not at a limit. + joint.jnAcc = 0.0f; +// } else { + cpVect j = cpvmult(joint.n, joint.jnAcc); + apply_impulses(a, b, joint.r1, joint.r2, j); +// } +} + +static void +applyImpulse(cpSlideJoint *joint) +{ + if(!joint.bias) return; // early exit + + mixin(CONSTRAINT_BEGIN!("joint", "a", "b")); + + cpVect n = joint.n; + cpVect r1 = joint.r1; + cpVect r2 = joint.r2; + + // compute relative velocity + cpVect vr = relative_velocity(a, b, r1, r2); + cpFloat vrn = cpvdot(vr, n); + + // compute normal impulse + cpFloat jn = (joint.bias - vrn)*joint.nMass; + cpFloat jnOld = joint.jnAcc; + joint.jnAcc = cpfclamp(jnOld + jn, -joint.jnMax, 0.0f); + jn = joint.jnAcc - jnOld; + + // apply impulse + apply_impulses(a, b, joint.r1, joint.r2, cpvmult(n, jn)); +} + +static cpFloat +getImpulse(cpConstraint *joint) +{ + return cpfabs((cast(cpSlideJoint *)joint).jnAcc); +} + +static /+const+/ cpConstraintClass klass = { + cast(cpConstraintPreStepFunction)&preStep, + cast(cpConstraintApplyImpulseFunction)&applyImpulse, + cast(cpConstraintGetImpulseFunction)&getImpulse, +}; +mixin(CP_DefineClassGetter!("cpSlideJoint")); + +cpSlideJoint * +cpSlideJointAlloc() +{ + return cast(cpSlideJoint *)cpmalloc(cpSlideJoint.sizeof); +} + +cpSlideJoint * +cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max) +{ + cpConstraintInit(cast(cpConstraint *)joint, &klass, a, b); + + joint.anchr1 = anchr1; + joint.anchr2 = anchr2; + joint.min = min; + joint.max = max; + + joint.jnAcc = 0.0f; + + return joint; +} + +cpConstraint * +cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max) +{ + return cast(cpConstraint *)cpSlideJointInit(cpSlideJointAlloc(), a, b, anchr1, anchr2, min, max); +} \ No newline at end of file