示例#1
0
static void
preStep(cpSlideJoint *joint, cpFloat dt, cpFloat dt_inv)
{
    cpBody *a = joint->constraint.a;
    cpBody *b = joint->constraint.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 : (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 = 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);
//	}
}
示例#2
0
static void
preStep(cpRatchetJoint *joint, cpFloat dt, cpFloat dt_inv)
{
	cpBody *a = joint->constraint.a;
	cpBody *b = joint->constraint.b;
	
	cpFloat angle = joint->angle;
	cpFloat phase = joint->phase;
	cpFloat ratchet = joint->ratchet;
	
	cpFloat delta = b->a - a->a;
	cpFloat diff = angle - delta;
	cpFloat pdist = 0.0f;
	
	if(diff*ratchet > 0.0f){
		pdist = diff;
	} else {
		joint->angle = cpffloor((delta - phase)/ratchet)*ratchet + phase;
	}
	
	// calculate moment of inertia coefficient.
	joint->iSum = 1.0f/(a->i_inv + b->i_inv);
	
	// calculate bias velocity
	cpFloat maxBias = joint->constraint.maxBias;
	joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*pdist, -maxBias, maxBias);
	
	// compute max impulse
	joint->jMax = J_MAX(joint, dt);

	// If the bias is 0, the joint is not at a limit. Reset the impulse.
	if(!joint->bias)
		joint->jAcc = 0.0f;

	// apply joint torque
	a->w -= joint->jAcc*a->i_inv;
	b->w += joint->jAcc*b->i_inv;
}
示例#3
0
static void
preStep(cpPinJoint *joint, cpFloat dt)
{
    cpBody *a = joint->constraint.a;
    cpBody *b = joint->constraint.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);
    joint->n = cpvmult(delta, 1.0f/(dist ? dist : (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(-bias_coef(joint->constraint.errorBias, dt)*(dist - joint->dist)/dt, -maxBias, maxBias);
    
    // compute max impulse
    joint->jnMax = J_MAX(joint, dt);
}
static void
preStep(cpRotaryLimitJoint *joint, cpFloat dt)
{
	cpBody *a = joint->constraint.a;
	cpBody *b = joint->constraint.b;
	
	cpFloat dist = b->a - a->a;
	cpFloat pdist = 0.0f;
	if(dist > joint->max) {
		pdist = joint->max - dist;
	} else if(dist < joint->min) {
		pdist = joint->min - dist;
	}
	
	// calculate moment of inertia coefficient.
	joint->iSum = 1.0f/(1.0f/a->i + 1.0f/b->i);
	
	// calculate bias velocity
	cpFloat maxBias = joint->constraint.maxBias;
	joint->bias = cpfclamp(-bias_coef(joint->constraint.errorBias, dt)*pdist/dt, -maxBias, maxBias);

	// If the bias is 0, the joint is not at a limit. Reset the impulse.
	if(!joint->bias) joint->jAcc = 0.0f;
}
示例#5
0
static void
applyImpulse(cpSlideJoint *joint)
{
	if(!joint->bias) return;  // early exit

	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));
}
示例#6
0
static void
applyImpulse(cpRatchetJoint *joint, cpFloat dt)
{
	if(!joint->bias) return; // early exit

	cpBody *a = joint->constraint.a;
	cpBody *b = joint->constraint.b;
	
	// compute relative rotational velocity
	cpFloat wr = b->w - a->w;
	cpFloat ratchet = joint->ratchet;
	
	cpFloat jMax = joint->constraint.maxForce*dt;
	
	// compute normal impulse	
	cpFloat j = -(joint->bias + wr)*joint->iSum;
	cpFloat jOld = joint->jAcc;
	joint->jAcc = cpfclamp((jOld + j)*ratchet, 0.0f, jMax*cpfabs(ratchet))/ratchet;
	j = joint->jAcc - jOld;
	
	// apply impulse
	a->w -= j*a->i_inv;
	b->w += j*b->i_inv;
}
示例#7
0
// Find the closest p(t) to (0, 0) where p(t) = a*(1-t)/2 + b*(1+t)/2
// The range for t is [-1, 1] to avoid floating point issues if the parameters are swapped.
static inline cpFloat
ClosestT(const cpVect a, const cpVect b)
{
    cpVect delta = cpvsub(b, a);
    return -cpfclamp(cpvdot(delta, cpvadd(a, b))/cpvlengthsq(delta), -1.0f, 1.0f);
}
示例#8
0
static cpFloat
springForce(cpConstraint *spring, cpFloat dist)
{
	cpFloat clamp = 20.0f;
	return cpfclamp(cpDampedSpringGetRestLength(spring) - dist, -clamp, clamp)*cpDampedSpringGetStiffness(spring);
}
示例#9
0
static VALUE
rb_cpfclamp(VALUE self, VALUE f, VALUE min, VALUE max) {
  cpFloat result = cpfclamp(NUM2DBL(f), NUM2DBL(min), NUM2DBL(max));
  return rb_float_new(result);
}