Пример #1
0
void b2PulleyJoint::SolveVelocityConstraints(const b2TimeStep& step)
{
	b2Body* b1 = m_body1;
	b2Body* b2 = m_body2;

	b2Vec2 r1 = b2Mul(b1->GetXForm().R, m_localAnchor1 - b1->GetLocalCenter());
	b2Vec2 r2 = b2Mul(b2->GetXForm().R, m_localAnchor2 - b2->GetLocalCenter());

	if (m_state == e_atUpperLimit)
	{
		b2Vec2 v1 = b1->m_linearVelocity + b2Cross(b1->m_angularVelocity, r1);
		b2Vec2 v2 = b2->m_linearVelocity + b2Cross(b2->m_angularVelocity, r2);

		float32 Cdot = -b2Dot(m_u1, v1) - m_ratio * b2Dot(m_u2, v2);
		float32 force = -B2FORCE_INV_SCALE(step.inv_dt) * m_pulleyMass * Cdot;
		float32 oldForce = m_force;
		m_force = b2Max(0.0f, m_force + force);
		force = m_force - oldForce;

		b2Vec2 P1 = -B2FORCE_SCALE(step.dt) * force * m_u1;
		b2Vec2 P2 = -B2FORCE_SCALE(step.dt) * m_ratio * force * m_u2;
		b1->m_linearVelocity += b1->m_invMass * P1;
		b1->m_angularVelocity += b1->m_invI * b2Cross(r1, P1);
		b2->m_linearVelocity += b2->m_invMass * P2;
		b2->m_angularVelocity += b2->m_invI * b2Cross(r2, P2);
	}

	if (m_limitState1 == e_atUpperLimit)
	{
		b2Vec2 v1 = b1->m_linearVelocity + b2Cross(b1->m_angularVelocity, r1);

		float32 Cdot = -b2Dot(m_u1, v1);
		float32 force = -B2FORCE_INV_SCALE(step.inv_dt) * m_limitMass1 * Cdot;
		float32 oldForce = m_limitForce1;
		m_limitForce1 = b2Max(0.0f, m_limitForce1 + force);
		force = m_limitForce1 - oldForce;

		b2Vec2 P1 = -B2FORCE_SCALE(step.dt) * force * m_u1;
		b1->m_linearVelocity += b1->m_invMass * P1;
		b1->m_angularVelocity += b1->m_invI * b2Cross(r1, P1);
	}

	if (m_limitState2 == e_atUpperLimit)
	{
		b2Vec2 v2 = b2->m_linearVelocity + b2Cross(b2->m_angularVelocity, r2);

		float32 Cdot = -b2Dot(m_u2, v2);
		float32 force = -B2FORCE_INV_SCALE(step.inv_dt) * m_limitMass2 * Cdot;
		float32 oldForce = m_limitForce2;
		m_limitForce2 = b2Max(0.0f, m_limitForce2 + force);
		force = m_limitForce2 - oldForce;

		b2Vec2 P2 = -B2FORCE_SCALE(step.dt) * force * m_u2;
		b2->m_linearVelocity += b2->m_invMass * P2;
		b2->m_angularVelocity += b2->m_invI * b2Cross(r2, P2);
	}
}
b2MouseJoint::b2MouseJoint(const b2MouseJointDef* def)
: b2Joint(def)
{
	m_target = def->target;
	m_localAnchor = b2MulT(m_body2->GetXForm(), m_target);

	m_maxForce = B2FORCE_INV_SCALE(def->maxForce);
	m_impulse.SetZero();

	float32 mass = m_body2->m_mass;

	// Frequency
	float32 omega = 2.0f * b2_pi * def->frequencyHz;

	// Damping coefficient
	float32 d = 2.0f * mass * def->dampingRatio * omega;

	// Spring stiffness
	float32 k = (def->timeStep * mass) * (omega * omega);

	// magic formulas
	b2Assert(d + k > B2_FLT_EPSILON);
	m_gamma = 1.0f / (d + k);
	m_beta = k / (d + k);
}
Пример #3
0
b2LineJoint::b2LineJoint(const b2LineJointDef* def)
: b2Joint(def)
{
	m_localAnchor1 = def->localAnchor1;
	m_localAnchor2 = def->localAnchor2;
	m_localXAxis1 = def->localAxis1;
	m_localYAxis1 = b2Cross(1.0f, m_localXAxis1);

	m_impulse.SetZero();
	m_motorMass = 0.0;
	m_motorImpulse = 0.0f;

	m_lowerTranslation = def->lowerTranslation;
	m_upperTranslation = def->upperTranslation;
	m_maxMotorForce = B2FORCE_INV_SCALE(def->maxMotorForce);
	m_motorSpeed = def->motorSpeed;
	m_enableLimit = def->enableLimit;
	m_enableMotor = def->enableMotor;
	m_limitState = e_inactiveLimit;

	m_axis.SetZero();
	m_perp.SetZero();
}
void b2MouseJoint::SolveVelocityConstraints(const b2TimeStep& step)
{
	b2Body* b = m_body2;

	b2Vec2 r = b2Mul(b->GetXForm().R, m_localAnchor - b->GetLocalCenter());

	// Cdot = v + cross(w, r)
	b2Vec2 Cdot = b->m_linearVelocity + b2Cross(b->m_angularVelocity, r);
	b2Vec2 force = -B2FORCE_INV_SCALE(step.inv_dt) * b2Mul(m_mass, Cdot + (m_beta * step.inv_dt) * m_C + B2FORCE_SCALE(step.dt) * (m_gamma * m_impulse));

	b2Vec2 oldForce = m_impulse;
	m_impulse += force;
	float32 forceMagnitude = m_impulse.Length();
	if (forceMagnitude > m_maxForce)
	{
		m_impulse *= m_maxForce / forceMagnitude;
	}
	force = m_impulse - oldForce;

	b2Vec2 P = B2FORCE_SCALE(step.dt) * force;
	b->m_linearVelocity += b->m_invMass * P;
	b->m_angularVelocity += b->m_invI * b2Cross(r, P);
}