Advertisement
Guest User

b2RevoluteJoint

a guest
Apr 13th, 2018
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty.  In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software
  12. * in a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. * 2. Altered source versions must be plainly marked as such, and must not be
  15. * misrepresented as being the original software.
  16. * 3. This notice may not be removed or altered from any source distribution.
  17. */
  18.  
  19. package Box2D.Dynamics.Joints
  20. {
  21.     import Box2D.Common.Math.*;
  22.     import Box2D.Common.*;
  23.     import Box2D.Dynamics.*;
  24.    
  25.     import Box2D.Common.b2internal;
  26.  
  27.     use namespace b2internal;
  28.    
  29.     // Point-to-point constraint
  30.     // C = p2 - p1
  31.     // Cdot = v2 - v1
  32.     //      = v2 + cross(w2, r2) - v1 - cross(w1, r1)
  33.     // J = [-I -r1_skew I r2_skew ]
  34.     // Identity used:
  35.     // w k % (rx i + ry j) = w * (-ry i + rx j)
  36.    
  37.     // Motor constraint
  38.     // Cdot = w2 - w1
  39.     // J = [0 0 -1 0 0 1]
  40.     // K = invI1 + invI2
  41.    
  42.     /**
  43.     * A revolute joint constrains to bodies to share a common point while they
  44.     * are free to rotate about the point. The relative rotation about the shared
  45.     * point is the joint angle. You can limit the relative rotation with
  46.     * a joint limit that specifies a lower and upper angle. You can use a motor
  47.     * to drive the relative rotation about the shared point. A maximum motor torque
  48.     * is provided so that infinite forces are not generated.
  49.     * @see b2RevoluteJointDef
  50.     */
  51.     public class b2RevoluteJoint extends b2Joint
  52.     {
  53.         /** @inheritDoc */
  54.         public override function GetAnchorA(result:b2Vec2):void
  55.         {
  56.             return m_bodyA.GetWorldPoint(m_localAnchor1, result);
  57.         }
  58.        
  59.         /** @inheritDoc */
  60.         public override function GetAnchorB(result:b2Vec2):void
  61.         {
  62.             return m_bodyB.GetWorldPoint(m_localAnchor2, result);
  63.         }
  64.    
  65.         /** @inheritDoc */
  66.         public override function GetReactionForce(inv_dt:Number) :b2Vec2{
  67.             return new b2Vec2(inv_dt * m_impulse.x, inv_dt * m_impulse.y);
  68.         }
  69.         /** @inheritDoc */
  70.         public override function GetReactionTorque(inv_dt:Number) :Number{
  71.             return inv_dt * m_impulse.z;
  72.         }
  73.    
  74.         /**
  75.         * Get the current joint angle in radians.
  76.         */
  77.         public function GetJointAngle() :Number{
  78.             //b2Body* bA = m_bodyA;
  79.             //b2Body* bB = m_bodyB;
  80.             return m_bodyB.m_sweep.a - m_bodyA.m_sweep.a - m_referenceAngle;
  81.         }
  82.    
  83.         /**
  84.         * Get the current joint angle speed in radians per second.
  85.         */
  86.         public function GetJointSpeed() :Number{
  87.             //b2Body* bA = m_bodyA;
  88.             //b2Body* bB = m_bodyB;
  89.             return m_bodyB.m_angularVelocity - m_bodyA.m_angularVelocity;
  90.         }
  91.    
  92.         /**
  93.         * Is the joint limit enabled?
  94.         */
  95.         public function IsLimitEnabled() :Boolean{
  96.             return m_enableLimit;
  97.         }
  98.    
  99.         /**
  100.         * Enable/disable the joint limit.
  101.         */
  102.         public function EnableLimit(flag:Boolean) :void{
  103.             m_enableLimit = flag;
  104.         }
  105.    
  106.         /**
  107.         * Get the lower joint limit in radians.
  108.         */
  109.         public function GetLowerLimit() :Number{
  110.             return m_lowerAngle;
  111.         }
  112.    
  113.         /**
  114.         * Get the upper joint limit in radians.
  115.         */
  116.         public function GetUpperLimit() :Number{
  117.             return m_upperAngle;
  118.         }
  119.    
  120.         /**
  121.         * Set the joint limits in radians.
  122.         */
  123.         public function SetLimits(lower:Number, upper:Number) : void{
  124.             //b2Settings.b2Assert(lower <= upper);
  125.             m_lowerAngle = lower;
  126.             m_upperAngle = upper;
  127.         }
  128.    
  129.         /**
  130.         * Is the joint motor enabled?
  131.         */
  132.         public function IsMotorEnabled() :Boolean {
  133.             m_bodyA.SetAwake(true);
  134.             m_bodyB.SetAwake(true);
  135.             return m_enableMotor;
  136.         }
  137.    
  138.         /**
  139.         * Enable/disable the joint motor.
  140.         */
  141.         public function EnableMotor(flag:Boolean) :void{
  142.             m_enableMotor = flag;
  143.         }
  144.    
  145.         /**
  146.         * Set the motor speed in radians per second.
  147.         */
  148.         [Inline]
  149.         final public function SetMotorSpeed(speed:Number):void
  150.         {
  151.             m_bodyA.SetAwake(true);
  152.             m_bodyB.SetAwake(true);
  153.             m_motorSpeed = speed;
  154.         }
  155.    
  156.         /**
  157.         * Get the motor speed in radians per second.
  158.         */
  159.         public function GetMotorSpeed() :Number{
  160.             return m_motorSpeed;
  161.         }
  162.    
  163.         /**
  164.         * Set the maximum motor torque, usually in N-m.
  165.         */
  166.         [Inline]
  167.         final public function SetMaxMotorTorque(torque:Number):void
  168.         {
  169.             m_maxMotorTorque = torque;
  170.         }
  171.    
  172.         public function GetMaxMotorTorque():Number
  173.         {
  174.             return m_maxMotorTorque;
  175.         }
  176.        
  177.         /**
  178.         * Get the current motor torque, usually in N-m.
  179.         */
  180.         public function GetMotorTorque():Number
  181.         {
  182.             return m_maxMotorTorque;
  183.         }
  184.    
  185.         //--------------- Internals Below -------------------
  186.    
  187.         /** @private */
  188.         public function b2RevoluteJoint(def:b2RevoluteJointDef){
  189.             super(def);
  190.            
  191.             //m_localAnchor1 = def->localAnchorA;
  192.             m_localAnchor1.SetV(def.localAnchorA);
  193.             //m_localAnchor2 = def->localAnchorB;
  194.             m_localAnchor2.SetV(def.localAnchorB);
  195.            
  196.             m_referenceAngle = def.referenceAngle;
  197.            
  198.             m_impulse.SetZero();
  199.             m_motorImpulse = 0.0;
  200.            
  201.             m_lowerAngle = def.lowerAngle;
  202.             m_upperAngle = def.upperAngle;
  203.             m_maxMotorTorque = def.maxMotorTorque;
  204.             m_motorSpeed = def.motorSpeed;
  205.             m_enableLimit = def.enableLimit;
  206.             m_enableMotor = def.enableMotor;
  207.             m_limitState = e_inactiveLimit;
  208.         }
  209.    
  210.         // internal vars
  211.         private var K:b2Mat22 = new b2Mat22();
  212.         private var K1:b2Mat22 = new b2Mat22();
  213.         private var K2:b2Mat22 = new b2Mat22();
  214.         private var K3:b2Mat22 = new b2Mat22();
  215.        
  216.         private var tMat:b2Mat22;
  217.         private var tX:Number;
  218.        
  219.         private var r1X:Number;
  220.         private var r1Y:Number;
  221.        
  222.         private var r2X:Number;
  223.         private var r2Y:Number;
  224.  
  225.         private var jointAngle:Number;
  226.        
  227.         private var PX:Number;
  228.         private var PY:Number;
  229.        
  230.         private var newImpulse:Number;
  231.        
  232.         private var v1:b2Vec2;
  233.         private var v2:b2Vec2;
  234.        
  235.         private var w1:Number;
  236.         private var w2:Number;
  237.        
  238.         private var Cdot:Number;
  239.         private var impulse:Number;
  240.         private var oldImpulse:Number;
  241.         private var maxImpulse:Number;
  242.        
  243.         private var Cdot1X:Number;
  244.         private var Cdot1Y:Number;
  245.         private var Cdot2:Number;
  246.        
  247.         private var CdotX:Number;
  248.         private var CdotY:Number;
  249.        
  250.         private var angularError:Number;
  251.         private var positionError:Number;
  252.        
  253.         private var oldLimitImpulse:Number;
  254.         private var C:Number;
  255.        
  256.         private var impulseX:Number;
  257.         private var impulseY:Number;
  258.        
  259.         private var angle:Number;
  260.         private var limitImpulse:Number;
  261.        
  262.         private var CX:Number;
  263.         private var CY:Number;
  264.         private var CLengthSquared:Number;
  265.         private var CLength:Number;
  266.        
  267.         private var invMass1:Number;
  268.         private var invMass2:Number;
  269.         private var invI1:Number;
  270.         private var invI2:Number;
  271.        
  272.         private var uX:Number;
  273.         private var uY:Number;
  274.         private var k:Number;
  275.         private var m:Number;
  276.        
  277.        
  278.         b2internal override function InitVelocityConstraints(step:b2TimeStep):void
  279.         {
  280.             tMat = m_bodyA.m_xf.R;
  281.             r1X = m_localAnchor1.x - m_bodyA.m_sweep.localCenter.x;
  282.             r1Y = m_localAnchor1.y - m_bodyA.m_sweep.localCenter.y;
  283.            
  284.             tX =  (tMat.col1.x * r1X + tMat.col2.x * r1Y);
  285.             r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
  286.             r1X = tX;
  287.  
  288.             tMat = m_bodyB.m_xf.R;
  289.            
  290.             r2X = m_localAnchor2.x - m_bodyB.m_sweep.localCenter.x;
  291.             r2Y = m_localAnchor2.y - m_bodyB.m_sweep.localCenter.y;
  292.            
  293.             tX =  (tMat.col1.x * r2X + tMat.col2.x * r2Y);
  294.             r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
  295.             r2X = tX;
  296.  
  297.             m_mass.col1.x = m_bodyA.m_invMass + m_bodyB.m_invMass + r1Y * r1Y * m_bodyA.m_invI + r2Y * r2Y * m_bodyB.m_invI;
  298.             m_mass.col2.x = -r1Y * r1X * m_bodyA.m_invI - r2Y * r2X * m_bodyB.m_invI;
  299.             m_mass.col3.x = -r1Y * m_bodyA.m_invI - r2Y * m_bodyB.m_invI;
  300.             m_mass.col1.y = m_mass.col2.x;
  301.             m_mass.col2.y = m_bodyA.m_invMass + m_bodyB.m_invMass + r1X * r1X * m_bodyA.m_invI + r2X * r2X * m_bodyB.m_invI;
  302.             m_mass.col3.y = r1X * m_bodyA.m_invI + r2X * m_bodyB.m_invI;
  303.             m_mass.col1.z = m_mass.col3.x;
  304.             m_mass.col2.z = m_mass.col3.y;
  305.             m_mass.col3.z = m_bodyA.m_invI + m_bodyB.m_invI;
  306.            
  307.             m_motorMass = 1.0 / (m_bodyA.m_invI + m_bodyB.m_invI);
  308.            
  309.             if (m_enableMotor == false)
  310.             {
  311.                 m_motorImpulse = 0.0;
  312.             }
  313.            
  314.             if (m_enableLimit)
  315.             {
  316.                 jointAngle = m_bodyB.m_sweep.a - m_bodyA.m_sweep.a - m_referenceAngle;
  317.                
  318.                 if (b2Math.Abs(m_upperAngle - m_lowerAngle) < 2.0 * b2Settings.b2_angularSlop)
  319.                 {
  320.                     m_limitState = e_equalLimits;
  321.                 }
  322.                 else if (jointAngle <= m_lowerAngle)
  323.                 {
  324.                     if (m_limitState != e_atLowerLimit)
  325.                     {
  326.                         m_impulse.z = 0.0;
  327.                     }
  328.                     m_limitState = e_atLowerLimit;
  329.                 }
  330.                 else if (jointAngle >= m_upperAngle)
  331.                 {
  332.                     if (m_limitState != e_atUpperLimit)
  333.                     {
  334.                         m_impulse.z = 0.0;
  335.                     }
  336.                     m_limitState = e_atUpperLimit;
  337.                 }
  338.                 else
  339.                 {
  340.                     m_limitState = e_inactiveLimit;
  341.                     m_impulse.z = 0.0;
  342.                 }
  343.             }
  344.             else
  345.             {
  346.                 m_limitState = e_inactiveLimit;
  347.             }
  348.            
  349.             // Warm starting.
  350.             if (step.warmStarting)
  351.             {
  352.                 //Scale impulses to support a variable time step
  353.                 m_impulse.x *= step.dtRatio;
  354.                 m_impulse.y *= step.dtRatio;
  355.                 m_motorImpulse *= step.dtRatio;
  356.  
  357.                 PX = m_impulse.x;
  358.                 PY = m_impulse.y;
  359.  
  360.                 //bA->m_linearVelocity -= m1 * P;
  361.                 m_bodyA.m_linearVelocity.x -= m_bodyA.m_invMass * PX;
  362.                 m_bodyA.m_linearVelocity.y -= m_bodyA.m_invMass * PY;
  363.  
  364.                 m_bodyA.m_angularVelocity -= m_bodyA.m_invI * ((r1X * PY - r1Y * PX) + m_motorImpulse + m_impulse.z);
  365.                
  366.                 //bB->m_linearVelocity += m2 * P;
  367.                 m_bodyB.m_linearVelocity.x += m_bodyB.m_invMass * PX;
  368.                 m_bodyB.m_linearVelocity.y += m_bodyB.m_invMass * PY;
  369.  
  370.                 m_bodyB.m_angularVelocity += m_bodyB.m_invI * ((r2X * PY - r2Y * PX) + m_motorImpulse + m_impulse.z);
  371.             }
  372.             else
  373.             {
  374.                 m_impulse.SetZero();
  375.                 m_motorImpulse = 0.0;
  376.             }
  377.         }
  378.        
  379.         private var impulse3:b2Vec3 = new b2Vec3();
  380.         private var impulse2:b2Vec2 = new b2Vec2();
  381.         private var reduced:b2Vec2 = new b2Vec2();
  382.    
  383.         [Inline]
  384.         final b2internal override function SolveVelocityConstraints(step:b2TimeStep):void
  385.         {
  386.             v1 = m_bodyA.m_linearVelocity;
  387.             v2 = m_bodyB.m_linearVelocity;
  388.            
  389.             w1 = m_bodyA.m_angularVelocity;
  390.             w2 = m_bodyB.m_angularVelocity;
  391.  
  392.             // Solve motor constraint.
  393.             if(m_enableMotor && m_limitState != e_equalLimits)
  394.             {
  395.                 Cdot = w2 - w1 - m_motorSpeed;
  396.                 impulse = m_motorMass * (-Cdot);
  397.                 oldImpulse = m_motorImpulse;
  398.                 maxImpulse = step.dt * m_maxMotorTorque;
  399.                
  400.                 m_motorImpulse = b2Math.Clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse);
  401.                 impulse = m_motorImpulse - oldImpulse;
  402.                
  403.                 w1 -= m_bodyA.m_invI * impulse;
  404.                 w2 += m_bodyB.m_invI * impulse;
  405.             }
  406.            
  407.             // Solve limit constraint.
  408.             if (m_enableLimit && m_limitState !== e_inactiveLimit)
  409.             {
  410.                 tMat = m_bodyA.m_xf.R;
  411.                 r1X = m_localAnchor1.x - m_bodyA.m_sweep.localCenter.x;
  412.                 r1Y = m_localAnchor1.y - m_bodyA.m_sweep.localCenter.y;
  413.                 tX =  (tMat.col1.x * r1X + tMat.col2.x * r1Y);
  414.                 r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
  415.                 r1X = tX;
  416.  
  417.                 tMat = m_bodyB.m_xf.R;
  418.                 r2X = m_localAnchor2.x - m_bodyB.m_sweep.localCenter.x;
  419.                 r2Y = m_localAnchor2.y - m_bodyB.m_sweep.localCenter.y;
  420.                 tX =  (tMat.col1.x * r2X + tMat.col2.x * r2Y);
  421.                 r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
  422.                 r2X = tX;
  423.  
  424.                 Cdot1X = v2.x + (-w2 * r2Y) - v1.x - (-w1 * r1Y);
  425.                 Cdot1Y = v2.y + (w2 * r2X) - v1.y - (w1 * r1X);
  426.                 Cdot2  = w2 - w1;
  427.                
  428.                 m_mass.Solve33(impulse3, -Cdot1X, -Cdot1Y, -Cdot2);
  429.                
  430.                 if (m_limitState === e_equalLimits)
  431.                 {
  432.                     m_impulse.Add(impulse3);
  433.                 }
  434.                 else if (m_limitState === e_atLowerLimit)
  435.                 {
  436.                     newImpulse = m_impulse.z + impulse3.z;
  437.  
  438.                     if (newImpulse < 0.0)
  439.                     {
  440.                         m_mass.Solve22(reduced, -Cdot1X, -Cdot1Y);
  441.                         impulse3.x = reduced.x;
  442.                         impulse3.y = reduced.y;
  443.                         impulse3.z = -m_impulse.z;
  444.                         m_impulse.x += reduced.x;
  445.                         m_impulse.y += reduced.y;
  446.                         m_impulse.z = 0.0;
  447.                     }
  448.                 }
  449.                 else if (m_limitState === e_atUpperLimit)
  450.                 {
  451.                     newImpulse = m_impulse.z + impulse3.z;
  452.  
  453.                     if (newImpulse > 0.0)
  454.                     {
  455.                         m_mass.Solve22(reduced, -Cdot1X, -Cdot1Y);
  456.                         impulse3.x = reduced.x;
  457.                         impulse3.y = reduced.y;
  458.                         impulse3.z = -m_impulse.z;
  459.                         m_impulse.x += reduced.x;
  460.                         m_impulse.y += reduced.y;
  461.                         m_impulse.z = 0.0;
  462.                     }
  463.                 }
  464.                
  465.                 v1.x -= m_bodyA.m_invMass * impulse3.x;
  466.                 v1.y -= m_bodyA.m_invMass * impulse3.y;
  467.                 w1 -= m_bodyA.m_invI * (r1X * impulse3.y - r1Y * impulse3.x + impulse3.z);
  468.                
  469.                 v2.x += m_bodyB.m_invMass * impulse3.x;
  470.                 v2.y += m_bodyB.m_invMass * impulse3.y;
  471.                 w2 += m_bodyB.m_invI * (r2X * impulse3.y - r2Y * impulse3.x + impulse3.z);
  472.             }
  473.             else
  474.             {
  475.                 //b2Vec2 r1 = b2Mul(bA->m_xf.R, m_localAnchor1 - bA->GetLocalCenter());
  476.                 tMat = m_bodyA.m_xf.R;
  477.                 r1X = m_localAnchor1.x - m_bodyA.m_sweep.localCenter.x;
  478.                 r1Y = m_localAnchor1.y - m_bodyA.m_sweep.localCenter.y;
  479.                 tX =  (tMat.col1.x * r1X + tMat.col2.x * r1Y);
  480.                 r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
  481.                 r1X = tX;
  482.                 //b2Vec2 r2 = b2Mul(bB->m_xf.R, m_localAnchor2 - bB->GetLocalCenter());
  483.                 tMat = m_bodyB.m_xf.R;
  484.                 r2X = m_localAnchor2.x - m_bodyB.m_sweep.localCenter.x;
  485.                 r2Y = m_localAnchor2.y - m_bodyB.m_sweep.localCenter.y;
  486.                 tX =  (tMat.col1.x * r2X + tMat.col2.x * r2Y);
  487.                 r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
  488.                 r2X = tX;
  489.  
  490.                 CdotX = v2.x + ( -w2 * r2Y) - v1.x - ( -w1 * r1Y);
  491.                 CdotY = v2.y + (w2 * r2X) - v1.y - (w1 * r1X);
  492.                
  493.                 m_mass.Solve22(impulse2, -CdotX, -CdotY);
  494.                
  495.                 m_impulse.x += impulse2.x;
  496.                 m_impulse.y += impulse2.y;
  497.                
  498.                 v1.x -= m_bodyA.m_invMass * impulse2.x;
  499.                 v1.y -= m_bodyA.m_invMass * impulse2.y;
  500.                 //w1 -= i1 * b2Cross(r1, impulse2);
  501.                 w1 -= m_bodyA.m_invI * ( r1X * impulse2.y - r1Y * impulse2.x);
  502.                
  503.                 v2.x += m_bodyB.m_invMass * impulse2.x;
  504.                 v2.y += m_bodyB.m_invMass * impulse2.y;
  505.                 //w2 += i2 * b2Cross(r2, impulse2);
  506.                 w2 += m_bodyB.m_invI * ( r2X * impulse2.y - r2Y * impulse2.x);
  507.             }
  508.            
  509.             m_bodyA.m_linearVelocity.SetV(v1);
  510.             m_bodyA.m_angularVelocity = w1;
  511.             m_bodyB.m_linearVelocity.SetV(v2);
  512.             m_bodyB.m_angularVelocity = w2;
  513.         }
  514.        
  515.         private static var tImpulse:b2Vec2 = new b2Vec2();
  516.        
  517.         [Inline]
  518.         final b2internal override function SolvePositionConstraints(baumgarte:Number):Boolean
  519.         {
  520.             angularError = 0.0;
  521.             positionError = 0.0;
  522.            
  523.             // Solve angular limit constraint.
  524.             if (m_enableLimit && m_limitState !== e_inactiveLimit)
  525.             {
  526.                 angle = m_bodyB.m_sweep.a - m_bodyA.m_sweep.a - m_referenceAngle;
  527.                 limitImpulse = 0.0;
  528.                
  529.                 if (m_limitState == e_equalLimits)
  530.                 {
  531.                     // Prevent large angular corrections
  532.                     C = b2Math.Clamp(angle - m_lowerAngle, -b2Settings.b2_maxAngularCorrection, b2Settings.b2_maxAngularCorrection);
  533.                     limitImpulse = -m_motorMass * C;
  534.                     angularError = b2Math.Abs(C);
  535.                 }
  536.                 else if (m_limitState === e_atLowerLimit)
  537.                 {
  538.                     C = angle - m_lowerAngle;
  539.                     angularError = -C;
  540.                    
  541.                     // Prevent large angular corrections and allow some slop.
  542.                     C = b2Math.Clamp(C + b2Settings.b2_angularSlop, -b2Settings.b2_maxAngularCorrection, 0.0);
  543.                     limitImpulse = -m_motorMass * C;
  544.                 }
  545.                 else if (m_limitState === e_atUpperLimit)
  546.                 {
  547.                     C = angle - m_upperAngle;
  548.                     angularError = C;
  549.                    
  550.                     // Prevent large angular corrections and allow some slop.
  551.                     C = b2Math.Clamp(C - b2Settings.b2_angularSlop, 0.0, b2Settings.b2_maxAngularCorrection);
  552.                     limitImpulse = -m_motorMass * C;
  553.                 }
  554.                
  555.                 m_bodyA.m_sweep.a -= m_bodyA.m_invI * limitImpulse;
  556.                 m_bodyB.m_sweep.a += m_bodyB.m_invI * limitImpulse;
  557.                
  558.                 m_bodyA.SynchronizeTransform();
  559.                 m_bodyB.SynchronizeTransform();
  560.             }
  561.            
  562.             // Solve point-to-point constraint
  563.             {
  564.                 //b2Vec2 r1 = b2Mul(bA->m_xf.R, m_localAnchor1 - bA->GetLocalCenter());
  565.                 tMat = m_bodyA.m_xf.R;
  566.                 r1X = m_localAnchor1.x - m_bodyA.m_sweep.localCenter.x;
  567.                 r1Y = m_localAnchor1.y - m_bodyA.m_sweep.localCenter.y;
  568.                
  569.                 tX =  (tMat.col1.x * r1X + tMat.col2.x * r1Y);
  570.                 r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
  571.                
  572.                 r1X = tX;
  573.                
  574.                 tMat = m_bodyB.m_xf.R;
  575.                 r2X = m_localAnchor2.x - m_bodyB.m_sweep.localCenter.x;
  576.                 r2Y = m_localAnchor2.y - m_bodyB.m_sweep.localCenter.y;
  577.                 tX =  (tMat.col1.x * r2X + tMat.col2.x * r2Y);
  578.                 r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
  579.                 r2X = tX;
  580.                
  581.                 //b2Vec2 C = bB->m_sweep.c + r2 - bA->m_sweep.c - r1;
  582.                 CX = m_bodyB.m_sweep.c.x + r2X - m_bodyA.m_sweep.c.x - r1X;
  583.                 CY = m_bodyB.m_sweep.c.y + r2Y - m_bodyA.m_sweep.c.y - r1Y;
  584.  
  585.                 CLengthSquared = CX * CX + CY * CY;
  586.                 CLength = Math.sqrt(CLengthSquared);
  587.  
  588.                 positionError = CLength;
  589.                
  590.                 invMass1 = m_bodyA.m_invMass;
  591.                 invMass2 = m_bodyB.m_invMass;
  592.                 invI1 = m_bodyA.m_invI;
  593.                 invI2 = m_bodyB.m_invI;
  594.  
  595.                 if (CLengthSquared > k_allowedStretch * k_allowedStretch)
  596.                 {
  597.                     uX = CX / CLength;
  598.                     uY = CY / CLength;
  599.                     k = invMass1 + invMass2;
  600.                     m = 1.0 / k;
  601.                    
  602.                     impulseX = m * ( -CX);
  603.                     impulseY = m * ( -CY);
  604.  
  605.                     m_bodyA.m_sweep.c.x -= k_beta * invMass1 * impulseX;
  606.                     m_bodyA.m_sweep.c.y -= k_beta * invMass1 * impulseY;
  607.                     m_bodyB.m_sweep.c.x += k_beta * invMass2 * impulseX;
  608.                     m_bodyB.m_sweep.c.y += k_beta * invMass2 * impulseY;
  609.                    
  610.                     //C = bB->m_sweep.c + r2 - bA->m_sweep.c - r1;
  611.                     CX = m_bodyB.m_sweep.c.x + r2X - m_bodyA.m_sweep.c.x - r1X;
  612.                     CY = m_bodyB.m_sweep.c.y + r2Y - m_bodyA.m_sweep.c.y - r1Y;
  613.                 }
  614.                
  615.                 //b2Mat22 K1;
  616.                 K1.col1.x = invMass1 + invMass2;    K1.col2.x = 0.0;
  617.                 K1.col1.y = 0.0;                    K1.col2.y = invMass1 + invMass2;
  618.                
  619.                 //b2Mat22 K2;
  620.                 K2.col1.x =  invI1 * r1Y * r1Y; K2.col2.x = -invI1 * r1X * r1Y;
  621.                 K2.col1.y = -invI1 * r1X * r1Y; K2.col2.y =  invI1 * r1X * r1X;
  622.                
  623.                 //b2Mat22 K3;
  624.                 K3.col1.x =  invI2 * r2Y * r2Y;     K3.col2.x = -invI2 * r2X * r2Y;
  625.                 K3.col1.y = -invI2 * r2X * r2Y;     K3.col2.y =  invI2 * r2X * r2X;
  626.                
  627.                 //b2Mat22 K = K1 + K2 + K3;
  628.                 K.SetM(K1);
  629.                 K.AddM(K2);
  630.                 K.AddM(K3);
  631.                 //b2Vec2 impulse = K.Solve(-C);
  632.                 K.Solve(tImpulse, -CX, -CY);
  633.                 impulseX = tImpulse.x;
  634.                 impulseY = tImpulse.y;
  635.                
  636.                 //bA.m_sweep.c -= bA.m_invMass * impulse;
  637.                 m_bodyA.m_sweep.c.x -= m_bodyA.m_invMass * impulseX;
  638.                 m_bodyA.m_sweep.c.y -= m_bodyA.m_invMass * impulseY;
  639.                 //bA.m_sweep.a -= bA.m_invI * b2Cross(r1, impulse);
  640.                 m_bodyA.m_sweep.a -= m_bodyA.m_invI * (r1X * impulseY - r1Y * impulseX);
  641.                
  642.                 //bB.m_sweep.c += bB.m_invMass * impulse;
  643.                 m_bodyB.m_sweep.c.x += m_bodyB.m_invMass * impulseX;
  644.                 m_bodyB.m_sweep.c.y += m_bodyB.m_invMass * impulseY;
  645.                 //bB.m_sweep.a += bB.m_invI * b2Cross(r2, impulse);
  646.                 m_bodyB.m_sweep.a += m_bodyB.m_invI * (r2X * impulseY - r2Y * impulseX);
  647.                
  648.                 m_bodyA.SynchronizeTransform();
  649.                 m_bodyB.SynchronizeTransform();
  650.             }
  651.    
  652.             return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop;
  653.         }
  654.  
  655.         private static const k_beta:Number = 0.5;
  656.         private static const k_allowedStretch:Number = 10.0 * b2Settings.b2_linearSlop;
  657.        
  658.         b2internal var m_localAnchor1:b2Vec2 = new b2Vec2(); // relative
  659.         b2internal var m_localAnchor2:b2Vec2 = new b2Vec2();
  660.  
  661.         private var m_impulse:b2Vec3 = new b2Vec3();
  662.         private var m_motorImpulse:Number;
  663.    
  664.         private var m_mass:b2Mat33 = new b2Mat33();     // effective mass for point-to-point constraint.
  665.         private var m_motorMass:Number; // effective mass for motor/limit angular constraint.
  666.         private var m_enableMotor:Boolean;
  667.         private var m_maxMotorTorque:Number;
  668.         private var m_motorSpeed:Number;
  669.    
  670.         private var m_enableLimit:Boolean;
  671.         private var m_referenceAngle:Number;
  672.         private var m_lowerAngle:Number;
  673.         private var m_upperAngle:Number;
  674.         private var m_limitState:int;
  675.     };
  676. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement