Beispiel #1
0
 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();
        }
Beispiel #4
0
        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();
        }
Beispiel #5
0
        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;
        }
Beispiel #6
0
 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;
 }
Beispiel #8
0
        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();
 }
Beispiel #10
0
        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;
        }
Beispiel #11
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();
 }
Beispiel #17
0
        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);
        }
Beispiel #18
0
        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;
        }
Beispiel #19
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;
        }
Beispiel #20
0
        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);
        }
Beispiel #21
0
    // 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);
    }