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