public b2PolygonShape() { ShapeType = b2ShapeType.e_polygon; Radius = b2Settings.b2_polygonRadius; m_vertexCount = 0; Centroid.SetZero(); }
public b2FrictionJoint(b2FrictionJointDef def) : base(def) { m_localAnchorA = def.localAnchorA; m_localAnchorB = def.localAnchorB; m_linearImpulse.SetZero(); m_angularImpulse = 0.0f; m_maxForce = def.maxForce; m_maxTorque = def.maxTorque; }
public b2WheelJoint(b2WheelJointDef def) : base(def) { m_localAnchorA = def.localAnchorA; m_localAnchorB = def.localAnchorB; m_localXAxisA = def.localAxisA; m_localYAxisA = m_localXAxisA.NegUnitCross(); // m_localYAxisA = b2Math.b2Cross(1.0f, m_localXAxisA); m_mass = 0.0f; m_impulse = 0.0f; m_motorMass = 0.0f; m_motorImpulse = 0.0f; m_springMass = 0.0f; m_springImpulse = 0.0f; m_maxMotorTorque = def.maxMotorTorque; m_motorSpeed = def.motorSpeed; m_enableMotor = def.enableMotor; m_frequencyHz = def.frequencyHz; m_dampingRatio = def.dampingRatio; m_bias = 0.0f; m_gamma = 0.0f; m_ax.SetZero(); m_ay.SetZero(); }
public b2PrismaticJoint(b2PrismaticJointDef def) : base(def) { m_localAnchorA = def.localAnchorA; m_localAnchorB = def.localAnchorB; m_localXAxisA = def.localAxisA; m_localXAxisA.Normalize(); m_localYAxisA = m_localXAxisA.NegUnitCross(); // b2Math.b2Cross(1.0f, m_localXAxisA); m_referenceAngle = def.referenceAngle; m_impulse.SetZero(); m_motorMass = 0.0f; m_motorImpulse = 0.0f; m_lowerTranslation = def.lowerTranslation; m_upperTranslation = def.upperTranslation; m_maxMotorForce = def.maxMotorForce; m_motorSpeed = def.motorSpeed; m_enableLimit = def.enableLimit; m_enableMotor = def.enableMotor; m_limitState = b2LimitState.e_inactiveLimit; m_axis.SetZero(); m_perp.SetZero(); }
public b2MouseJoint(b2MouseJointDef def) : base(def) { Debug.Assert(def.target.IsValid()); Debug.Assert(b2Math.b2IsValid(def.maxForce) && def.maxForce >= 0.0f); Debug.Assert(b2Math.b2IsValid(def.frequencyHz) && def.frequencyHz >= 0.0f); Debug.Assert(b2Math.b2IsValid(def.dampingRatio) && def.dampingRatio >= 0.0f); m_targetA = def.target; m_localAnchorB = b2Math.b2MulT(m_bodyB.Transform, m_targetA); m_maxForce = def.maxForce; m_impulse.SetZero(); m_frequencyHz = def.frequencyHz; m_dampingRatio = def.dampingRatio; m_beta = 0.0f; m_gamma = 0.0f; }
public virtual void SetAwake(bool flag) { if (flag) { if ((m_flags & b2BodyFlags.e_awakeFlag) == 0) { m_flags |= b2BodyFlags.e_awakeFlag; m_sleepTime = 0.0f; } } else { m_flags &= ~b2BodyFlags.e_awakeFlag; m_sleepTime = 0.0f; m_linearVelocity.SetZero(); m_angularVelocity = 0.0f; m_force.SetZero(); m_torque = 0.0f; } }
public b2Rope() { m_count = 0; m_ps = null; m_p0s = null; m_vs = null; m_ims = null; m_Ls = null; m_as = null; m_gravity.SetZero(); m_k2 = 1.0f; m_k3 = 0.1f; }
public virtual void SetType(b2BodyType type) { if (World.IsLocked == true) { return; } if (BodyType == type) { return; } BodyType = type; ResetMassData(); if (BodyType == b2BodyType.b2_staticBody) { m_linearVelocity.SetZero(); m_angularVelocity = 0.0f; Sweep.a0 = Sweep.a; Sweep.c0 = Sweep.c; SynchronizeFixtures(); } SetAwake(true); Force.SetZero(); Torque = 0.0f; // Since the body type changed, we need to flag contacts for filtering. for (b2Fixture f = FixtureList; f != null; f = f.Next) { f.Refilter(); } }
public virtual b2CircleShape() { m_type = b2ShapeType.e_circle; m_radius = 0.0f; m_p.SetZero(); }
public b2Body(b2BodyDef bd, b2World world) { m_flags = 0; if (bd.bullet) { m_flags |= b2BodyFlags.e_bulletFlag; } if (bd.fixedRotation) { m_flags |= b2BodyFlags.e_fixedRotationFlag; } if (bd.allowSleep) { m_flags |= b2BodyFlags.e_autoSleepFlag; } if (bd.awake) { m_flags |= b2BodyFlags.e_awakeFlag; } if (bd.active) { m_flags |= b2BodyFlags.e_activeFlag; } m_world = world; m_xf.p = bd.position; m_xf.q.Set(bd.angle); Sweep.localCenter.SetZero(); Sweep.c0 = m_xf.p; Sweep.c = m_xf.p; Sweep.a0 = bd.angle; Sweep.a = bd.angle; Sweep.alpha0 = 0.0f; m_jointList = null; m_contactList = null; Prev = null; Next = null; m_linearVelocity = bd.linearVelocity; m_angularVelocity = bd.angularVelocity; m_linearDamping = bd.linearDamping; m_angularDamping = bd.angularDamping; m_gravityScale = bd.gravityScale; m_force.SetZero(); m_torque = 0.0f; m_sleepTime = 0.0f; m_type = bd.type; if (m_type == b2BodyType.b2_dynamicBody) { m_mass = 1.0f; m_invMass = 1.0f; } else { m_mass = 0.0f; m_invMass = 0.0f; } m_I = 0.0f; m_invI = 0.0f; m_userData = bd.userData; m_fixtureList = null; m_fixtureCount = 0; }
public void SetZero() { linearA.SetZero(); angularA = 0.0f; linearB.SetZero(); angularB = 0.0f; }
public override void InitVelocityConstraints(b2SolverData data) { m_indexA = m_bodyA.IslandIndex; m_indexB = m_bodyB.IslandIndex; m_localCenterA = m_bodyA.Sweep.localCenter; m_localCenterB = m_bodyB.Sweep.localCenter; m_invMassA = m_bodyA.InvertedMass; m_invMassB = m_bodyB.InvertedMass; m_invIA = m_bodyA.InvertedI; m_invIB = m_bodyB.InvertedI; b2Vec2 cA = data.positions[m_indexA].c; float aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; float wA = data.velocities[m_indexA].w; b2Vec2 cB = data.positions[m_indexB].c; float aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; float wB = data.velocities[m_indexB].w; b2Rot qA = new b2Rot(aA); b2Rot qB = new b2Rot(aB); m_rA = b2Math.b2Mul(qA, m_localAnchorA - m_localCenterA); m_rB = b2Math.b2Mul(qB, m_localAnchorB - m_localCenterB); m_u = cB + m_rB - cA - m_rA; m_length = m_u.Length(); float C = m_length - m_maxLength; if (C > 0.0f) { m_state = b2LimitState.e_atUpperLimit; } else { m_state = b2LimitState.e_inactiveLimit; } if (m_length > b2Settings.b2_linearSlop) { m_u *= 1.0f / m_length; } else { m_u.SetZero(); m_mass = 0.0f; m_impulse = 0.0f; return; } // Compute effective mass. float crA = b2Math.b2Cross(m_rA, m_u); float crB = b2Math.b2Cross(m_rB, m_u); float invMass = m_invMassA + m_invIA * crA * crA + m_invMassB + m_invIB * crB * crB; m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; if (data.step.warmStarting) { // Scale the impulse to support a variable time step. m_impulse *= data.step.dtRatio; b2Vec2 P = m_impulse * m_u; vA -= m_invMassA * P; wA -= m_invIA * b2Math.b2Cross(m_rA, P); vB += m_invMassB * P; wB += m_invIB * b2Math.b2Cross(m_rB, P); } else { m_impulse = 0.0f; } data.velocities[m_indexA].v = vA; data.velocities[m_indexA].w = wA; data.velocities[m_indexB].v = vB; data.velocities[m_indexB].w = wB; }
public b2GearJoint(b2GearJointDef def) : base(def) { m_joint1 = def.joint1; m_joint2 = def.joint2; m_typeA = m_joint1.GetJointType(); m_typeB = m_joint2.GetJointType(); Debug.Assert(m_typeA == b2JointType.e_revoluteJoint || m_typeA == b2JointType.e_prismaticJoint); Debug.Assert(m_typeB == b2JointType.e_revoluteJoint || m_typeB == b2JointType.e_prismaticJoint); float coordinateA, coordinateB; // TODO_ERIN there might be some problem with the joint edges in b2Joint. m_bodyC = m_joint1.GetBodyA(); m_bodyA = m_joint1.GetBodyB(); // Get geometry of joint1 b2Transform xfA = m_bodyA.XF; float aA = m_bodyA.Sweep.a; b2Transform xfC = m_bodyC.XF; float aC = m_bodyC.Sweep.a; if (m_typeA == b2JointType.e_revoluteJoint) { b2RevoluteJoint revolute = (b2RevoluteJoint)def.joint1; m_localAnchorC = revolute.GetLocalAnchorA(); m_localAnchorA = revolute.GetLocalAnchorB(); m_referenceAngleA = revolute.GetReferenceAngle(); m_localAxisC.SetZero(); coordinateA = aA - aC - m_referenceAngleA; } else { b2PrismaticJoint prismatic = (b2PrismaticJoint)def.joint1; m_localAnchorC = prismatic.GetLocalAnchorA(); m_localAnchorA = prismatic.GetLocalAnchorB(); m_referenceAngleA = prismatic.GetReferenceAngle(); m_localAxisC = prismatic.GetLocalXAxisA(); b2Vec2 pC = m_localAnchorC; b2Vec2 pA = b2Math.b2MulT(xfC.q, b2Math.b2Mul(xfA.q, m_localAnchorA) + (xfA.p - xfC.p)); coordinateA = b2Math.b2Dot(pA - pC, m_localAxisC); } m_bodyD = m_joint2.GetBodyA(); m_bodyB = m_joint2.GetBodyB(); // Get geometry of joint2 b2Transform xfB = m_bodyB.XF; float aB = m_bodyB.Sweep.a; b2Transform xfD = m_bodyD.XF; float aD = m_bodyD.Sweep.a; if (m_typeB == b2JointType.e_revoluteJoint) { b2RevoluteJoint revolute = (b2RevoluteJoint)def.joint2; m_localAnchorD = revolute.GetLocalAnchorA(); m_localAnchorB = revolute.GetLocalAnchorB(); m_referenceAngleB = revolute.GetReferenceAngle(); m_localAxisD.SetZero(); coordinateB = aB - aD - m_referenceAngleB; } else { b2PrismaticJoint prismatic = (b2PrismaticJoint)def.joint2; m_localAnchorD = prismatic.GetLocalAnchorA(); m_localAnchorB = prismatic.GetLocalAnchorB(); m_referenceAngleB = prismatic.GetReferenceAngle(); m_localAxisD = prismatic.GetLocalXAxisA(); b2Vec2 pD = m_localAnchorD; b2Vec2 pB = b2Math.b2MulT(xfD.q, b2Math.b2Mul(xfB.q, m_localAnchorB) + (xfB.p - xfD.p)); coordinateB = b2Math.b2Dot(pB - pD, m_localAxisD); } m_ratio = def.ratio; m_constant = coordinateA + m_ratio * coordinateB; m_impulse = 0.0f; }
public override bool SolvePositionConstraints(b2SolverData data) { b2Vec2 cA = m_bodyA.InternalPosition.c; float aA = m_bodyA.InternalPosition.a; b2Vec2 cB = m_bodyB.InternalPosition.c; float aB = m_bodyB.InternalPosition.a; b2Vec2 cC = m_bodyC.InternalPosition.c; float aC = m_bodyC.InternalPosition.a; b2Vec2 cD = m_bodyD.InternalPosition.c; float aD = m_bodyD.InternalPosition.a; b2Rot qA = new b2Rot(aA); b2Rot qB = new b2Rot(aB); b2Rot qC = new b2Rot(aC); b2Rot qD = new b2Rot(aD); float linearError = 0.0f; float coordinateA, coordinateB; b2Vec2 JvAC = b2Vec2.Zero, JvBD = b2Vec2.Zero; float JwA, JwB, JwC, JwD; float mass = 0.0f; if (m_typeA == b2JointType.e_revoluteJoint) { JvAC.SetZero(); JwA = 1.0f; JwC = 1.0f; mass += m_iA + m_iC; coordinateA = aA - aC - m_referenceAngleA; } else { b2Vec2 u = b2Math.b2Mul(qC, m_localAxisC); b2Vec2 rC = b2Math.b2Mul(qC, m_localAnchorC - m_lcC); b2Vec2 rA = b2Math.b2Mul(qA, m_localAnchorA - m_lcA); JvAC = u; JwC = b2Math.b2Cross(rC, u); JwA = b2Math.b2Cross(rA, u); mass += m_mC + m_mA + m_iC * JwC * JwC + m_iA * JwA * JwA; b2Vec2 pC = m_localAnchorC - m_lcC; b2Vec2 pA = b2Math.b2MulT(qC, rA + (cA - cC)); coordinateA = b2Math.b2Dot(pA - pC, m_localAxisC); } if (m_typeB == b2JointType.e_revoluteJoint) { JvBD.SetZero(); JwB = m_ratio; JwD = m_ratio; mass += m_ratio * m_ratio * (m_iB + m_iD); coordinateB = aB - aD - m_referenceAngleB; } else { b2Vec2 u = b2Math.b2Mul(qD, m_localAxisD); b2Vec2 rD = b2Math.b2Mul(qD, m_localAnchorD - m_lcD); b2Vec2 rB = b2Math.b2Mul(qB, m_localAnchorB - m_lcB); JvBD = m_ratio * u; JwD = m_ratio * b2Math.b2Cross(rD, u); JwB = m_ratio * b2Math.b2Cross(rB, u); mass += m_ratio * m_ratio * (m_mD + m_mB) + m_iD * JwD * JwD + m_iB * JwB * JwB; b2Vec2 pD = m_localAnchorD - m_lcD; b2Vec2 pB = b2Math.b2MulT(qD, rB + (cB - cD)); coordinateB = b2Math.b2Dot(pB - pD, m_localAxisD); } float C = (coordinateA + m_ratio * coordinateB) - m_constant; float impulse = 0.0f; if (mass > 0.0f) { impulse = -C / mass; } cA += m_mA * impulse * JvAC; aA += m_iA * impulse * JwA; cB += m_mB * impulse * JvBD; aB += m_iB * impulse * JwB; cC -= m_mC * impulse * JvAC; aC -= m_iC * impulse * JwC; cD -= m_mD * impulse * JvBD; aD -= m_iD * impulse * JwD; m_bodyA.InternalPosition.c = cA; m_bodyA.InternalPosition.a = aA; m_bodyB.InternalPosition.c = cB; m_bodyB.InternalPosition.a = aB; m_bodyC.InternalPosition.c = cC; m_bodyC.InternalPosition.a = aC; m_bodyD.InternalPosition.c = cD; m_bodyD.InternalPosition.a = aD; // TODO_ERIN not implemented return(linearError < b2Settings.b2_linearSlop); }
public override void InitVelocityConstraints(b2SolverData data) { m_indexA = m_bodyA.IslandIndex; m_indexB = m_bodyB.IslandIndex; m_indexC = m_bodyC.IslandIndex; m_indexD = m_bodyD.IslandIndex; m_lcA = m_bodyA.Sweep.localCenter; m_lcB = m_bodyB.Sweep.localCenter; m_lcC = m_bodyC.Sweep.localCenter; m_lcD = m_bodyD.Sweep.localCenter; m_mA = m_bodyA.InvertedMass; m_mB = m_bodyB.InvertedMass; m_mC = m_bodyC.InvertedMass; m_mD = m_bodyD.InvertedMass; m_iA = m_bodyA.InvertedI; m_iB = m_bodyB.InvertedI; m_iC = m_bodyC.InvertedI; m_iD = m_bodyD.InvertedI; b2Vec2 cA = m_bodyA.InternalPosition.c; float aA = m_bodyA.InternalPosition.a; b2Vec2 vA = m_bodyA.InternalVelocity.v; float wA = m_bodyA.InternalVelocity.w; b2Vec2 cB = m_bodyB.InternalPosition.c; float aB = m_bodyB.InternalPosition.a; b2Vec2 vB = m_bodyB.InternalVelocity.v; float wB = m_bodyB.InternalVelocity.w; b2Vec2 cC = m_bodyC.InternalPosition.c; float aC = m_bodyC.InternalPosition.a; b2Vec2 vC = m_bodyC.InternalVelocity.v; float wC = m_bodyC.InternalVelocity.w; b2Vec2 cD = m_bodyD.InternalPosition.c; float aD = m_bodyD.InternalPosition.a; b2Vec2 vD = m_bodyD.InternalVelocity.v; float wD = m_bodyD.InternalVelocity.w; b2Rot qA = new b2Rot(aA); b2Rot qB = new b2Rot(aB); b2Rot qC = new b2Rot(aC); b2Rot qD = new b2Rot(aD); m_mass = 0.0f; if (m_typeA == b2JointType.e_revoluteJoint) { m_JvAC.SetZero(); m_JwA = 1.0f; m_JwC = 1.0f; m_mass += m_iA + m_iC; } else { b2Vec2 u = b2Math.b2Mul(qC, m_localAxisC); b2Vec2 rC = b2Math.b2Mul(qC, m_localAnchorC - m_lcC); b2Vec2 rA = b2Math.b2Mul(qA, m_localAnchorA - m_lcA); m_JvAC = u; m_JwC = b2Math.b2Cross(rC, u); m_JwA = b2Math.b2Cross(rA, u); m_mass += m_mC + m_mA + m_iC * m_JwC * m_JwC + m_iA * m_JwA * m_JwA; } if (m_typeB == b2JointType.e_revoluteJoint) { m_JvBD.SetZero(); m_JwB = m_ratio; m_JwD = m_ratio; m_mass += m_ratio * m_ratio * (m_iB + m_iD); } else { b2Vec2 u = b2Math.b2Mul(qD, m_localAxisD); b2Vec2 rD = b2Math.b2Mul(qD, m_localAnchorD - m_lcD); b2Vec2 rB = b2Math.b2Mul(qB, m_localAnchorB - m_lcB); m_JvBD = m_ratio * u; m_JwD = m_ratio * b2Math.b2Cross(rD, u); m_JwB = m_ratio * b2Math.b2Cross(rB, u); m_mass += m_ratio * m_ratio * (m_mD + m_mB) + m_iD * m_JwD * m_JwD + m_iB * m_JwB * m_JwB; } // Compute effective mass. m_mass = m_mass > 0.0f ? 1.0f / m_mass : 0.0f; if (data.step.warmStarting) { vA += (m_mA * m_impulse) * m_JvAC; wA += m_iA * m_impulse * m_JwA; vB += (m_mB * m_impulse) * m_JvBD; wB += m_iB * m_impulse * m_JwB; vC -= (m_mC * m_impulse) * m_JvAC; wC -= m_iC * m_impulse * m_JwC; vD -= (m_mD * m_impulse) * m_JvBD; wD -= m_iD * m_impulse * m_JwD; } else { m_impulse = 0.0f; } m_bodyA.InternalVelocity.v = vA; m_bodyA.InternalVelocity.w = wA; m_bodyB.InternalVelocity.v = vB; m_bodyB.InternalVelocity.w = wB; m_bodyC.InternalVelocity.v = vC; m_bodyC.InternalVelocity.w = wC; m_bodyD.InternalVelocity.v = vD; m_bodyD.InternalVelocity.w = wD; }
public b2CircleShape() { ShapeType = b2ShapeType.e_circle; Radius = 0.0f; Position.SetZero(); }
public bool RayCast(out b2RayCastOutput output, b2RayCastInput input) { float tmin = -float.MaxValue; float tmax = float.MaxValue; b2Vec2 p = input.p1; b2Vec2 d = input.p2 - input.p1; b2Vec2 absD = b2Math.b2Abs(d); b2Vec2 normal = new b2Vec2(0, 0); for (int i = 0; i < 2; ++i) { float p_i, lb, ub, d_i, absd_i; p_i = (i == 0 ? p.x : p.y); lb = (i == 0 ? m_lowerBound.x : m_lowerBound.y); ub = (i == 0 ? m_upperBound.x : m_upperBound.y); absd_i = (i == 0 ? absD.x : absD.y); d_i = (i == 0 ? d.x : d.y); if (absd_i < b2Settings.b2_epsilon) { // Parallel. if (p_i < lb || ub < p_i) { output.fraction = 0f; output.normal = new b2Vec2(0, 0); return(false); } } else { float inv_d = 1.0f / d_i; float t1 = (lb - p_i) * inv_d; float t2 = (ub - p_i) * inv_d; // Sign of the normal vector. float s = -1.0f; if (t1 > t2) { b2Math.b2Swap(t1, t2); s = 1.0f; } // Push the min up if (t1 > tmin) { normal.SetZero(); if (i == 0) { normal.x = s; } else { normal.y = s; } tmin = t1; } // Pull the max down tmax = Math.Min(tmax, t2); if (tmin > tmax) { output.fraction = 0f; output.normal = new b2Vec2(0, 0); return(false); } } } // Does the ray start inside the box? // Does the ray intersect beyond the max fraction? if (tmin < 0.0f || input.maxFraction < tmin) { output.fraction = 0f; output.normal = new b2Vec2(0, 0); return(false); } // Intersection. output.fraction = tmin; output.normal = normal; return(true); }
public b2Body(b2BodyDef bd, b2World world) { BodyFlags = 0; if (bd.bullet) { BodyFlags |= b2BodyFlags.e_bulletFlag; } if (bd.fixedRotation) { BodyFlags |= b2BodyFlags.e_fixedRotationFlag; } if (bd.allowSleep) { BodyFlags |= b2BodyFlags.e_autoSleepFlag; } if (bd.awake) { BodyFlags |= b2BodyFlags.e_awakeFlag; } if (bd.active) { BodyFlags |= b2BodyFlags.e_activeFlag; } World = world; Transform.p = bd.position; Transform.q.Set(bd.angle); Sweep.localCenter.SetZero(); Sweep.c0 = Transform.p; Sweep.c = Transform.p; Sweep.a0 = bd.angle; Sweep.a = bd.angle; Sweep.alpha0 = 0.0f; JointList = null; ContactList = null; Prev = null; Next = null; m_linearVelocity = bd.linearVelocity; m_angularVelocity = bd.angularVelocity; LinearDamping = bd.linearDamping; AngularDamping = bd.angularDamping; GravityScale = bd.gravityScale; Force.SetZero(); Torque = 0.0f; SleepTime = 0.0f; BodyType = bd.type; if (BodyType == b2BodyType.b2_dynamicBody) { Mass = 1.0f; InvertedMass = 1.0f; } else { Mass = 0.0f; InvertedMass = 0.0f; } m_I = 0.0f; InvertedI = 0.0f; UserData = bd.userData; FixtureList = null; FixtureCount = 0; }
public override void InitVelocityConstraints(b2SolverData data) { m_indexA = m_bodyA.IslandIndex; m_indexB = m_bodyB.IslandIndex; m_localCenterA = m_bodyA.Sweep.localCenter; m_localCenterB = m_bodyB.Sweep.localCenter; m_invMassA = m_bodyA.InvertedMass; m_invMassB = m_bodyB.InvertedMass; m_invIA = m_bodyA.InvertedI; m_invIB = m_bodyB.InvertedI; b2Vec2 cA = data.positions[m_indexA].c; float aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; float wA = data.velocities[m_indexA].w; b2Vec2 cB = data.positions[m_indexB].c; float aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; float wB = data.velocities[m_indexB].w; b2Rot qA = new b2Rot(aA); b2Rot qB = new b2Rot(aB); m_rA = b2Math.b2Mul(qA, m_localAnchorA - m_localCenterA); m_rB = b2Math.b2Mul(qB, m_localAnchorB - m_localCenterB); // Get the pulley axes. m_uA = cA + m_rA - m_groundAnchorA; m_uB = cB + m_rB - m_groundAnchorB; float lengthA = m_uA.Length; float lengthB = m_uB.Length; if (lengthA > 10.0f * b2Settings.b2_linearSlop) { m_uA *= 1.0f / lengthA; } else { m_uA.SetZero(); } if (lengthB > 10.0f * b2Settings.b2_linearSlop) { m_uB *= 1.0f / lengthB; } else { m_uB.SetZero(); } // Compute effective mass. float ruA = b2Math.b2Cross(m_rA, m_uA); float ruB = b2Math.b2Cross(m_rB, m_uB); float mA = m_invMassA + m_invIA * ruA * ruA; float mB = m_invMassB + m_invIB * ruB * ruB; m_mass = mA + m_ratio * m_ratio * mB; if (m_mass > 0.0f) { m_mass = 1.0f / m_mass; } if (data.step.warmStarting) { // Scale impulses to support variable time steps. m_impulse *= data.step.dtRatio; // Warm starting. b2Vec2 PA = -(m_impulse) * m_uA; b2Vec2 PB = (-m_ratio * m_impulse) * m_uB; vA += m_invMassA * PA; wA += m_invIA * b2Math.b2Cross(m_rA, PA); vB += m_invMassB * PB; wB += m_invIB * b2Math.b2Cross(m_rB, PB); } else { m_impulse = 0.0f; } data.velocities[m_indexA].v = vA; data.velocities[m_indexA].w = wA; data.velocities[m_indexB].v = vB; data.velocities[m_indexB].w = wB; }
public override bool SolvePositionConstraints(b2SolverData data) { b2Vec2 cA = data.positions[m_indexA].c; float aA = data.positions[m_indexA].a; b2Vec2 cB = data.positions[m_indexB].c; float aB = data.positions[m_indexB].a; b2Rot qA = new b2Rot(aA); b2Rot qB = new b2Rot(aB); b2Vec2 rA = b2Math.b2Mul(qA, m_localAnchorA - m_localCenterA); b2Vec2 rB = b2Math.b2Mul(qB, m_localAnchorB - m_localCenterB); // Get the pulley axes. b2Vec2 uA = cA + rA - m_groundAnchorA; b2Vec2 uB = cB + rB - m_groundAnchorB; float lengthA = uA.Length; float lengthB = uB.Length; if (lengthA > 10.0f * b2Settings.b2_linearSlop) { uA *= 1.0f / lengthA; } else { uA.SetZero(); } if (lengthB > 10.0f * b2Settings.b2_linearSlop) { uB *= 1.0f / lengthB; } else { uB.SetZero(); } // Compute effective mass. float ruA = b2Math.b2Cross(rA, uA); float ruB = b2Math.b2Cross(rB, uB); float mA = m_invMassA + m_invIA * ruA * ruA; float mB = m_invMassB + m_invIB * ruB * ruB; float mass = mA + m_ratio * m_ratio * mB; if (mass > 0.0f) { mass = 1.0f / mass; } float C = m_constant - lengthA - m_ratio * lengthB; float linearError = b2Math.b2Abs(C); float impulse = -mass * C; b2Vec2 PA = -impulse * uA; b2Vec2 PB = -m_ratio * impulse * uB; cA += m_invMassA * PA; aA += m_invIA * b2Math.b2Cross(rA, PA); cB += m_invMassB * PB; aB += m_invIB * b2Math.b2Cross(rB, PB); data.positions[m_indexA].c = cA; data.positions[m_indexA].a = aA; data.positions[m_indexB].c = cB; data.positions[m_indexB].a = aB; return(linearError < b2Settings.b2_linearSlop); }
// From Real-time Collision Detection, p179. public bool RayCast(b2RayCastOutput output, b2RayCastInput input) { float tmin = -float.MaxValue; float tmax = float.MaxValue; b2Vec2 p = new b2Vec2(input.p1); b2Vec2 d = input.p2 - input.p1; b2Vec2 absD = Utils.b2Abs(d); b2Vec2 normal = new b2Vec2(); for (int i = 0; i < 2; ++i) { if (absD[i] < float.Epsilon) { // Parallel. if (p[i] < lowerBound[i] || upperBound[i] < p[i]) { return(false); } } else { float inv_d = 1.0f / d[i]; float t1 = (lowerBound[i] - p[i]) * inv_d; float t2 = (upperBound[i] - p[i]) * inv_d; // Sign of the normal vector. float s = -1.0f; if (t1 > t2) { Utils.b2Swap(ref t1, ref t2); s = 1.0f; } // Push the min up if (t1 > tmin) { normal.SetZero(); normal[i] = s; tmin = t1; } // Pull the max down tmax = Utils.b2Min(tmax, t2); if (tmin > tmax) { return(false); } } } // Does the ray start inside the box? // Does the ray intersect beyond the max fraction? if (tmin < 0.0f || input.maxFraction < tmin) { return(false); } // Intersection. output.fraction = tmin; output.normal = normal; return(true); }