Advertisement
Guest User

Untitled

a guest
Apr 18th, 2019
177
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.Collision
  20. {
  21.     import Box2D.Collision.Shapes.b2CircleShape;
  22.     import Box2D.Collision.Shapes.b2PolygonShape;
  23.     import Box2D.Common.b2Settings;
  24.     import Box2D.Common.Math.b2Mat22;
  25.     import Box2D.Common.Math.b2Transform;
  26.     import Box2D.Common.Math.b2Vec2;
  27.    
  28.     /**
  29.     * @private
  30.     */
  31.     public class b2Collision
  32.     {
  33.        
  34.         // Null feature
  35.         static public const b2_nullFeature:uint = 0x000000ff;//UCHAR_MAX;
  36.  
  37.        
  38.        
  39.         private static var csl_cv:ClipVertex;
  40.         private static var csl_numOut:int;
  41.        
  42.         private static var csl_vIn0:b2Vec2;
  43.         private static var csl_vIn1:b2Vec2;
  44.        
  45.         private static var csl_distance0:Number;
  46.         private static var csl_distance1:Number;
  47.  
  48.         private static var csl_interp:Number;
  49.         private static var csl_tVec:b2Vec2;
  50.         private static var csl_cv2:ClipVertex;
  51.  
  52.         private static var vInCurrent:ClipVertex;
  53.         private static var vOutCurrent:ClipVertex;
  54.        
  55.         // Sutherland-Hodgman clipping.
  56.  
  57.         [Inline]
  58.         static public function ClipSegmentToLine(vOut:Vector.<ClipVertex>, vIn:Vector.<ClipVertex>, normal:b2Vec2, offset:Number):int
  59.         {
  60.             csl_cv = null;
  61.            
  62.             // Start with no output points
  63.             csl_numOut = 0;
  64.            
  65.             csl_cv = vIn[0];
  66.            
  67.             csl_vIn0 = csl_cv.v;
  68.            
  69.             csl_cv = vIn[1];
  70.            
  71.             csl_vIn1 = csl_cv.v;
  72.            
  73.             // Calculate the distance of end points to the line
  74.             csl_distance0 = normal.x * csl_vIn0.x + normal.y * csl_vIn0.y - offset;
  75.             csl_distance1 = normal.x * csl_vIn1.x + normal.y * csl_vIn1.y - offset;
  76.            
  77.             // If the points are behind the plane
  78.             if(csl_distance0 <= b2Settings.DECIMAL_ZERO)
  79.             {
  80.                 vInCurrent = vIn[0];
  81.                
  82.                 vOutCurrent = vOut[csl_numOut++];
  83.                 vOutCurrent.v.x = vInCurrent.v.x;
  84.                 vOutCurrent.v.y = vInCurrent.v.y;
  85.                
  86.                 vOutCurrent.id.Set(vInCurrent.id);
  87.             }
  88.            
  89.             if(csl_distance1 <= b2Settings.DECIMAL_ZERO)
  90.             {
  91.                 vInCurrent = vIn[1];
  92.                 vOutCurrent = vOut[csl_numOut++];
  93.                
  94.                 vOutCurrent.v.x = vInCurrent.v.x;
  95.                 vOutCurrent.v.y = vInCurrent.v.y;
  96.                
  97.                 vOutCurrent.id.Set(vInCurrent.id);
  98.             }
  99.            
  100.             // If the points are on different sides of the plane
  101.             if (csl_distance0 * csl_distance1 < b2Settings.DECIMAL_ZERO)
  102.             {
  103.                 // Find intersection point of edge and plane
  104.                 csl_interp = csl_distance0 / (csl_distance0 - csl_distance1);
  105.                
  106.                 // expanded for performance
  107.                 // vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v);
  108.                 csl_cv = vOut[csl_numOut];
  109.                
  110.                 csl_tVec = csl_cv.v;
  111.                
  112.                 csl_tVec.x = csl_vIn0.x + csl_interp * (csl_vIn1.x - csl_vIn0.x);
  113.                 csl_tVec.y = csl_vIn0.y + csl_interp * (csl_vIn1.y - csl_vIn0.y);
  114.                
  115.                 csl_cv = vOut[csl_numOut];
  116.                
  117.                 csl_cv2 = null;
  118.                
  119.                 if(csl_distance0 > b2Settings.DECIMAL_ZERO)
  120.                 {
  121.                     csl_cv2 = vIn[0];
  122.                     csl_cv.id = csl_cv2.id;
  123.                 }
  124.                 else
  125.                 {
  126.                     csl_cv2 = vIn[1];
  127.                     csl_cv.id = csl_cv2.id;
  128.                 }
  129.                
  130.                 ++csl_numOut;
  131.             }
  132.            
  133.             return csl_numOut;
  134.         }
  135.        
  136.        
  137.  
  138.         private static var es_vertices1:Array;
  139.         private static var es_normals1:Array;
  140.        
  141.         private static var es_count2:int;
  142.         private static var es_vertices2:Array;
  143.  
  144.         private static var es_tMat:b2Mat22;
  145.         private static var es_tVec:b2Vec2;
  146.  
  147.         private static var es_normal1WorldX:Number;
  148.         private static var es_normal1WorldY:Number;
  149.  
  150.         private static var es_normal1X:Number;
  151.         private static var es_normal1Y:Number;
  152.  
  153.         private static var es_index:int;
  154.         private static var es_minDot:Number;
  155.         private static var es_i:int
  156.         private static var es_dot:Number;
  157.  
  158.         private static var es_v1X:Number;
  159.         private static var es_v1Y:Number;
  160.  
  161.         private static var es_v2X:Number;
  162.         private static var es_v2Y:Number;  
  163.        
  164.         // Find the separation between poly1 and poly2 for a give edge normal on poly1.
  165.        
  166.         [Inline]
  167.         static public function EdgeSeparation(  poly1:b2PolygonShape, xf1:b2Transform, edge1:int,
  168.                                                 poly2:b2PolygonShape, xf2:b2Transform):Number
  169.         {
  170.             es_vertices1 = poly1.m_vertices;
  171.             es_normals1 = poly1.m_normals;
  172.            
  173.             es_count2 = poly2.m_vertexCount;
  174.             es_vertices2 = poly2.m_vertices;
  175.  
  176.             es_tMat = null;
  177.             es_tVec = null;
  178.            
  179.             // Convert normal from poly1's frame into poly2's frame.
  180.             //b2Vec2 normal1World = b2Mul(xf1.R, normals1[edge1]);
  181.             es_tMat = xf1.R;
  182.             es_tVec = es_normals1[edge1];
  183.            
  184.             es_normal1WorldX = (es_tMat.col1.x * es_tVec.x + es_tMat.col2.x * es_tVec.y);
  185.             es_normal1WorldY = (es_tMat.col1.y * es_tVec.x + es_tMat.col2.y * es_tVec.y);
  186.  
  187.             es_tMat = xf2.R;
  188.            
  189.             es_normal1X = (es_tMat.col1.x * es_normal1WorldX + es_tMat.col1.y * es_normal1WorldY);
  190.             es_normal1Y = (es_tMat.col2.x * es_normal1WorldX + es_tMat.col2.y * es_normal1WorldY);
  191.            
  192.             // Find support vertex on poly2 for -normal.
  193.             es_index = 0;
  194.             es_minDot = Number.MAX_VALUE;
  195.  
  196.             for(es_i = 0; es_i < es_count2; ++es_i)
  197.             {
  198.                 es_tVec = es_vertices2[es_i];
  199.  
  200.                 es_dot = es_tVec.x * es_normal1X + es_tVec.y * es_normal1Y;
  201.                
  202.                 if(es_dot < es_minDot)
  203.                 {
  204.                     es_minDot = es_dot;
  205.                     es_index = es_i;
  206.                 }
  207.             }
  208.            
  209.             //b2Vec2 v1 = b2Mul(xf1, vertices1[edge1]);
  210.             es_tVec = es_vertices1[edge1];
  211.             es_tMat = xf1.R;
  212.  
  213.             es_dot = xf1.position.x + (es_tMat.col1.x * es_tVec.x + es_tMat.col2.x * es_tVec.y);
  214.             es_v1Y = xf1.position.y + (es_tMat.col1.y * es_tVec.x + es_tMat.col2.y * es_tVec.y);
  215.  
  216.             es_tVec = es_vertices2[es_index];
  217.             es_tMat = xf2.R;
  218.            
  219.             es_v2X = xf2.position.x + (es_tMat.col1.x * es_tVec.x + es_tMat.col2.x * es_tVec.y);
  220.             es_v2Y = xf2.position.y + (es_tMat.col1.y * es_tVec.x + es_tMat.col2.y * es_tVec.y);
  221.            
  222.             es_v2X -= es_dot;
  223.             es_v2Y -= es_v1Y;
  224.            
  225.             es_vertices1 = null;
  226.             es_normals1 = null;
  227.            
  228.             return es_v2X * es_normal1WorldX + es_v2Y * es_normal1WorldY;
  229.         }
  230.        
  231.        
  232.        
  233.        
  234.         // Find the max separation between poly1 and poly2 using edge normals
  235.         // from poly1.
  236.        
  237.        
  238.         private static var fms_count1:int;
  239.         private static var fms_normals1:Array;
  240.        
  241.         private static var fms_tVec:b2Vec2;
  242.         private static var fms_tMat:b2Mat22;
  243.        
  244.         private static var fms_dX:Number;
  245.         private static var fms_dY:Number;
  246.  
  247.         private static var fms_dLocal1X:Number;
  248.         private static var fms_dLocal1Y:Number;
  249.        
  250.         private static var fms_edge:int;
  251.         private static var fms_maxDot:Number;
  252.         private static var fms_i:int
  253.         private static var fms_dot:Number;
  254.  
  255.         private static var fms_s:Number;
  256.  
  257.         private static var fms_prevEdge:int;
  258.         private static var fms_sPrev:Number;
  259.        
  260.         private static var fms_nextEdge:int;
  261.         private static var fms_sNext:Number;
  262.        
  263.        
  264.         private static var fms_bestEdge:int;
  265.         private static var fms_bestSeparation:Number;
  266.         private static var fms_increment:int;
  267.        
  268.         [Inline]
  269.         static public function FindMaxSeparation(edgeIndex:Vector.<int>,
  270.                                                 poly1:b2PolygonShape, xf1:b2Transform,
  271.                                                 poly2:b2PolygonShape, xf2:b2Transform):Number
  272.         {
  273.             fms_count1 = poly1.m_vertexCount;
  274.             fms_normals1 = poly1.m_normals;
  275.            
  276.             fms_tVec = null;
  277.             fms_tMat = null;
  278.            
  279.             // Vector pointing from the centroid of poly1 to the centroid of poly2.
  280.             //b2Vec2 d = b2Mul(xf2, poly2->m_centroid) - b2Mul(xf1, poly1->m_centroid);
  281.             fms_tMat = xf2.R;
  282.             fms_tVec = poly2.m_centroid;
  283.            
  284.             fms_dX = xf2.position.x + (fms_tMat.col1.x * fms_tVec.x + fms_tMat.col2.x * fms_tVec.y);
  285.             fms_dY = xf2.position.y + (fms_tMat.col1.y * fms_tVec.x + fms_tMat.col2.y * fms_tVec.y);
  286.            
  287.             fms_tMat = xf1.R;
  288.             fms_tVec = poly1.m_centroid;
  289.            
  290.             fms_dX -= xf1.position.x + (fms_tMat.col1.x * fms_tVec.x + fms_tMat.col2.x * fms_tVec.y);
  291.             fms_dY -= xf1.position.y + (fms_tMat.col1.y * fms_tVec.x + fms_tMat.col2.y * fms_tVec.y);
  292.            
  293.             //b2Vec2 dLocal1 = b2MulT(xf1.R, d);
  294.             fms_dLocal1X = (fms_dX * xf1.R.col1.x + fms_dY * xf1.R.col1.y);
  295.             fms_dLocal1Y = (fms_dX * xf1.R.col2.x + fms_dY * xf1.R.col2.y);
  296.            
  297.             // Get support vertex as a hint for our search
  298.             fms_edge = 0;
  299.             fms_maxDot = -Number.MAX_VALUE;
  300.  
  301.             for (fms_i = 0; fms_i < fms_count1; ++fms_i)
  302.             {
  303.                 //var dot:Number = b2Math.b2Dot(normals1[i], dLocal1);
  304.                 fms_tVec = fms_normals1[fms_i];
  305.  
  306.                 fms_dot = (fms_tVec.x * fms_dLocal1X + fms_tVec.y * fms_dLocal1Y);
  307.  
  308.                 if(fms_dot > fms_maxDot)
  309.                 {
  310.                     fms_maxDot = fms_dot;
  311.                     fms_edge = fms_i;
  312.                 }
  313.             }
  314.            
  315.             // Get the separation for the edge normal.
  316.             fms_s = EdgeSeparation(poly1, xf1, fms_edge, poly2, xf2);
  317.            
  318.             // Check the separation for the previous edge normal.
  319.             fms_prevEdge = fms_edge - 1 >= 0 ? fms_edge - 1 : fms_count1 - 1;
  320.             fms_sPrev = EdgeSeparation(poly1, xf1, fms_prevEdge, poly2, xf2);
  321.            
  322.             // Check the separation for the next edge normal.
  323.             fms_nextEdge = fms_edge + 1 < fms_count1 ? fms_edge + 1 : 0;
  324.             fms_sNext = EdgeSeparation(poly1, xf1, fms_nextEdge, poly2, xf2);
  325.            
  326.             fms_normals1 = null;
  327.  
  328.             // Find the best edge and the search direction.
  329.             fms_bestEdge = 0;
  330.             fms_bestSeparation = 0;
  331.             fms_increment = 0;
  332.  
  333.             if (fms_sPrev > fms_s && fms_sPrev > fms_sNext)
  334.             {
  335.                 fms_increment = -1;
  336.                 fms_bestEdge = fms_prevEdge;
  337.                 fms_bestSeparation = fms_sPrev;
  338.             }
  339.             else if (fms_sNext > fms_s)
  340.             {
  341.                 fms_increment = 1;
  342.                 fms_bestEdge = fms_nextEdge;
  343.                 fms_bestSeparation = fms_sNext;
  344.             }
  345.             else
  346.             {
  347.                 // pointer out
  348.                 edgeIndex[0] = fms_edge;
  349.                 return fms_s;
  350.             }
  351.            
  352.             // Perform a local search for the best edge normal.
  353.             while (true)
  354.             {
  355.                
  356.                 if (fms_increment == -1)
  357.                     fms_edge = fms_bestEdge - 1 >= 0 ? fms_bestEdge - 1 : fms_count1 - 1;
  358.                 else
  359.                     fms_edge = fms_bestEdge + 1 < fms_count1 ? fms_bestEdge + 1 : 0;
  360.                
  361.                 fms_s = EdgeSeparation(poly1, xf1, fms_edge, poly2, xf2);
  362.                
  363.                 if (fms_s > fms_bestSeparation)
  364.                 {
  365.                     fms_bestEdge = fms_edge;
  366.                     fms_bestSeparation = fms_s;
  367.                 }
  368.                 else
  369.                 {
  370.                     break;
  371.                 }
  372.             }
  373.            
  374.             // pointer out
  375.             edgeIndex[0] = fms_bestEdge;
  376.             return fms_bestSeparation;
  377.         }
  378.  
  379.         private static var fie_normals1:Array;
  380.        
  381.         private static var fie_count2:int;
  382.         private static var fie_vertices2:Array;
  383.         private static var fie_normals2:Array;
  384.  
  385.         private static var fie_tMat:b2Mat22;
  386.         private static var fie_tVec:b2Vec2;
  387.  
  388.         private static var fie_normal1X:Number;
  389.         private static var fie_normal1Y:Number;
  390.        
  391.         private static var fie_tX:Number;
  392.  
  393.         private static var fie_index:int;
  394.         private static var fie_minDot:Number;
  395.         private static var fie_i:int;
  396.         private static var fie_dot:Number;
  397.        
  398.         private static var fie_tClip:ClipVertex;
  399.  
  400.         private static var fie_i1:int;
  401.         private static var fie_i2:int;
  402.        
  403.        
  404.         [Inline]
  405.         static public function FindIncidentEdge(c:Vector.<ClipVertex>,
  406.                                                 poly1:b2PolygonShape, xf1:b2Transform, edge1:int,
  407.                                                 poly2:b2PolygonShape, xf2:b2Transform) : void
  408.         {
  409.             fie_normals1 = poly1.m_normals;
  410.            
  411.             fie_count2 = poly2.m_vertexCount;
  412.            
  413.             fie_vertices2 = poly2.m_vertices;
  414.             fie_normals2 = poly2.m_normals;
  415.            
  416.             //b2Assert(0 <= edge1 && edge1 < count1);
  417.            
  418.             fie_tMat = null;
  419.             fie_tVec = null;
  420.            
  421.             // Get the normal of the reference edge in poly2's frame.
  422.             //b2Vec2 normal1 = b2MulT(xf2.R, b2Mul(xf1.R, normals1[edge1]));
  423.             fie_tMat = xf1.R;
  424.             fie_tVec = fie_normals1[edge1];
  425.            
  426.             fie_normal1X = (fie_tMat.col1.x * fie_tVec.x + fie_tMat.col2.x * fie_tVec.y);
  427.             fie_normal1Y = (fie_tMat.col1.y * fie_tVec.x + fie_tMat.col2.y * fie_tVec.y);
  428.            
  429.             fie_tMat = xf2.R;
  430.            
  431.             fie_tX = (fie_tMat.col1.x * fie_normal1X + fie_tMat.col1.y * fie_normal1Y);
  432.  
  433.             fie_normal1Y =  (fie_tMat.col2.x * fie_normal1X + fie_tMat.col2.y * fie_normal1Y);
  434.             fie_normal1X = fie_tX;
  435.            
  436.             // Find the incident edge on poly2.
  437.             fie_index = 0;
  438.             fie_minDot = Number.MAX_VALUE;
  439.            
  440.             for (fie_i = 0; fie_i < fie_count2; ++fie_i)
  441.             {
  442.                 //var dot:Number = b2Dot(normal1, normals2[i]);
  443.                 fie_tVec = fie_normals2[fie_i];
  444.                 fie_dot = (fie_normal1X * fie_tVec.x + fie_normal1Y * fie_tVec.y);
  445.                
  446.                 if (fie_dot < fie_minDot)
  447.                 {
  448.                     fie_minDot = fie_dot;
  449.                     fie_index = fie_i;
  450.                 }
  451.             }
  452.            
  453.             fie_tClip = null;
  454.             // Build the clip vertices for the incident edge.
  455.             fie_i1 = fie_index;
  456.             fie_i2 = fie_i1 + 1 < fie_count2 ? fie_i1 + 1 : 0;
  457.            
  458.             fie_tClip = c[0];
  459.             //c[0].v = b2Mul(xf2, vertices2[i1]);
  460.             fie_tVec = fie_vertices2[fie_i1];
  461.             fie_tMat = xf2.R;
  462.             fie_tClip.v.x = xf2.position.x + (fie_tMat.col1.x * fie_tVec.x + fie_tMat.col2.x * fie_tVec.y);
  463.             fie_tClip.v.y = xf2.position.y + (fie_tMat.col1.y * fie_tVec.x + fie_tMat.col2.y * fie_tVec.y);
  464.            
  465.             fie_tClip.id.features.referenceEdge = edge1;
  466.             fie_tClip.id.features.incidentEdge = fie_i1;
  467.             fie_tClip.id.features.incidentVertex = 0;
  468.            
  469.             fie_tClip = c[1];
  470.             //c[1].v = b2Mul(xf2, vertices2[i2]);
  471.             fie_tVec = fie_vertices2[fie_i2];
  472.             fie_tMat = xf2.R;
  473.             fie_tClip.v.x = xf2.position.x + (fie_tMat.col1.x * fie_tVec.x + fie_tMat.col2.x * fie_tVec.y);
  474.             fie_tClip.v.y = xf2.position.y + (fie_tMat.col1.y * fie_tVec.x + fie_tMat.col2.y * fie_tVec.y);
  475.            
  476.             fie_tClip.id.features.referenceEdge = edge1;
  477.             fie_tClip.id.features.incidentEdge = fie_i2;
  478.             fie_tClip.id.features.incidentVertex = 1;
  479.            
  480.            
  481.             fie_normals1 = null;
  482.             fie_vertices2 = null;
  483.             fie_normals2 = null;
  484.         }
  485.        
  486.        
  487.         private static function MakeClipPointVector():Vector.<ClipVertex>
  488.         {
  489.             var r:Vector.<ClipVertex> = new Vector.<ClipVertex>(2);
  490.             r[0] = new ClipVertex();
  491.             r[1] = new ClipVertex();
  492.             return r;
  493.         }
  494.        
  495.         private static const k_relativeTol:Number = 0.98;
  496.         private static const k_absoluteTol:Number = 0.001;
  497.        
  498.        
  499.         private static var s_incidentEdge:Vector.<ClipVertex> = MakeClipPointVector();
  500.         private static var s_clipPoints1:Vector.<ClipVertex> = MakeClipPointVector();
  501.         private static var s_clipPoints2:Vector.<ClipVertex> = MakeClipPointVector();
  502.         private static var s_edgeAO:Vector.<int> = new Vector.<int>(1);
  503.         private static var s_edgeBO:Vector.<int> = new Vector.<int>(1);
  504.         private static var s_localTangent:b2Vec2 = new b2Vec2();
  505.         private static var s_localNormal:b2Vec2 = new b2Vec2();
  506.         private static var s_planePoint:b2Vec2 = new b2Vec2();
  507.         private static var s_normal:b2Vec2 = new b2Vec2();
  508.         private static var s_tangent:b2Vec2 = new b2Vec2();
  509.         private static var s_tangent2:b2Vec2 = new b2Vec2();
  510.         private static var s_v11:b2Vec2 = new b2Vec2();
  511.         private static var s_v12:b2Vec2 = new b2Vec2();
  512.         // Find edge normal of max separation on A - return if separating axis is found
  513.         // Find edge normal of max separation on B - return if separation axis is found
  514.         // Choose reference edge as min(minA, minB)
  515.         // Find incident edge
  516.         // Clip
  517.         static private var b2CollidePolyTempVec:b2Vec2 = new b2Vec2();
  518.         // The normal points from 1 to 2
  519.        
  520.        
  521.         private static var cp_cv:ClipVertex;
  522.         private static var cp_totalRadius:Number;
  523.        
  524.         private static var cp_edgeA:int;
  525.         private static var cp_separationA:Number;
  526.         private static var cp_edgeB:int;
  527.         private static var cp_separationB:Number;
  528.        
  529.         private static var cp_poly1:b2PolygonShape;
  530.         private static var cp_poly2:b2PolygonShape;
  531.         private static var cp_xf1:b2Transform;
  532.         private static var cp_xf2:b2Transform;
  533.         private static var cp_edge1:int;
  534.         private static var cp_flip:uint;
  535.         private static var cp_tMat:b2Mat22;
  536.         private static var cp_incidentEdge:Vector.<ClipVertex>;
  537.  
  538.         private static var cp_count1:int;
  539.         private static var cp_vertices1:Array;
  540.        
  541.         private static var cp_local_v11:b2Vec2;
  542.         private static var cp_local_v12:b2Vec2;
  543.         private static var cp_localTangent:b2Vec2;
  544.         private static var cp_localNormal:b2Vec2;
  545.                
  546.         private static var cp_planePoint:b2Vec2;
  547.         private static var cp_tangent:b2Vec2;
  548.         private static var cp_tangent2:b2Vec2;
  549.         private static var cp_normal:b2Vec2;
  550.  
  551.         private static var cp_v11:b2Vec2;
  552.         private static var cp_v12:b2Vec2;
  553.        
  554.         private static var cp_frontOffset:Number;
  555.         private static var cp_sideOffset1:Number;
  556.         private static var cp_sideOffset2:Number;
  557.        
  558.         // Clip incident edge against extruded edge1 side edges.
  559.         private static var cp_clipPoints1:Vector.<ClipVertex>;
  560.         private static var cp_clipPoints2:Vector.<ClipVertex>;
  561.         private static var cp_np:int;
  562.  
  563.         private static var cp_pointCount:int;
  564.         private static var cp_i:int;
  565.         private static var cp_separation:Number;
  566.         private static var cp_cp:b2ManifoldPoint;
  567.         private static var cp_tX:Number;
  568.         private static var cp_tY:Number;
  569.        
  570.         [Inline]
  571.         static public function CollidePolygons(manifold:b2Manifold,
  572.                                                 polyA:b2PolygonShape, xfA:b2Transform,
  573.                                                 polyB:b2PolygonShape, xfB:b2Transform):void
  574.         {
  575.             cp_cv = null;
  576.  
  577.             manifold.m_pointCount = 0;
  578.            
  579.             cp_totalRadius = polyA.m_radius + polyB.m_radius;
  580.    
  581.             cp_edgeA = 0;
  582.            
  583.             s_edgeAO[0] = cp_edgeA;
  584.            
  585.             cp_separationA = FindMaxSeparation(s_edgeAO, polyA, xfA, polyB, xfB);
  586.  
  587.             cp_edgeA = s_edgeAO[0];
  588.            
  589.             if(cp_separationA > cp_totalRadius)
  590.             {
  591.                 return;
  592.             }
  593.    
  594.             cp_edgeB = 0;
  595.            
  596.             s_edgeBO[0] = cp_edgeB;
  597.            
  598.             cp_separationB = FindMaxSeparation(s_edgeBO, polyB, xfB, polyA, xfA);
  599.            
  600.             cp_edgeB = s_edgeBO[0];
  601.            
  602.             if(cp_separationB > cp_totalRadius)
  603.             {
  604.                 return;
  605.             }
  606.    
  607.             cp_poly1 = null;
  608.             cp_poly2 = null;
  609.  
  610.             cp_xf1 = null;
  611.             cp_xf2 = null;
  612.  
  613.             cp_edge1 = 0;       // reference edge
  614.             cp_flip = 0;
  615.  
  616.             cp_tMat = null;
  617.    
  618.             if (cp_separationB > k_relativeTol * cp_separationA + k_absoluteTol)
  619.             {
  620.                 cp_poly1 = polyB;
  621.                 cp_poly2 = polyA;
  622.                 cp_xf1 = xfB;
  623.                 cp_xf2 = xfA;
  624.                 cp_edge1 = cp_edgeB;
  625.                 manifold.m_type = b2Manifold.e_faceB;
  626.                 cp_flip = 1;
  627.             }
  628.             else
  629.             {
  630.                 cp_poly1 = polyA;
  631.                 cp_poly2 = polyB;
  632.                 cp_xf1 = xfA;
  633.                 cp_xf2 = xfB;
  634.                 cp_edge1 = cp_edgeA;
  635.                 manifold.m_type = b2Manifold.e_faceA;
  636.                 cp_flip = 0;
  637.             }
  638.    
  639.             cp_incidentEdge = s_incidentEdge;
  640.             FindIncidentEdge(cp_incidentEdge, cp_poly1, cp_xf1, cp_edge1, cp_poly2, cp_xf2);
  641.    
  642.             cp_count1 = cp_poly1.m_vertexCount;
  643.             cp_vertices1 = cp_poly1.m_vertices;
  644.    
  645.             cp_local_v11 = cp_vertices1[cp_edge1];
  646.             cp_local_v12 = null;
  647.            
  648.             if(cp_edge1 + 1 < cp_count1)
  649.             {
  650.                 cp_local_v12 = cp_vertices1[int(cp_edge1+1)];
  651.             }
  652.             else
  653.             {
  654.                 cp_local_v12 = cp_vertices1[0];
  655.             }
  656.    
  657.             cp_localTangent = s_localTangent;
  658.             cp_localTangent.Set(cp_local_v12.x - cp_local_v11.x, cp_local_v12.y - cp_local_v11.y);
  659.             cp_localTangent.Normalize();
  660.            
  661.             cp_localNormal = s_localNormal;
  662.             cp_localNormal.x = cp_localTangent.y;
  663.             cp_localNormal.y = -cp_localTangent.x;
  664.            
  665.             cp_planePoint = s_planePoint;
  666.             cp_planePoint.Set(0.5 * (cp_local_v11.x + cp_local_v12.x), 0.5 * (cp_local_v11.y + cp_local_v12.y));
  667.            
  668.             cp_tangent = s_tangent;
  669.             //tangent = b2Math.b2MulMV(xf1.R, localTangent);
  670.             cp_tMat = cp_xf1.R;
  671.             cp_tangent.x = (cp_tMat.col1.x * cp_localTangent.x + cp_tMat.col2.x * cp_localTangent.y);
  672.             cp_tangent.y = (cp_tMat.col1.y * cp_localTangent.x + cp_tMat.col2.y * cp_localTangent.y);
  673.            
  674.             cp_tangent2 = s_tangent2;
  675.             cp_tangent2.x = - cp_tangent.x;
  676.             cp_tangent2.y = - cp_tangent.y;
  677.            
  678.             cp_normal = s_normal;
  679.             cp_normal.x = cp_tangent.y;
  680.             cp_normal.y = -cp_tangent.x;
  681.    
  682.             //v11 = b2Math.MulX(xf1, local_v11);
  683.             //v12 = b2Math.MulX(xf1, local_v12);
  684.             cp_v11 = s_v11;
  685.             cp_v12 = s_v12;
  686.  
  687.             cp_v11.x = cp_xf1.position.x + (cp_tMat.col1.x * cp_local_v11.x + cp_tMat.col2.x * cp_local_v11.y);
  688.             cp_v11.y = cp_xf1.position.y + (cp_tMat.col1.y * cp_local_v11.x + cp_tMat.col2.y * cp_local_v11.y);
  689.            
  690.             cp_v12.x = cp_xf1.position.x + (cp_tMat.col1.x * cp_local_v12.x + cp_tMat.col2.x * cp_local_v12.y);
  691.             cp_v12.y = cp_xf1.position.y + (cp_tMat.col1.y * cp_local_v12.x + cp_tMat.col2.y * cp_local_v12.y);
  692.    
  693.             // Face offset
  694.             cp_frontOffset = cp_normal.x * cp_v11.x + cp_normal.y * cp_v11.y;
  695.            
  696.             // Side offsets, extended by polytope skin thickness
  697.             cp_sideOffset1 = -cp_tangent.x * cp_v11.x - cp_tangent.y * cp_v11.y + cp_totalRadius;
  698.             cp_sideOffset2 = cp_tangent.x * cp_v12.x + cp_tangent.y * cp_v12.y + cp_totalRadius;
  699.    
  700.             // Clip incident edge against extruded edge1 side edges.
  701.             cp_clipPoints1 = s_clipPoints1;
  702.             cp_clipPoints2 = s_clipPoints2;
  703.             cp_np = 0;
  704.    
  705.             // Clip to box side 1
  706.             //np = ClipSegmentToLine(clipPoints1, incidentEdge, -tangent, sideOffset1);
  707.             cp_np = ClipSegmentToLine(cp_clipPoints1, cp_incidentEdge, cp_tangent2, cp_sideOffset1);
  708.    
  709.             if(cp_np < 2)
  710.             {
  711.                 return;
  712.             }
  713.    
  714.             // Clip to negative box side 1
  715.             cp_np = ClipSegmentToLine(cp_clipPoints2, cp_clipPoints1,  cp_tangent, cp_sideOffset2);
  716.    
  717.             if(cp_np < 2)
  718.             {
  719.                 return;            
  720.             }
  721.    
  722.             // Now clipPoints2 contains the clipped points.
  723.             manifold.m_localPlaneNormal.x = cp_localNormal.x;
  724.             manifold.m_localPlaneNormal.y = cp_localNormal.y;
  725.            
  726.             manifold.m_localPoint.x = cp_planePoint.x;
  727.             manifold.m_localPoint.y = cp_planePoint.y;
  728.            
  729.             cp_pointCount = 0;
  730.            
  731.             for (cp_i = 0; cp_i < b2Settings.b2_maxManifoldPoints; ++cp_i)
  732.             {
  733.                 cp_cv = cp_clipPoints2[cp_i];
  734.                
  735.                 cp_separation = cp_normal.x * cp_cv.v.x + cp_normal.y * cp_cv.v.y - cp_frontOffset;
  736.  
  737.                 if(cp_separation <= cp_totalRadius)
  738.                 {
  739.                     cp_cp = manifold.m_points[cp_pointCount];
  740.                    
  741.                     //cp.m_localPoint = b2Math.b2MulXT(xf2, cv.v);
  742.                     cp_tMat = cp_xf2.R;
  743.                    
  744.                     cp_tX = cp_cv.v.x - cp_xf2.position.x;
  745.                     cp_tY = cp_cv.v.y - cp_xf2.position.y;
  746.                    
  747.                     cp_cp.m_localPoint.x = (cp_tX * cp_tMat.col1.x + cp_tY * cp_tMat.col1.y);
  748.                     cp_cp.m_localPoint.y = (cp_tX * cp_tMat.col2.x + cp_tY * cp_tMat.col2.y);
  749.                     cp_cp.m_id.Set(cp_cv.id);
  750.                     cp_cp.m_id.features.flip = cp_flip;
  751.  
  752.                     ++cp_pointCount;
  753.                 }
  754.             }
  755.            
  756.             manifold.m_pointCount = cp_pointCount;
  757.         }
  758.        
  759.        
  760.         private static var cc_tMat:b2Mat22;
  761.         private static var cc_tVec:b2Vec2;
  762.    
  763.         private static var cc_p1X:Number;
  764.         private static var cc_p1Y:Number;
  765.  
  766.         private static var cc_p2X:Number;
  767.         private static var cc_p2Y:Number;
  768.  
  769.         private static var cc_dX:Number;
  770.         private static var cc_dY:Number;
  771.  
  772.         private static var cc_distSqr:Number;
  773.         private static var cc_radius:Number;
  774.        
  775.         private static var manifoldPoint:b2ManifoldPoint;
  776.        
  777.         [Inline]
  778.         static public function CollideCircles(manifold:b2Manifold,
  779.                                               circle1:b2CircleShape,
  780.                                               xf1:b2Transform,
  781.                                               circle2:b2CircleShape,
  782.                                               xf2:b2Transform):void
  783.         {
  784.             manifold.m_pointCount = 0;
  785.  
  786.             //b2Vec2 p1 = b2Mul(xf1, circle1->m_p);
  787.             cc_tMat = xf1.R;
  788.             cc_tVec = circle1.m_p;
  789.            
  790.             cc_p1X = xf1.position.x + (cc_tMat.col1.x * cc_tVec.x + cc_tMat.col2.x * cc_tVec.y);
  791.             cc_p1Y = xf1.position.y + (cc_tMat.col1.y * cc_tVec.x + cc_tMat.col2.y * cc_tVec.y);
  792.  
  793.             cc_tMat = xf2.R;
  794.             cc_tVec = circle2.m_p;
  795.            
  796.             cc_p2X = xf2.position.x + (cc_tMat.col1.x * cc_tVec.x + cc_tMat.col2.x * cc_tVec.y);
  797.             cc_p2Y = xf2.position.y + (cc_tMat.col1.y * cc_tVec.x + cc_tMat.col2.y * cc_tVec.y);
  798.  
  799.             cc_dX = cc_p2X - cc_p1X;
  800.             cc_dY = cc_p2Y - cc_p1Y;
  801.  
  802.             cc_distSqr = cc_dX * cc_dX + cc_dY * cc_dY;
  803.             cc_radius = circle1.m_radius + circle2.m_radius;
  804.            
  805.             if(cc_distSqr > cc_radius * cc_radius)
  806.             {
  807.                 return;
  808.             }
  809.            
  810.             manifold.m_type = b2Manifold.e_circles;
  811.            
  812.             manifold.m_localPoint.x = circle1.m_p.x;
  813.             manifold.m_localPoint.y = circle1.m_p.y;
  814.            
  815.             manifold.m_localPlaneNormal.x = b2Settings.DECIMAL_ZERO;
  816.             manifold.m_localPlaneNormal.y = b2Settings.DECIMAL_ZERO;
  817.            
  818.             manifold.m_pointCount = 1;
  819.            
  820.             manifoldPoint = manifold.m_points[0];
  821.            
  822.             manifoldPoint.m_localPoint.x = circle2.m_p.x;
  823.             manifoldPoint.m_localPoint.y = circle2.m_p.y;
  824.            
  825.             manifoldPoint.m_id.key = 0;
  826.            
  827.             manifoldPoint = null;
  828.             cc_tMat = null;
  829.             cc_tVec = null;
  830.         }
  831.        
  832.  
  833.         private static var cpc_dX:Number;
  834.         private static var cpc_dY:Number;
  835.        
  836.         private static var cpc_tVec:b2Vec2;
  837.         private static var cpc_tMat:b2Mat22;
  838.  
  839.         private static var cpc_cX:Number;
  840.         private static var cpc_cY:Number;
  841.  
  842.         private static var cpc_cLocalX:Number;
  843.         private static var cpc_cLocalY:Number;
  844.  
  845.         private static var cpc_normalIndex:int;
  846.         private static var cpc_separation:Number;
  847.         private static var cpc_radius:Number;
  848.         private static var cpc_vertexCount:int;
  849.         private static var cpc_vertices:Array;
  850.         private static var cpc_normals:Array;
  851.        
  852.         private static var cpc_i:int;
  853.         private static var cpc_s:Number;
  854.  
  855.         private static var cpc_vertIndex1:int;
  856.         private static var cpc_vertIndex2:int;
  857.         private static var cpc_v1:b2Vec2;
  858.         private static var cpc_v2:b2Vec2;
  859.         private static var cpc_normalv1:b2Vec2;
  860.         private static var cpc_normalv2:b2Vec2;
  861.        
  862.         private static var cpc_u1:Number;
  863.         private static var cpc_u2:Number;
  864.        
  865.         private static var cpc_faceCenterX:Number;
  866.         private static var cpc_faceCenterY:Number;
  867.        
  868.        
  869.         [Inline]
  870.         static public function CollidePolygonAndCircle(manifold:b2Manifold,
  871.                                                        polygon:b2PolygonShape,
  872.                                                        xf1:b2Transform,
  873.                                                        circle:b2CircleShape,
  874.                                                        xf2:b2Transform):void
  875.         {
  876.             manifold.m_pointCount = 0;
  877.            
  878.             cpc_dX = 0;
  879.             cpc_dY = 0;
  880.            
  881.             cpc_tVec = null;
  882.             cpc_tMat = null;
  883.  
  884.             cpc_tMat = xf2.R;
  885.             cpc_tVec = circle.m_p;
  886.            
  887.             cpc_cX = xf2.position.x + (cpc_tMat.col1.x * cpc_tVec.x + cpc_tMat.col2.x * cpc_tVec.y);
  888.             cpc_cY = xf2.position.y + (cpc_tMat.col1.y * cpc_tVec.x + cpc_tMat.col2.y * cpc_tVec.y);
  889.            
  890.             //b2Vec2 cLocal = b2MulT(xf1, c);
  891.             cpc_dX = cpc_cX - xf1.position.x;
  892.             cpc_dY = cpc_cY - xf1.position.y;
  893.             cpc_tMat = xf1.R;
  894.  
  895.             cpc_cLocalX = (cpc_dX * cpc_tMat.col1.x + cpc_dY * cpc_tMat.col1.y);
  896.             cpc_cLocalY = (cpc_dX * cpc_tMat.col2.x + cpc_dY * cpc_tMat.col2.y);
  897.            
  898.             // Find the min separating edge.
  899.             cpc_normalIndex = 0;
  900.             cpc_separation = -Number.MAX_VALUE;
  901.             cpc_radius = polygon.m_radius + circle.m_radius;
  902.            
  903.             cpc_vertexCount = polygon.m_vertexCount;
  904.             cpc_vertices = polygon.m_vertices;
  905.             cpc_normals = polygon.m_normals;
  906.    
  907.             for (cpc_i = 0; cpc_i < cpc_vertexCount; ++cpc_i)
  908.             {
  909.                 cpc_tVec = cpc_vertices[cpc_i];
  910.                 cpc_dX = cpc_cLocalX - cpc_tVec.x;
  911.                 cpc_dY = cpc_cLocalY - cpc_tVec.y;
  912.                 cpc_tVec = cpc_normals[cpc_i];
  913.                
  914.                 cpc_s = cpc_tVec.x * cpc_dX + cpc_tVec.y * cpc_dY;
  915.                
  916.                 if(cpc_s > cpc_radius)
  917.                 {
  918.                     return;
  919.                 }
  920.                
  921.                 if(cpc_s > cpc_separation)
  922.                 {
  923.                     cpc_separation = cpc_s;
  924.                     cpc_normalIndex = cpc_i;
  925.                 }
  926.             }
  927.            
  928.             // Vertices that subtend the incident face
  929.             cpc_vertIndex1 = cpc_normalIndex;
  930.             cpc_vertIndex2 = cpc_vertIndex1 + 1 < cpc_vertexCount ? cpc_vertIndex1 + 1 : 0;
  931.            
  932.             cpc_v1 = cpc_vertices[cpc_vertIndex1];
  933.             cpc_v2 = cpc_vertices[cpc_vertIndex2];
  934.  
  935.             // If the center is inside the polygon ...
  936.             if (cpc_separation < Number.MIN_VALUE)
  937.             {
  938.                 manifold.m_pointCount = 1;
  939.                 manifold.m_type = b2Manifold.e_faceA;
  940.                 manifold.m_localPlaneNormal.SetV(cpc_normals[cpc_normalIndex]);
  941.                 manifold.m_localPoint.x = 0.5 * (cpc_v1.x + cpc_v2.x);
  942.                 manifold.m_localPoint.y = 0.5 * (cpc_v1.y + cpc_v2.y);
  943.                
  944.                 manifoldPoint = manifold.m_points[0];
  945.  
  946.                 manifoldPoint.m_localPoint.x = circle.m_p.x;
  947.                 manifoldPoint.m_localPoint.y = circle.m_p.y;
  948.                
  949.                 manifoldPoint.m_id.key = 0;
  950.                
  951.                 manifoldPoint = null;
  952.                 return;
  953.             }
  954.            
  955.             // Project the circle center onto the edge segment.
  956.             cpc_u1 = (cpc_cLocalX - cpc_v1.x) * (cpc_v2.x - cpc_v1.x) + (cpc_cLocalY - cpc_v1.y) * (cpc_v2.y - cpc_v1.y);
  957.             cpc_u2 = (cpc_cLocalX - cpc_v2.x) * (cpc_v1.x - cpc_v2.x) + (cpc_cLocalY - cpc_v2.y) * (cpc_v1.y - cpc_v2.y);
  958.  
  959.             if(cpc_u1 <= b2Settings.DECIMAL_ZERO)
  960.             {
  961.                 if ((cpc_cLocalX - cpc_v1.x)*(cpc_cLocalX - cpc_v1.x)+(cpc_cLocalY - cpc_v1.y)*(cpc_cLocalY - cpc_v1.y) > cpc_radius * cpc_radius)
  962.                 {
  963.                     return;
  964.                 }
  965.                
  966.                 manifold.m_pointCount = 1;
  967.                 manifold.m_type = b2Manifold.e_faceA;
  968.                 manifold.m_localPlaneNormal.x = cpc_cLocalX - cpc_v1.x;
  969.                 manifold.m_localPlaneNormal.y = cpc_cLocalY - cpc_v1.y;
  970.                 manifold.m_localPlaneNormal.Normalize();
  971.                
  972.                 manifold.m_localPoint.x = cpc_v1.x;
  973.                 manifold.m_localPoint.y = cpc_v1.y;
  974.                
  975.                 manifoldPoint = manifold.m_points[0];
  976.                
  977.                 manifoldPoint.m_localPoint.x = circle.m_p.x;
  978.                 manifoldPoint.m_localPoint.y = circle.m_p.y;
  979.                
  980.                 manifoldPoint.m_id.key = 0;
  981.             }
  982.             else if (cpc_u2 <= 0)
  983.             {
  984.                 if ((cpc_cLocalX - cpc_v2.x)*(cpc_cLocalX - cpc_v2.x)+(cpc_cLocalY - cpc_v2.y)*(cpc_cLocalY - cpc_v2.y) > cpc_radius * cpc_radius)
  985.                 {
  986.                     return;
  987.                 }
  988.                
  989.                 manifold.m_pointCount = 1;
  990.                 manifold.m_type = b2Manifold.e_faceA;
  991.                 manifold.m_localPlaneNormal.x = cpc_cLocalX - cpc_v2.x;
  992.                 manifold.m_localPlaneNormal.y = cpc_cLocalY - cpc_v2.y;
  993.                
  994.                 manifold.m_localPlaneNormal.Normalize();
  995.  
  996.                 manifold.m_localPoint.x = cpc_v2.x;
  997.                 manifold.m_localPoint.y = cpc_v2.y;
  998.                
  999.                 manifoldPoint = manifold.m_points[0];
  1000.                
  1001.                 manifoldPoint.m_localPoint.x = circle.m_p.x;
  1002.                 manifoldPoint.m_localPoint.y = circle.m_p.y;
  1003.                
  1004.                 manifoldPoint.m_id.key = 0;
  1005.             }
  1006.             else
  1007.             {
  1008.                 cpc_faceCenterX = 0.5 * (cpc_v1.x + cpc_v2.x);
  1009.                 cpc_faceCenterY = 0.5 * (cpc_v1.y + cpc_v2.y);
  1010.                
  1011.                 cpc_normalv1 = cpc_normals[cpc_vertIndex1];
  1012.                
  1013.                 cpc_separation = (cpc_cLocalX - cpc_faceCenterX) * cpc_normalv1.x + (cpc_cLocalY - cpc_faceCenterY) * cpc_normalv1.y;
  1014.                
  1015.                 if (cpc_separation > cpc_radius)
  1016.                 {
  1017.                     return;
  1018.                 }
  1019.  
  1020.                 manifold.m_pointCount = 1;
  1021.                 manifold.m_type = b2Manifold.e_faceA;
  1022.                
  1023.                 manifold.m_localPlaneNormal.x = cpc_normalv1.x;
  1024.                 manifold.m_localPlaneNormal.y = cpc_normalv1.y;
  1025.                
  1026.                 manifold.m_localPlaneNormal.Normalize();
  1027.                
  1028.                 manifold.m_localPoint.x = cpc_faceCenterX;
  1029.                 manifold.m_localPoint.y = cpc_faceCenterY;
  1030.                
  1031.                 manifoldPoint = manifold.m_points[0];
  1032.                
  1033.                 manifoldPoint.m_localPoint.x = circle.m_p.x;
  1034.                 manifoldPoint.m_localPoint.y = circle.m_p.y;
  1035.                
  1036.                 manifoldPoint.m_id.key = 0;
  1037.             }
  1038.            
  1039.             manifoldPoint = null;
  1040.         }
  1041.    
  1042.    
  1043.         private static var to_t1:b2Vec2;
  1044.         private static var to_t2:b2Vec2;
  1045.        
  1046.         private static var to_d1X:Number;
  1047.         private static var to_d1Y:Number;
  1048.  
  1049.        
  1050.         private static var to_d2X:Number;
  1051.         private static var to_d2Y:Number;
  1052.        
  1053.    
  1054.         [Inline]
  1055.         static public function TestOverlap(a:b2AABB, b:b2AABB):Boolean
  1056.         {
  1057.             to_t1 = b.lowerBound;
  1058.             to_t2 = a.upperBound;
  1059.            
  1060.             //d1 = b2Math.SubtractVV(b.lowerBound, a.upperBound);
  1061.             to_d1X = to_t1.x - to_t2.x;
  1062.             to_d1Y = to_t1.y - to_t2.y;
  1063.            
  1064.             //d2 = b2Math.SubtractVV(a.lowerBound, b.upperBound);
  1065.             to_t1 = a.lowerBound;
  1066.             to_t2 = b.upperBound;
  1067.            
  1068.             to_d2X = to_t1.x - to_t2.x;
  1069.             to_d2Y = to_t1.y - to_t2.y;
  1070.            
  1071.             if (to_d1X > b2Settings.DECIMAL_ZERO || to_d1Y > b2Settings.DECIMAL_ZERO)
  1072.             {
  1073.                 return false;
  1074.             }
  1075.            
  1076.             if (to_d2X > b2Settings.DECIMAL_ZERO || to_d2Y > b2Settings.DECIMAL_ZERO)
  1077.             {
  1078.                 return false;
  1079.             }
  1080.            
  1081.             return true;
  1082.         }
  1083.     }
  1084. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement