Example #1
0
        /**
         * @inheritDoc
         */
        public override bool TestPoint(b2Transform xf, b2Vec2 p)
        {
            b2Vec2 tVec;

            //b2Vec2 pLocal = b2MulT(xf.R, p - xf.position);
            b2Mat22 tMat    = xf.R;
            float   tX      = p.x - xf.position.x;
            float   tY      = p.y - xf.position.y;
            float   pLocalX = (tX * tMat.col1.x + tY * tMat.col1.y);
            float   pLocalY = (tX * tMat.col2.x + tY * tMat.col2.y);

            for (int i = 0; i < m_vertexCount; ++i)
            {
                //float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]);
                tVec = m_vertices[i];
                tX   = pLocalX - tVec.x;
                tY   = pLocalY - tVec.y;
                tVec = m_normals[i];
                float dot = (tVec.x * tX + tVec.y * tY);
                if (dot > 0.0f)
                {
                    return(false);
                }
            }

            return(true);
        }
Example #2
0
        /**
         * @inheritDoc
         */
        public override void ComputeAABB(b2AABB aabb, b2Transform transform)
        {
            b2Mat22 tMat = transform.R;
            //b2Vec2 v1 = b2Mul(transform, m_v1);
            float v1X = transform.position.x + (tMat.col1.x * m_v1.x + tMat.col2.x * m_v1.y);
            float v1Y = transform.position.y + (tMat.col1.y * m_v1.x + tMat.col2.y * m_v1.y);
            //b2Vec2 v2 = b2Mul(transform, m_v2);
            float v2X = transform.position.x + (tMat.col1.x * m_v2.x + tMat.col2.x * m_v2.y);
            float v2Y = transform.position.y + (tMat.col1.y * m_v2.x + tMat.col2.y * m_v2.y);

            if (v1X < v2X)
            {
                aabb.lowerBound.x = v1X;
                aabb.upperBound.x = v2X;
            }
            else
            {
                aabb.lowerBound.x = v2X;
                aabb.upperBound.x = v1X;
            }
            if (v1Y < v2Y)
            {
                aabb.lowerBound.y = v1Y;
                aabb.upperBound.y = v2Y;
            }
            else
            {
                aabb.lowerBound.y = v2Y;
                aabb.upperBound.y = v1Y;
            }
        }
Example #3
0
        //--------------- Internals Below -------------------

        /** @private */
        public b2MouseJoint(b2MouseJointDef def) : base(def)
        {
            //b2Settings.b2Assert(def.target.IsValid());
            //b2Settings.b2Assert(b2Math.b2IsValid(def.maxForce) && def.maxForce > 0.0);
            //b2Settings.b2Assert(b2Math.b2IsValid(def.frequencyHz) && def.frequencyHz > 0.0);
            //b2Settings.b2Assert(b2Math.b2IsValid(def.dampingRatio) && def.dampingRatio > 0.0);

            m_target.SetV(def.target);
            //m_localAnchor = b2MulT(m_bodyB.m_xf, m_target);
            float   tX   = m_target.x - m_bodyB.m_xf.position.x;
            float   tY   = m_target.y - m_bodyB.m_xf.position.y;
            b2Mat22 tMat = m_bodyB.m_xf.R;

            m_localAnchor.x = (tX * tMat.col1.x + tY * tMat.col1.y);
            m_localAnchor.y = (tX * tMat.col2.x + tY * tMat.col2.y);

            m_maxForce = def.maxForce;
            m_impulse.SetZero();

            m_frequencyHz  = def.frequencyHz;
            m_dampingRatio = def.dampingRatio;

            m_beta  = 0.0f;
            m_gamma = 0.0f;
        }
Example #4
0
        /**
         * @inheritDoc
         */
        public override void ComputeAABB(b2AABB aabb, b2Transform xf)
        {
            //var lower:b2Vec2 = b2Math.MulX(xf, m_vertices[0]);
            b2Mat22 tMat   = xf.R;
            b2Vec2  tVec   = m_vertices[0];
            float   lowerX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
            float   lowerY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
            float   upperX = lowerX;
            float   upperY = lowerY;

            for (int i = 1; i < m_vertexCount; ++i)
            {
                tVec = m_vertices[i];
                float vX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
                float vY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
                lowerX = lowerX < vX ? lowerX : vX;
                lowerY = lowerY < vY ? lowerY : vY;
                upperX = upperX > vX ? upperX : vX;
                upperY = upperY > vY ? upperY : vY;
            }

            aabb.lowerBound.x = lowerX - m_radius;
            aabb.lowerBound.y = lowerY - m_radius;
            aabb.upperBound.x = upperX + m_radius;
            aabb.upperBound.y = upperY + m_radius;
        }
Example #5
0
        /**
         * Get the first vertex and apply the supplied transform.
         */
        public b2Vec2 GetFirstVertex(b2Transform xf)
        {
            //return b2Mul(xf, m_coreV1);
            b2Mat22 tMat = xf.R;

            return(new b2Vec2(xf.position.x + (tMat.col1.x * m_coreV1.x + tMat.col2.x * m_coreV1.y),
                              xf.position.y + (tMat.col1.y * m_coreV1.x + tMat.col2.y * m_coreV1.y)));
        }
Example #6
0
        public static b2Vec2 b2Mul(b2Mat22 A, b2Vec2 v)
        {
            b2Vec2 ret = new b2Vec2(Box2DPINVOKE.b2Mul__SWIG_0(b2Mat22.getCPtr(A), b2Vec2.getCPtr(v)), true);

            if (Box2DPINVOKE.SWIGPendingException.Pending)
            {
                throw Box2DPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
Example #7
0
        /**
         * @inheritDoc
         */
        public override void ComputeAABB(b2AABB aabb, b2Transform transform)
        {
            //b2Vec2 p = transform.position + b2Mul(transform.R, m_p);
            b2Mat22 tMat = transform.R;
            float   pX   = transform.position.x + (tMat.col1.x * m_p.x + tMat.col2.x * m_p.y);
            float   pY   = transform.position.y + (tMat.col1.y * m_p.x + tMat.col2.y * m_p.y);

            aabb.lowerBound.Set(pX - m_radius, pY - m_radius);
            aabb.upperBound.Set(pX + m_radius, pY + m_radius);
        }
Example #8
0
        public static b2Mat22 b2MulT(b2Mat22 A, b2Mat22 B)
        {
            b2Mat22 ret = new b2Mat22(Box2DPINVOKE.b2MulT__SWIG_1(b2Mat22.getCPtr(A), b2Mat22.getCPtr(B)), true);

            if (Box2DPINVOKE.SWIGPendingException.Pending)
            {
                throw Box2DPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
Example #9
0
        public static b2Mat22 b2Abs(b2Mat22 A)
        {
            b2Mat22 ret = new b2Mat22(Box2DPINVOKE.b2Abs__SWIG_2(b2Mat22.getCPtr(A)), true);

            if (Box2DPINVOKE.SWIGPendingException.Pending)
            {
                throw Box2DPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
Example #10
0
        /**
         * @inheritDoc
         */
        public override bool RayCast(b2RayCastOutput output, b2RayCastInput input, b2Transform transform)
        {
            //b2Vec2 position = transform.position + b2Mul(transform.R, m_p);
            b2Mat22 tMat      = transform.R;
            float   positionX = transform.position.x + (tMat.col1.x * m_p.x + tMat.col2.x * m_p.y);
            float   positionY = transform.position.y + (tMat.col1.y * m_p.x + tMat.col2.y * m_p.y);

            //b2Vec2 s = input.p1 - position;
            float sX = input.p1.x - positionX;
            float sY = input.p1.y - positionY;
            //float32 b = b2Dot(s, s) - m_radius * m_radius;
            float b = (sX * sX + sY * sY) - m_radius * m_radius;

            /*// Does the segment start inside the circle?
             * if (b < 0.0)
             * {
             *      output.fraction = 0;
             *      output.hit = e_startsInsideCollide;
             *      return;
             * }*/

            // Solve quadratic equation.
            //b2Vec2 r = input.p2 - input.p1;
            float rX = input.p2.x - input.p1.x;
            float rY = input.p2.y - input.p1.y;
            //float32 c =  b2Dot(s, r);
            float c = (sX * rX + sY * rY);
            //float32 rr = b2Dot(r, r);
            float rr    = (rX * rX + rY * rY);
            float sigma = c * c - rr * b;

            // Check for negative discriminant and short segment.
            if (sigma < 0.0 || rr < float.MinValue)
            {
                return(false);
            }

            // Find the point of intersection of the line with the circle.
            float a = -(c + Mathf.Sqrt(sigma));

            // Is the intersection point on the segment?
            if (0.0f <= a && a <= input.maxFraction * rr)
            {
                a /= rr;
                output.fraction = a;
                // manual inline of: output.normal = s + a * r;
                output.normal.x = sX + a * rX;
                output.normal.y = sY + a * rY;
                output.normal.Normalize();
                return(true);
            }

            return(false);
        }
Example #11
0
        /**
         * @inheritDoc
         */
        public override bool TestPoint(b2Transform transform, b2Vec2 p)
        {
            //b2Vec2 center = transform.position + b2Mul(transform.R, m_p);
            b2Mat22 tMat = transform.R;
            float   dX   = transform.position.x + (tMat.col1.x * m_p.x + tMat.col2.x * m_p.y);
            float   dY   = transform.position.y + (tMat.col1.y * m_p.x + tMat.col2.y * m_p.y);

            //b2Vec2 d = p - center;
            dX = p.x - dX;
            dY = p.y - dY;
            //return b2Dot(d, d) <= m_radius * m_radius;
            return((dX * dX + dY * dY) <= m_radius * m_radius);
        }
Example #12
0
        /**
         * Get the interpolated transform at a specific time.
         * @param alpha is a factor in [0,1], where 0 indicates t0.
         */
        public void GetTransform(b2Transform xf, float alpha)
        {
            xf.position.x = (1.0f - alpha) * c0.x + alpha * c.x;
            xf.position.y = (1.0f - alpha) * c0.y + alpha * c.y;
            float angle = (1.0f - alpha) * a0 + alpha * a;

            xf.R.Set(angle);

            // Shift to origin
            //xf->position -= b2Mul(xf->R, localCenter);
            b2Mat22 tMat = xf.R;

            xf.position.x -= (tMat.col1.x * localCenter.x + tMat.col2.x * localCenter.y);
            xf.position.y -= (tMat.col1.y * localCenter.x + tMat.col2.y * localCenter.y);
        }
Example #13
0
        /** @inheritDoc */
        public override float GetReactionTorque(float inv_dt)
        {
            // TODO_ERIN not tested
            //b2Vec2 r = b2Mul(m_bodyB->m_xf.R, m_localAnchor2 - m_bodyB->GetLocalCenter());
            b2Mat22 tMat = m_bodyB.m_xf.R;
            float   rX   = m_localAnchor1.x - m_bodyB.m_sweep.localCenter.x;
            float   rY   = m_localAnchor1.y - m_bodyB.m_sweep.localCenter.y;
            float   tX   = tMat.col1.x * rX + tMat.col2.x * rY;

            rY = tMat.col1.y * rX + tMat.col2.y * rY;
            rX = tX;
            //b2Vec2 P = m_impulse * m_J.linearB;
            float PX = m_impulse * m_J.linearB.x;
            float PY = m_impulse * m_J.linearB.y;

            //float32 L = m_impulse * m_J.angularB - b2Cross(r, P);
            //return inv_dt * L;
            return(inv_dt * (m_impulse * m_J.angularB - rX * PY + rY * PX));
        }
Example #14
0
    public b2Mat22 GetInverse()
    {
        float   a   = ex.x;
        float   b   = ey.x;
        float   c   = ex.y;
        float   d   = ey.y;
        b2Mat22 B   = new b2Mat22();
        float   det = a * d - b * c;

        if (det != 0.0f)
        {
            det = 1.0f / det;
        }

        B.ex.x = det * d;
        B.ey.x = -det * b;
        B.ex.y = -det * c;
        B.ey.y = det * a;
        return(B);
    }
Example #15
0
        /**
         * Get the support point in the given world direction.
         * Use the supplied transform.
         */
        public b2Vec2 Support(b2Transform xf, float dX, float dY)
        {
            b2Mat22 tMat = xf.R;
            //b2Vec2 v1 = b2Mul(xf, m_coreV1);
            float v1X = xf.position.x + (tMat.col1.x * m_coreV1.x + tMat.col2.x * m_coreV1.y);
            float v1Y = xf.position.y + (tMat.col1.y * m_coreV1.x + tMat.col2.y * m_coreV1.y);

            //b2Vec2 v2 = b2Mul(xf, m_coreV2);
            float v2X = xf.position.x + (tMat.col1.x * m_coreV2.x + tMat.col2.x * m_coreV2.y);
            float v2Y = xf.position.y + (tMat.col1.y * m_coreV2.x + tMat.col2.y * m_coreV2.y);

            if ((v1X * dX + v1Y * dY) > (v2X * dX + v2Y * dY))
            {
                s_supportVec.x = v1X;
                s_supportVec.y = v1Y;
            }
            else
            {
                s_supportVec.x = v2X;
                s_supportVec.y = v2Y;
            }
            return(s_supportVec);
        }
Example #16
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);

            float mA = InvertedMassA, mB = InvertedMassB;
            float iA = InvertedIA, iB = InvertedIB;

            // Compute fresh Jacobians
            b2Vec2 rA = b2Math.b2Mul(qA, m_localAnchorA - m_localCenterA);
            b2Vec2 rB = b2Math.b2Mul(qB, m_localAnchorB - m_localCenterB);
            b2Vec2 d  = cB + rB - cA - rA;

            b2Vec2 axis = b2Math.b2Mul(qA, m_localXAxisA);
            float  a1   = b2Math.b2Cross(d + rA, axis);
            float  a2   = b2Math.b2Cross(rB, axis);
            b2Vec2 perp = b2Math.b2Mul(qA, m_localYAxisA);

            float s1 = b2Math.b2Cross(d + rA, perp);
            float s2 = b2Math.b2Cross(rB, perp);

            b2Vec3 impulse;
            b2Vec2 C1 = new b2Vec2();

            C1.x = b2Math.b2Dot(perp, d);
            C1.y = aB - aA - m_referenceAngle;

            float linearError  = b2Math.b2Abs(C1.x);
            float angularError = b2Math.b2Abs(C1.y);

            bool  active = false;
            float C2     = 0.0f;

            if (m_enableLimit)
            {
                float translation = b2Math.b2Dot(axis, d);
                if (b2Math.b2Abs(m_upperTranslation - m_lowerTranslation) < 2.0f * b2Settings.b2_linearSlop)
                {
                    // Prevent large angular corrections
                    C2          = b2Math.b2Clamp(translation, -b2Settings.b2_maxLinearCorrection, b2Settings.b2_maxLinearCorrection);
                    linearError = Math.Max(linearError, b2Math.b2Abs(translation));
                    active      = true;
                }
                else if (translation <= m_lowerTranslation)
                {
                    // Prevent large linear corrections and allow some slop.
                    C2          = b2Math.b2Clamp(translation - m_lowerTranslation + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0.0f);
                    linearError = Math.Max(linearError, m_lowerTranslation - translation);
                    active      = true;
                }
                else if (translation >= m_upperTranslation)
                {
                    // Prevent large linear corrections and allow some slop.
                    C2          = b2Math.b2Clamp(translation - m_upperTranslation - b2Settings.b2_linearSlop, 0.0f, b2Settings.b2_maxLinearCorrection);
                    linearError = Math.Max(linearError, translation - m_upperTranslation);
                    active      = true;
                }
            }

            if (active)
            {
                float k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;
                float k12 = iA * s1 + iB * s2;
                float k13 = iA * s1 * a1 + iB * s2 * a2;
                float k22 = iA + iB;
                if (k22 == 0.0f)
                {
                    // For fixed rotation
                    k22 = 1.0f;
                }
                float k23 = iA * a1 + iB * a2;
                float k33 = mA + mB + iA * a1 * a1 + iB * a2 * a2;

                b2Mat33 K = new b2Mat33(
                    new b2Vec3(k11, k12, k13),
                    new b2Vec3(k12, k22, k23),
                    new b2Vec3(k13, k23, k33));

                b2Vec3 C = new b2Vec3(C1.x, C1.y, C2);

                impulse = K.Solve33(-C);
            }
            else
            {
                float k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2;
                float k12 = iA * s1 + iB * s2;
                float k22 = iA + iB;
                if (k22 == 0.0f)
                {
                    k22 = 1.0f;
                }

                b2Mat22 K = new b2Mat22();
                K.ex.Set(k11, k12);
                K.ey.Set(k12, k22);

                b2Vec2 impulse1 = K.Solve(-C1);
                impulse   = new b2Vec3();
                impulse.x = impulse1.x;
                impulse.y = impulse1.y;
                impulse.z = 0.0f;
            }

            b2Vec2 P  = impulse.x * perp + impulse.z * axis;
            float  LA = impulse.x * s1 + impulse.y + impulse.z * a1;
            float  LB = impulse.x * s2 + impulse.y + impulse.z * a2;

            cA -= mA * P;
            aA -= iA * LA;
            cB += mB * P;
            aB += iB * LB;

            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 && angularError <= b2Settings.b2_angularSlop);
        }
Example #17
0
        /**
         * Computes a polygon's OBB
         * @see http://www.geometrictools.com/Documentation/MinimumAreaRectangle.pdf
         */
        static public void ComputeOBB(b2OBB obb, List <b2Vec2> vs, int count)
        {
            int           i;
            List <b2Vec2> p = new List <b2Vec2>(count + 1);

            for (i = 0; i < count; ++i)
            {
                p[i] = vs[i];
            }
            p[count] = p[0];

            float minArea = float.MaxValue;

            for (i = 1; i <= count; ++i)
            {
                b2Vec2 root = p[(int)(i - 1)];
                //b2Vec2 ux = p[i] - root;
                float uxX = p[i].x - root.x;
                float uxY = p[i].y - root.y;
                //var length:Number = ux.Normalize();
                float length = Mathf.Sqrt(uxX * uxX + uxY * uxY);
                uxX /= length;
                uxY /= length;
                //b2Settings.b2Assert(length > Number.MIN_VALUE);
                //b2Vec2 uy(-ux.y, ux.x);
                float uyX = -uxY;
                float uyY = uxX;
                //b2Vec2 lower(FLT_MAX, FLT_MAX);
                float lowerX = float.MaxValue;
                float lowerY = float.MaxValue;
                //b2Vec2 upper(-FLT_MAX, -FLT_MAX);
                float upperX = -float.MaxValue;
                float upperY = -float.MaxValue;

                for (int j = 0; j < count; ++j)
                {
                    //b2Vec2 d = p[j] - root;
                    float dX = p[j].x - root.x;
                    float dY = p[j].y - root.y;
                    //b2Vec2 r;
                    //var rX:Number = b2Dot(ux, d);
                    float rX = (uxX * dX + uxY * dY);
                    //var rY:Number = b2Dot(uy, d);
                    float rY = (uyX * dX + uyY * dY);
                    //lower = b2Min(lower, r);
                    if (rX < lowerX)
                    {
                        lowerX = rX;
                    }
                    if (rY < lowerY)
                    {
                        lowerY = rY;
                    }
                    //upper = b2Max(upper, r);
                    if (rX > upperX)
                    {
                        upperX = rX;
                    }
                    if (rY > upperY)
                    {
                        upperY = rY;
                    }
                }

                float area = (upperX - lowerX) * (upperY - lowerY);
                if (area < 0.95f * minArea)
                {
                    minArea = area;
                    //obb->R.col1 = ux;
                    obb.R.col1.x = uxX;
                    obb.R.col1.y = uxY;
                    //obb->R.col2 = uy;
                    obb.R.col2.x = uyX;
                    obb.R.col2.y = uyY;
                    //b2Vec2 center = 0.5f * (lower + upper);
                    float centerX = 0.5f * (lowerX + upperX);
                    float centerY = 0.5f * (lowerY + upperY);
                    //obb->center = root + b2Mul(obb->R, center);
                    b2Mat22 tMat = obb.R;
                    obb.center.x = root.x + (tMat.col1.x * centerX + tMat.col2.x * centerY);
                    obb.center.y = root.y + (tMat.col1.y * centerX + tMat.col2.y * centerY);
                    //obb->extents = 0.5f * (upper - lower);
                    obb.extents.x = 0.5f * (upperX - lowerX);
                    obb.extents.y = 0.5f * (upperY - lowerY);
                }
            }

            //b2Settings.b2Assert(minArea < Number.MAX_VALUE);
        }
        public override bool SolvePositionConstraints(float baumgarte)
        {
            //B2_NOT_USED(baumgarte);


            float limitC;
            float oldLimitImpulse;

            b2Body bA = m_bodyA;
            b2Body bB = m_bodyB;

            b2Vec2 c1 = bA.m_sweep.c;
            float  a1 = bA.m_sweep.a;

            b2Vec2 c2 = bB.m_sweep.c;
            float  a2 = bB.m_sweep.a;

            b2Mat22 tMat;
            float   tX;

            float m1;
            float m2;
            float i1;
            float i2;

            // Solve linear limit constraint
            float linearError  = 0.0f;
            float angularError = 0.0f;
            bool  active       = false;
            float C2           = 0.0f;

            b2Mat22 R1 = b2Mat22.FromAngle(a1);
            b2Mat22 R2 = b2Mat22.FromAngle(a2);

            //b2Vec2 r1 = b2Mul(R1, m_localAnchor1 - m_localCenterA);
            tMat = R1;
            float r1X = m_localAnchor1.x - m_localCenterA.x;
            float r1Y = m_localAnchor1.y - m_localCenterA.y;

            tX  = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
            r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
            r1X = tX;
            //b2Vec2 r2 = b2Mul(R2, m_localAnchor2 - m_localCenterB);
            tMat = R2;
            float r2X = m_localAnchor2.x - m_localCenterB.x;
            float r2Y = m_localAnchor2.y - m_localCenterB.y;

            tX  = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
            r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
            r2X = tX;

            float dX = c2.x + r2X - c1.x - r1X;
            float dY = c2.y + r2Y - c1.y - r1Y;

            if (m_enableLimit)
            {
                m_axis = b2Math.MulMV(R1, m_localXAxis1);

                //m_a1 = b2Math.b2Cross(d + r1, m_axis);
                m_a1 = (dX + r1X) * m_axis.y - (dY + r1Y) * m_axis.x;
                //m_a2 = b2Math.b2Cross(r2, m_axis);
                m_a2 = r2X * m_axis.y - r2Y * m_axis.x;

                float translation = m_axis.x * dX + m_axis.y * dY;
                if (b2Math.Abs(m_upperTranslation - m_lowerTranslation) < 2.0f * b2Settings.b2_linearSlop)
                {
                    // Prevent large angular corrections.
                    C2          = b2Math.Clamp(translation, -b2Settings.b2_maxLinearCorrection, b2Settings.b2_maxLinearCorrection);
                    linearError = b2Math.Abs(translation);
                    active      = true;
                }
                else if (translation <= m_lowerTranslation)
                {
                    // Prevent large angular corrections and allow some slop.
                    C2          = b2Math.Clamp(translation - m_lowerTranslation + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0.0f);
                    linearError = m_lowerTranslation - translation;
                    active      = true;
                }
                else if (translation >= m_upperTranslation)
                {
                    // Prevent large angular corrections and allow some slop.
                    C2          = b2Math.Clamp(translation - m_upperTranslation + b2Settings.b2_linearSlop, 0.0f, b2Settings.b2_maxLinearCorrection);
                    linearError = translation - m_upperTranslation;
                    active      = true;
                }
            }

            m_perp = b2Math.MulMV(R1, m_localYAxis1);

            //m_s1 = b2Cross(d + r1, m_perp);
            m_s1 = (dX + r1X) * m_perp.y - (dY + r1Y) * m_perp.x;
            //m_s2 = b2Cross(r2, m_perp);
            m_s2 = r2X * m_perp.y - r2Y * m_perp.x;

            b2Vec3 impulse = new b2Vec3();
            float  C1X     = m_perp.x * dX + m_perp.y * dY;
            float  C1Y     = a2 - a1 - m_refAngle;

            linearError  = b2Math.Max(linearError, b2Math.Abs(C1X));
            angularError = b2Math.Abs(C1Y);

            if (active)
            {
                m1 = m_invMassA;
                m2 = m_invMassB;
                i1 = m_invIA;
                i2 = m_invIB;

                m_K.col1.x = m1 + m2 + i1 * m_s1 * m_s1 + i2 * m_s2 * m_s2;
                m_K.col1.y = i1 * m_s1 + i2 * m_s2;
                m_K.col1.z = i1 * m_s1 * m_a1 + i2 * m_s2 * m_a2;
                m_K.col2.x = m_K.col1.y;
                m_K.col2.y = i1 + i2;
                m_K.col2.z = i1 * m_a1 + i2 * m_a2;
                m_K.col3.x = m_K.col1.z;
                m_K.col3.y = m_K.col2.z;
                m_K.col3.z = m1 + m2 + i1 * m_a1 * m_a1 + i2 * m_a2 * m_a2;

                m_K.Solve33(impulse, -C1X, -C1Y, -C2);
            }
            else
            {
                m1 = m_invMassA;
                m2 = m_invMassB;
                i1 = m_invIA;
                i2 = m_invIB;

                float k11 = m1 + m2 + i1 * m_s1 * m_s1 + i2 * m_s2 * m_s2;
                float k12 = i1 * m_s1 + i2 * m_s2;
                float k22 = i1 + i2;

                m_K.col1.Set(k11, k12, 0.0f);
                m_K.col2.Set(k12, k22, 0.0f);

                b2Vec2 impulse1 = m_K.Solve22(new b2Vec2(), -C1X, -C1Y);
                impulse.x = impulse1.x;
                impulse.y = impulse1.y;
                impulse.z = 0.0f;
            }

            float PX = impulse.x * m_perp.x + impulse.z * m_axis.x;
            float PY = impulse.x * m_perp.y + impulse.z * m_axis.y;
            float L1 = impulse.x * m_s1 + impulse.y + impulse.z * m_a1;
            float L2 = impulse.x * m_s2 + impulse.y + impulse.z * m_a2;

            c1.x -= m_invMassA * PX;
            c1.y -= m_invMassA * PY;
            a1   -= m_invIA * L1;

            c2.x += m_invMassB * PX;
            c2.y += m_invMassB * PY;
            a2   += m_invIB * L2;

            // TODO_ERIN remove need for this
            //bA.m_sweep.c = c1;	//Already done by reference
            bA.m_sweep.a = a1;
            //bB.m_sweep.c = c2;	//Already done by reference
            bB.m_sweep.a = a2;
            bA.SynchronizeTransform();
            bB.SynchronizeTransform();

            return(linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop);
        }
Example #19
0
    internal override void InitVelocityConstraints(b2SolverData data)
    {
        m_indexA = m_bodyA.m_islandIndex;
        m_indexB = m_bodyB.m_islandIndex;


        m_localCenterA = m_bodyA.m_sweep.localCenter;


        m_localCenterB = m_bodyB.m_sweep.localCenter;
        m_invMassA     = m_bodyA.m_invMass;
        m_invMassB     = m_bodyB.m_invMass;
        m_invIA        = m_bodyA.m_invI;
        m_invIB        = m_bodyB.m_invI;

        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);

        // Compute the effective mass matrix.


        m_rA = Utils.b2Mul(qA, m_linearOffset - m_localCenterA);


        m_rB = Utils.b2Mul(qB, -m_localCenterB);

        // J = [-I -r1_skew I r2_skew]
        // r_skew = [-ry; rx]

        // Matlab
        // K = [ mA+r1y^2*iA+mB+r2y^2*iB,  -r1y*iA*r1x-r2y*iB*r2x,          -r1y*iA-r2y*iB]
        //     [  -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB,           r1x*iA+r2x*iB]
        //     [          -r1y*iA-r2y*iB,           r1x*iA+r2x*iB,                   iA+iB]



        float mA = m_invMassA;
        float mB = m_invMassB;
        float iA = m_invIA;
        float iB = m_invIB;

        // Upper 2 by 2 of K for point to point
        b2Mat22 K = new b2Mat22();

        K.ex.x = mA + mB + iA * m_rA.y * m_rA.y + iB * m_rB.y * m_rB.y;
        K.ex.y = -iA * m_rA.x * m_rA.y - iB * m_rB.x * m_rB.y;
        K.ey.x = K.ex.y;
        K.ey.y = mA + mB + iA * m_rA.x * m_rA.x + iB * m_rB.x * m_rB.x;



        m_linearMass = K.GetInverse();

        m_angularMass = iA + iB;
        if (m_angularMass > 0.0f)
        {
            m_angularMass = 1.0f / m_angularMass;
        }



        m_linearError  = cB + m_rB - cA - m_rA;
        m_angularError = aB - aA - m_angularOffset;

        if (data.step.warmStarting)
        {
            // Scale impulses to support a variable time step.
            m_linearImpulse  *= data.step.dtRatio;
            m_angularImpulse *= data.step.dtRatio;

            b2Vec2 P = new b2Vec2(m_linearImpulse.x, m_linearImpulse.y);
            vA -= mA * P;
            wA -= iA * (Utils.b2Cross(m_rA, P) + m_angularImpulse);
            vB += mB * P;
            wB += iB * (Utils.b2Cross(m_rB, P) + m_angularImpulse);
        }
        else
        {
            m_linearImpulse.SetZero();
            m_angularImpulse = 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;
    }
Example #20
0
        public override void InitVelocityConstraints(b2TimeStep step)
        {
            b2Mat22 tMat;
            float   tX;

            b2Body bA = m_bodyA;
            b2Body bB = m_bodyB;

            // Compute the effective mass matrix.
            //b2Vec2 rA = b2Mul(bA->m_xf.R, m_localAnchorA - bA->GetLocalCenter());
            tMat = bA.m_xf.R;
            float rAX = m_localAnchorA.x - bA.m_sweep.localCenter.x;
            float rAY = m_localAnchorA.y - bA.m_sweep.localCenter.y;

            tX  = (tMat.col1.x * rAX + tMat.col2.x * rAY);
            rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY);
            rAX = tX;
            //b2Vec2 rB = b2Mul(bB->m_xf.R, m_localAnchorB - bB->GetLocalCenter());
            tMat = bB.m_xf.R;
            float rBX = m_localAnchorB.x - bB.m_sweep.localCenter.x;
            float rBY = m_localAnchorB.y - bB.m_sweep.localCenter.y;

            tX  = (tMat.col1.x * rBX + tMat.col2.x * rBY);
            rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY);
            rBX = tX;

            // J = [-I -r1_skew I r2_skew]
            //     [ 0       -1 0       1]
            // r_skew = [-ry; rx]

            // Matlab
            // K = [ mA+r1y^2*iA+mB+r2y^2*iB,  -r1y*iA*r1x-r2y*iB*r2x,          -r1y*iA-r2y*iB]
            //     [  -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB,           r1x*iA+r2x*iB]
            //     [          -r1y*iA-r2y*iB,           r1x*iA+r2x*iB,                   iA+iB]

            float mA = bA.m_invMass;
            float mB = bB.m_invMass;
            float iA = bA.m_invI;
            float iB = bB.m_invI;

            b2Mat22 K = new b2Mat22();

            K.col1.x = mA + mB;     K.col2.x = 0.0f;
            K.col1.y = 0.0f;        K.col2.y = mA + mB;

            K.col1.x += iA * rAY * rAY;     K.col2.x += -iA * rAX * rAY;
            K.col1.y += -iA * rAX * rAY;     K.col2.y += iA * rAX * rAX;

            K.col1.x += iB * rBY * rBY;     K.col2.x += -iB * rBX * rBY;
            K.col1.y += -iB * rBX * rBY;     K.col2.y += iB * rBX * rBX;

            K.GetInverse(m_linearMass);

            m_angularMass = iA + iB;
            if (m_angularMass > 0.0f)
            {
                m_angularMass = 1.0f / m_angularMass;
            }

            if (step.warmStarting)
            {
                // Scale impulses to support a variable time step.
                m_linearImpulse.x *= step.dtRatio;
                m_linearImpulse.y *= step.dtRatio;
                m_angularImpulse  *= step.dtRatio;

                b2Vec2 P = m_linearImpulse;

                bA.m_linearVelocity.x -= mA * P.x;
                bA.m_linearVelocity.y -= mA * P.y;
                bA.m_angularVelocity  -= iA * (rAX * P.y - rAY * P.x + m_angularImpulse);

                bB.m_linearVelocity.x += mB * P.x;
                bB.m_linearVelocity.y += mB * P.y;
                bB.m_angularVelocity  += iB * (rBX * P.y - rBY * P.x + m_angularImpulse);
            }
            else
            {
                m_linearImpulse.SetZero();
                m_angularImpulse = 0.0f;
            }
        }
Example #21
0
    internal override void InitVelocityConstraints(b2SolverData data)
    {
        m_indexB = m_bodyB.m_islandIndex;


        m_localCenterB = m_bodyB.m_sweep.localCenter;
        m_invMassB     = m_bodyB.m_invMass;
        m_invIB        = m_bodyB.m_invI;

        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 qB = new b2Rot(aB);

        float mass = m_bodyB.GetMass();

        // Frequency
        float omega = 2.0f * Settings.b2_pi * m_frequencyHz;

        // Damping coefficient
        float d = 2.0f * mass * m_dampingRatio * omega;

        // Spring stiffness
        float k = mass * (omega * omega);

        // magic formulas
        // gamma has units of inverse mass.
        // beta has units of inverse time.
        float h = data.step.dt;

        Debug.Assert(d + h * k > float.Epsilon);
        m_gamma = h * (d + h * k);
        if (m_gamma != 0.0f)
        {
            m_gamma = 1.0f / m_gamma;
        }
        m_beta = h * k * m_gamma;

        // Compute the effective mass matrix.


        m_rB = Utils.b2Mul(qB, m_localAnchorB - m_localCenterB);

        // K    = [(1/m1 + 1/m2) * eye(2) - skew(r1) * invI1 * skew(r1) - skew(r2) * invI2 * skew(r2)]
        //      = [1/m1+1/m2     0    ] + invI1 * [r1.y*r1.y -r1.x*r1.y] + invI2 * [r1.y*r1.y -r1.x*r1.y]
        //        [    0     1/m1+1/m2]           [-r1.x*r1.y r1.x*r1.x]           [-r1.x*r1.y r1.x*r1.x]
        b2Mat22 K = new b2Mat22();

        K.ex.x = m_invMassB + m_invIB * m_rB.y * m_rB.y + m_gamma;
        K.ex.y = -m_invIB * m_rB.x * m_rB.y;
        K.ey.x = K.ex.y;
        K.ey.y = m_invMassB + m_invIB * m_rB.x * m_rB.x + m_gamma;



        m_mass = K.GetInverse();



        m_C  = cB + m_rB - m_targetA;
        m_C *= m_beta;

        // Cheat with some damping
        wB *= 0.98f;

        if (data.step.warmStarting)
        {
            m_impulse *= data.step.dtRatio;
            vB        += m_invMassB * m_impulse;
            wB        += m_invIB * Utils.b2Cross(m_rB, m_impulse);
        }
        else
        {
            m_impulse.SetZero();
        }



        data.velocities[m_indexB].v = vB;
        data.velocities[m_indexB].w = wB;
    }
        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;

            b2Rot qA = new b2Rot(aA);
            b2Rot qB = new b2Rot(aB);

            float angularError  = 0.0f;
            float positionError = 0.0f;

            bool fixedRotation = (m_invIA + m_invIB == 0.0f);

            // Solve angular limit constraint.
            if (m_enableLimit && m_limitState != b2LimitState.e_inactiveLimit && fixedRotation == false)
            {
                float angle        = aB - aA - m_referenceAngle;
                float limitImpulse = 0.0f;

                if (m_limitState == b2LimitState.e_equalLimits)
                {
                    // Prevent large angular corrections
                    float C = b2Math.b2Clamp(angle - m_lowerAngle, -b2Settings.b2_maxAngularCorrection, b2Settings.b2_maxAngularCorrection);
                    limitImpulse = -m_motorMass * C;
                    angularError = b2Math.b2Abs(C);
                }
                else if (m_limitState == b2LimitState.e_atLowerLimit)
                {
                    float C = angle - m_lowerAngle;
                    angularError = -C;

                    // Prevent large angular corrections and allow some slop.
                    C            = b2Math.b2Clamp(C + b2Settings.b2_angularSlop, -b2Settings.b2_maxAngularCorrection, 0.0f);
                    limitImpulse = -m_motorMass * C;
                }
                else if (m_limitState == b2LimitState.e_atUpperLimit)
                {
                    float C = angle - m_upperAngle;
                    angularError = C;

                    // Prevent large angular corrections and allow some slop.
                    C            = b2Math.b2Clamp(C - b2Settings.b2_angularSlop, 0.0f, b2Settings.b2_maxAngularCorrection);
                    limitImpulse = -m_motorMass * C;
                }

                aA -= m_invIA * limitImpulse;
                aB += m_invIB * limitImpulse;
            }

            // Solve point-to-point constraint.
            {
                qA.Set(aA);
                qB.Set(aB);
                b2Vec2 rA = b2Math.b2Mul(qA, m_localAnchorA - m_localCenterA);
                b2Vec2 rB = b2Math.b2Mul(qB, m_localAnchorB - m_localCenterB);

                b2Vec2 C = cB + rB - cA - rA;
                positionError = C.Length;

                float mA = m_invMassA, mB = m_invMassB;
                float iA = m_invIA, iB = m_invIB;

                b2Mat22 K = new b2Mat22();
                K.exx = mA + mB + iA * rA.y * rA.y + iB * rB.y * rB.y;
                K.exy = -iA * rA.x * rA.y - iB * rB.x * rB.y;
                K.eyx = K.ex.y;
                K.eyy = mA + mB + iA * rA.x * rA.x + iB * rB.x * rB.x;

                b2Vec2 impulse = -K.Solve(C);

                cA -= mA * impulse;
                aA -= iA * b2Math.b2Cross(rA, impulse);

                cB += mB * impulse;
                aB += iB * b2Math.b2Cross(rB, impulse);
            }

            m_bodyA.InternalPosition.c = cA;
            m_bodyA.InternalPosition.a = aA;
            m_bodyB.InternalPosition.c = cB;
            m_bodyB.InternalPosition.a = aB;

            return(positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop);
        }
Example #23
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(b2Mat22 obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
Example #24
0
        public b2Mat22 GetInverse()
        {
            b2Mat22 ret = new b2Mat22(Box2DPINVOKE.b2Mat22_GetInverse(swigCPtr), true);

            return(ret);
        }
        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;

            float  aA = data.positions[m_indexA].a;
            b2Vec2 vA = data.velocities[m_indexA].v;
            float  wA = data.velocities[m_indexA].w;

            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);

            // Compute the effective mass matrix.
            m_rA = b2Math.b2Mul(qA, m_localAnchorA - m_localCenterA);
            m_rB = b2Math.b2Mul(qB, m_localAnchorB - m_localCenterB);

            // J = [-I -r1_skew I r2_skew]
            //     [ 0       -1 0       1]
            // r_skew = [-ry; rx]

            // Matlab
            // K = [ mA+r1y^2*iA+mB+r2y^2*iB,  -r1y*iA*r1x-r2y*iB*r2x,          -r1y*iA-r2y*iB]
            //     [  -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB,           r1x*iA+r2x*iB]
            //     [          -r1y*iA-r2y*iB,           r1x*iA+r2x*iB,                   iA+iB]

            float mA = m_invMassA, mB = m_invMassB;
            float iA = m_invIA, iB = m_invIB;

            b2Mat22 K = new b2Mat22();

            K.exx = mA + mB + iA * m_rA.y * m_rA.y + iB * m_rB.y * m_rB.y;
            K.exy = -iA * m_rA.x * m_rA.y - iB * m_rB.x * m_rB.y;
            K.eyx = K.ex.y;
            K.eyy = mA + mB + iA * m_rA.x * m_rA.x + iB * m_rB.x * m_rB.x;

            m_linearMass = K.GetInverse();

            m_angularMass = iA + iB;
            if (m_angularMass > 0.0f)
            {
                m_angularMass = 1.0f / m_angularMass;
            }

            if (data.step.warmStarting)
            {
                // Scale impulses to support a variable time step.
                m_linearImpulse  *= data.step.dtRatio;
                m_angularImpulse *= data.step.dtRatio;

                b2Vec2 P = new b2Vec2(m_linearImpulse.x, m_linearImpulse.y);
                vA -= mA * P;
                wA -= iA * (b2Math.b2Cross(m_rA, P) + m_angularImpulse);
                vB += mB * P;
                wB += iB * (b2Math.b2Cross(m_rB, P) + m_angularImpulse);
            }
            else
            {
                m_linearImpulse.SetZero();
                m_angularImpulse = 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;
        }