home *** CD-ROM | disk | FTP | other *** search
/ 404 Jogos / CLJG.iso / Diversos / Beez.swf / scripts / Box2D / Collision / Shapes / b2PolygonShape.as < prev    next >
Encoding:
Text File  |  2008-09-03  |  16.0 KB  |  470 lines

  1. package Box2D.Collision.Shapes
  2. {
  3.    import Box2D.Collision.*;
  4.    import Box2D.Common.*;
  5.    import Box2D.Common.Math.*;
  6.    import Box2D.Dynamics.*;
  7.    
  8.    public class b2PolygonShape extends b2Shape
  9.    {
  10.       
  11.       private static var s_computeMat:b2Mat22 = new b2Mat22();
  12.       
  13.       private static var s_sweptAABB1:b2AABB = new b2AABB();
  14.       
  15.       private static var s_sweptAABB2:b2AABB = new b2AABB();
  16.        
  17.       
  18.       public var m_coreVertices:Array;
  19.       
  20.       public var m_vertices:Array;
  21.       
  22.       private var s_supportVec:b2Vec2;
  23.       
  24.       public var m_centroid:b2Vec2;
  25.       
  26.       public var m_normals:Array;
  27.       
  28.       public var m_obb:b2OBB;
  29.       
  30.       public var m_vertexCount:int;
  31.       
  32.       public function b2PolygonShape(def:b2ShapeDef)
  33.       {
  34.          var i:int = 0;
  35.          var edgeX:Number = NaN;
  36.          var edgeY:Number = NaN;
  37.          var len:Number = NaN;
  38.          var n1X:Number = NaN;
  39.          var n1Y:Number = NaN;
  40.          var n2X:Number = NaN;
  41.          var n2Y:Number = NaN;
  42.          var vX:Number = NaN;
  43.          var vY:Number = NaN;
  44.          var dX:Number = NaN;
  45.          var dY:Number = NaN;
  46.          var det:Number = NaN;
  47.          s_supportVec = new b2Vec2();
  48.          m_obb = new b2OBB();
  49.          m_vertices = new Array(b2Settings.b2_maxPolygonVertices);
  50.          m_normals = new Array(b2Settings.b2_maxPolygonVertices);
  51.          m_coreVertices = new Array(b2Settings.b2_maxPolygonVertices);
  52.          super(def);
  53.          m_type = e_polygonShape;
  54.          var poly:b2PolygonDef = def as b2PolygonDef;
  55.          m_vertexCount = poly.vertexCount;
  56.          var i1:int = i;
  57.          var i2:int = i;
  58.          for(i = 0; i < m_vertexCount; i++)
  59.          {
  60.             m_vertices[i] = poly.vertices[i].Copy();
  61.          }
  62.          for(i = 0; i < m_vertexCount; i++)
  63.          {
  64.             i1 = i;
  65.             i2 = i + 1 < m_vertexCount ? i + 1 : 0;
  66.             edgeX = m_vertices[i2].x - m_vertices[i1].x;
  67.             edgeY = m_vertices[i2].y - m_vertices[i1].y;
  68.             len = Math.sqrt(edgeX * edgeX + edgeY * edgeY);
  69.             m_normals[i] = new b2Vec2(edgeY / len,-edgeX / len);
  70.          }
  71.          m_centroid = ComputeCentroid(poly.vertices,poly.vertexCount);
  72.          ComputeOBB(m_obb,m_vertices,m_vertexCount);
  73.          for(i = 0; i < m_vertexCount; i++)
  74.          {
  75.             i1 = i - 1 >= 0 ? i - 1 : m_vertexCount - 1;
  76.             i2 = i;
  77.             n1X = Number(m_normals[i1].x);
  78.             n1Y = Number(m_normals[i1].y);
  79.             n2X = Number(m_normals[i2].x);
  80.             n2Y = Number(m_normals[i2].y);
  81.             vX = m_vertices[i].x - m_centroid.x;
  82.             vY = m_vertices[i].y - m_centroid.y;
  83.             dX = n1X * vX + n1Y * vY - b2Settings.b2_toiSlop;
  84.             dY = n2X * vX + n2Y * vY - b2Settings.b2_toiSlop;
  85.             det = 1 / (n1X * n2Y - n1Y * n2X);
  86.             m_coreVertices[i] = new b2Vec2(det * (n2Y * dX - n1Y * dY) + m_centroid.x,det * (n1X * dY - n2X * dX) + m_centroid.y);
  87.          }
  88.       }
  89.       
  90.       public static function ComputeCentroid(vs:Array, count:int) : b2Vec2
  91.       {
  92.          var c:b2Vec2 = null;
  93.          var inv3:Number = NaN;
  94.          var p2:b2Vec2 = null;
  95.          var p3:b2Vec2 = null;
  96.          var e1X:Number = NaN;
  97.          var e1Y:Number = NaN;
  98.          var e2X:Number = NaN;
  99.          var e2Y:Number = NaN;
  100.          var D:Number = NaN;
  101.          var triangleArea:Number = NaN;
  102.          c = new b2Vec2();
  103.          var area:Number = 0;
  104.          var p1X:Number = 0;
  105.          var p1Y:Number = 0;
  106.          inv3 = 1 / 3;
  107.          for(var i:int = 0; i < count; i++)
  108.          {
  109.             p2 = vs[i];
  110.             p3 = i + 1 < count ? vs[int(i + 1)] : vs[0];
  111.             e1X = p2.x - p1X;
  112.             e1Y = p2.y - p1Y;
  113.             e2X = p3.x - p1X;
  114.             e2Y = p3.y - p1Y;
  115.             D = e1X * e2Y - e1Y * e2X;
  116.             triangleArea = 0.5 * D;
  117.             area += triangleArea;
  118.             c.x += triangleArea * inv3 * (p1X + p2.x + p3.x);
  119.             c.y += triangleArea * inv3 * (p1Y + p2.y + p3.y);
  120.          }
  121.          c.x *= 1 / area;
  122.          c.y *= 1 / area;
  123.          return c;
  124.       }
  125.       
  126.       public static function ComputeOBB(obb:b2OBB, vs:Array, count:int) : void
  127.       {
  128.          var i:int = 0;
  129.          var root:b2Vec2 = null;
  130.          var uxX:Number = NaN;
  131.          var uxY:Number = NaN;
  132.          var length:Number = NaN;
  133.          var uyX:Number = NaN;
  134.          var uyY:Number = NaN;
  135.          var lowerX:Number = NaN;
  136.          var lowerY:Number = NaN;
  137.          var upperX:Number = NaN;
  138.          var upperY:Number = NaN;
  139.          var j:int = 0;
  140.          var area:Number = NaN;
  141.          var dX:Number = NaN;
  142.          var dY:Number = NaN;
  143.          var rX:Number = NaN;
  144.          var rY:Number = NaN;
  145.          var centerX:Number = NaN;
  146.          var centerY:Number = NaN;
  147.          var tMat:b2Mat22 = null;
  148.          var p:Array = new Array(b2Settings.b2_maxPolygonVertices + 1);
  149.          for(i = 0; i < count; i++)
  150.          {
  151.             p[i] = vs[i];
  152.          }
  153.          p[count] = p[0];
  154.          var minArea:Number = Number.MAX_VALUE;
  155.          for(i = 1; i <= count; i++)
  156.          {
  157.             root = p[int(i - 1)];
  158.             uxX = p[i].x - root.x;
  159.             uxY = p[i].y - root.y;
  160.             length = Math.sqrt(uxX * uxX + uxY * uxY);
  161.             uxX /= length;
  162.             uxY /= length;
  163.             uyX = -uxY;
  164.             uyY = uxX;
  165.             lowerX = Number.MAX_VALUE;
  166.             lowerY = Number.MAX_VALUE;
  167.             upperX = -Number.MAX_VALUE;
  168.             upperY = -Number.MAX_VALUE;
  169.             for(j = 0; j < count; j++)
  170.             {
  171.                dX = p[j].x - root.x;
  172.                dY = p[j].y - root.y;
  173.                rX = uxX * dX + uxY * dY;
  174.                rY = uyX * dX + uyY * dY;
  175.                if(rX < lowerX)
  176.                {
  177.                   lowerX = rX;
  178.                }
  179.                if(rY < lowerY)
  180.                {
  181.                   lowerY = rY;
  182.                }
  183.                if(rX > upperX)
  184.                {
  185.                   upperX = rX;
  186.                }
  187.                if(rY > upperY)
  188.                {
  189.                   upperY = rY;
  190.                }
  191.             }
  192.             area = (upperX - lowerX) * (upperY - lowerY);
  193.             if(area < 0.95 * minArea)
  194.             {
  195.                minArea = area;
  196.                obb.R.col1.x = uxX;
  197.                obb.R.col1.y = uxY;
  198.                obb.R.col2.x = uyX;
  199.                obb.R.col2.y = uyY;
  200.                centerX = 0.5 * (lowerX + upperX);
  201.                centerY = 0.5 * (lowerY + upperY);
  202.                tMat = obb.R;
  203.                obb.center.x = root.x + (tMat.col1.x * centerX + tMat.col2.x * centerY);
  204.                obb.center.y = root.y + (tMat.col1.y * centerX + tMat.col2.y * centerY);
  205.                obb.extents.x = 0.5 * (upperX - lowerX);
  206.                obb.extents.y = 0.5 * (upperY - lowerY);
  207.             }
  208.          }
  209.       }
  210.       
  211.       override public function ComputeSweptAABB(aabb:b2AABB, transform1:b2XForm, transform2:b2XForm) : void
  212.       {
  213.          var aabb1:b2AABB = s_sweptAABB1;
  214.          var aabb2:b2AABB = s_sweptAABB2;
  215.          ComputeAABB(aabb1,transform1);
  216.          ComputeAABB(aabb2,transform2);
  217.          aabb.lowerBound.Set(aabb1.lowerBound.x < aabb2.lowerBound.x ? aabb1.lowerBound.x : aabb2.lowerBound.x,aabb1.lowerBound.y < aabb2.lowerBound.y ? aabb1.lowerBound.y : aabb2.lowerBound.y);
  218.          aabb.upperBound.Set(aabb1.upperBound.x > aabb2.upperBound.x ? aabb1.upperBound.x : aabb2.upperBound.x,aabb1.upperBound.y > aabb2.upperBound.y ? aabb1.upperBound.y : aabb2.upperBound.y);
  219.       }
  220.       
  221.       public function GetVertices() : Array
  222.       {
  223.          return m_vertices;
  224.       }
  225.       
  226.       public function GetCoreVertices() : Array
  227.       {
  228.          return m_coreVertices;
  229.       }
  230.       
  231.       public function GetCentroid() : b2Vec2
  232.       {
  233.          return m_centroid;
  234.       }
  235.       
  236.       public function GetOBB() : b2OBB
  237.       {
  238.          return m_obb;
  239.       }
  240.       
  241.       public function GetFirstVertex(xf:b2XForm) : b2Vec2
  242.       {
  243.          return b2Math.b2MulX(xf,m_coreVertices[0]);
  244.       }
  245.       
  246.       public function Centroid(xf:b2XForm) : b2Vec2
  247.       {
  248.          return b2Math.b2MulX(xf,m_centroid);
  249.       }
  250.       
  251.       override public function TestSegment(xf:b2XForm, lambda:Array, normal:b2Vec2, segment:b2Segment, maxLambda:Number) : Boolean
  252.       {
  253.          var tX:Number = NaN;
  254.          var tY:Number = NaN;
  255.          var tMat:b2Mat22 = null;
  256.          var tVec:b2Vec2 = null;
  257.          var numerator:Number = NaN;
  258.          var denominator:Number = NaN;
  259.          var lower:Number = 0;
  260.          var upper:Number = maxLambda;
  261.          tX = segment.p1.x - xf.position.x;
  262.          tY = segment.p1.y - xf.position.y;
  263.          tMat = xf.R;
  264.          var p1X:Number = tX * tMat.col1.x + tY * tMat.col1.y;
  265.          var p1Y:Number = tX * tMat.col2.x + tY * tMat.col2.y;
  266.          tX = segment.p2.x - xf.position.x;
  267.          tY = segment.p2.y - xf.position.y;
  268.          tMat = xf.R;
  269.          var p2X:Number = tX * tMat.col1.x + tY * tMat.col1.y;
  270.          var p2Y:Number = tX * tMat.col2.x + tY * tMat.col2.y;
  271.          var dX:Number = p2X - p1X;
  272.          var dY:Number = p2Y - p1Y;
  273.          var index:int = -1;
  274.          for(var i:int = 0; i < m_vertexCount; i++)
  275.          {
  276.             tVec = m_vertices[i];
  277.             tX = tVec.x - p1X;
  278.             tY = tVec.y - p1Y;
  279.             tVec = m_normals[i];
  280.             numerator = tVec.x * tX + tVec.y * tY;
  281.             denominator = tVec.x * dX + tVec.y * dY;
  282.             if(denominator < 0 && numerator < lower * denominator)
  283.             {
  284.                lower = numerator / denominator;
  285.                index = i;
  286.             }
  287.             else if(denominator > 0 && numerator < upper * denominator)
  288.             {
  289.                upper = numerator / denominator;
  290.             }
  291.             if(upper < lower)
  292.             {
  293.                return false;
  294.             }
  295.          }
  296.          if(index >= 0)
  297.          {
  298.             lambda[0] = lower;
  299.             tMat = xf.R;
  300.             tVec = m_normals[index];
  301.             normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
  302.             normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
  303.             return true;
  304.          }
  305.          return false;
  306.       }
  307.       
  308.       override public function ComputeMass(massData:b2MassData) : void
  309.       {
  310.          var p2:b2Vec2 = null;
  311.          var p3:b2Vec2 = null;
  312.          var e1X:Number = NaN;
  313.          var e1Y:Number = NaN;
  314.          var e2X:Number = NaN;
  315.          var e2Y:Number = NaN;
  316.          var D:Number = NaN;
  317.          var triangleArea:Number = NaN;
  318.          var px:Number = NaN;
  319.          var py:Number = NaN;
  320.          var ex1:Number = NaN;
  321.          var ey1:Number = NaN;
  322.          var ex2:Number = NaN;
  323.          var ey2:Number = NaN;
  324.          var intx2:Number = NaN;
  325.          var inty2:Number = NaN;
  326.          var centerX:Number = 0;
  327.          var centerY:Number = 0;
  328.          var area:Number = 0;
  329.          var I:Number = 0;
  330.          var p1X:Number = 0;
  331.          var p1Y:Number = 0;
  332.          var k_inv3:Number = 1 / 3;
  333.          for(var i:int = 0; i < m_vertexCount; i++)
  334.          {
  335.             p2 = m_vertices[i];
  336.             p3 = i + 1 < m_vertexCount ? m_vertices[int(i + 1)] : m_vertices[0];
  337.             e1X = p2.x - p1X;
  338.             e1Y = p2.y - p1Y;
  339.             e2X = p3.x - p1X;
  340.             e2Y = p3.y - p1Y;
  341.             D = e1X * e2Y - e1Y * e2X;
  342.             triangleArea = 0.5 * D;
  343.             area += triangleArea;
  344.             centerX += triangleArea * k_inv3 * (p1X + p2.x + p3.x);
  345.             centerY += triangleArea * k_inv3 * (p1Y + p2.y + p3.y);
  346.             px = p1X;
  347.             py = p1Y;
  348.             ex1 = e1X;
  349.             ey1 = e1Y;
  350.             ex2 = e2X;
  351.             ey2 = e2Y;
  352.             intx2 = k_inv3 * (0.25 * (ex1 * ex1 + ex2 * ex1 + ex2 * ex2) + (px * ex1 + px * ex2)) + 0.5 * px * px;
  353.             inty2 = k_inv3 * (0.25 * (ey1 * ey1 + ey2 * ey1 + ey2 * ey2) + (py * ey1 + py * ey2)) + 0.5 * py * py;
  354.             I += D * (intx2 + inty2);
  355.          }
  356.          massData.mass = m_density * area;
  357.          centerX *= 1 / area;
  358.          centerY *= 1 / area;
  359.          massData.center.Set(centerX,centerY);
  360.          massData.I = m_density * I;
  361.       }
  362.       
  363.       public function GetNormals() : Array
  364.       {
  365.          return m_normals;
  366.       }
  367.       
  368.       public function Support(xf:b2XForm, dX:Number, dY:Number) : b2Vec2
  369.       {
  370.          var tVec:b2Vec2 = null;
  371.          var tMat:b2Mat22 = null;
  372.          var value:Number = NaN;
  373.          tMat = xf.R;
  374.          var dLocalX:Number = dX * tMat.col1.x + dY * tMat.col1.y;
  375.          var dLocalY:Number = dX * tMat.col2.x + dY * tMat.col2.y;
  376.          var bestIndex:int = 0;
  377.          tVec = m_coreVertices[0];
  378.          var bestValue:Number = tVec.x * dLocalX + tVec.y * dLocalY;
  379.          for(var i:int = 1; i < m_vertexCount; i++)
  380.          {
  381.             tVec = m_coreVertices[i];
  382.             value = tVec.x * dLocalX + tVec.y * dLocalY;
  383.             if(value > bestValue)
  384.             {
  385.                bestIndex = i;
  386.                bestValue = value;
  387.             }
  388.          }
  389.          tMat = xf.R;
  390.          tVec = m_coreVertices[bestIndex];
  391.          s_supportVec.x = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
  392.          s_supportVec.y = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
  393.          return s_supportVec;
  394.       }
  395.       
  396.       public function GetVertexCount() : int
  397.       {
  398.          return m_vertexCount;
  399.       }
  400.       
  401.       override public function ComputeAABB(aabb:b2AABB, xf:b2XForm) : void
  402.       {
  403.          var tMat:b2Mat22 = null;
  404.          var tVec:b2Vec2 = null;
  405.          var R:b2Mat22 = s_computeMat;
  406.          tMat = xf.R;
  407.          tVec = m_obb.R.col1;
  408.          R.col1.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
  409.          R.col1.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
  410.          tVec = m_obb.R.col2;
  411.          R.col2.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
  412.          R.col2.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
  413.          R.Abs();
  414.          var absR:b2Mat22 = R;
  415.          tVec = m_obb.extents;
  416.          var hX:Number = absR.col1.x * tVec.x + absR.col2.x * tVec.y;
  417.          var hY:Number = absR.col1.y * tVec.x + absR.col2.y * tVec.y;
  418.          tMat = xf.R;
  419.          tVec = m_obb.center;
  420.          var positionX:Number = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
  421.          var positionY:Number = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
  422.          aabb.lowerBound.Set(positionX - hX,positionY - hY);
  423.          aabb.upperBound.Set(positionX + hX,positionY + hY);
  424.       }
  425.       
  426.       override public function UpdateSweepRadius(center:b2Vec2) : void
  427.       {
  428.          var tVec:b2Vec2 = null;
  429.          var dX:Number = NaN;
  430.          var dY:Number = NaN;
  431.          m_sweepRadius = 0;
  432.          for(var i:int = 0; i < m_vertexCount; i++)
  433.          {
  434.             tVec = m_coreVertices[i];
  435.             dX = tVec.x - center.x;
  436.             dY = tVec.y - center.y;
  437.             dX = Math.sqrt(dX * dX + dY * dY);
  438.             if(dX > m_sweepRadius)
  439.             {
  440.                m_sweepRadius = dX;
  441.             }
  442.          }
  443.       }
  444.       
  445.       override public function TestPoint(xf:b2XForm, p:b2Vec2) : Boolean
  446.       {
  447.          var tVec:b2Vec2 = null;
  448.          var dot:Number = NaN;
  449.          var tMat:b2Mat22 = xf.R;
  450.          var tX:Number = p.x - xf.position.x;
  451.          var tY:Number = p.y - xf.position.y;
  452.          var pLocalX:Number = tX * tMat.col1.x + tY * tMat.col1.y;
  453.          var pLocalY:Number = tX * tMat.col2.x + tY * tMat.col2.y;
  454.          for(var i:int = 0; i < m_vertexCount; i++)
  455.          {
  456.             tVec = m_vertices[i];
  457.             tX = pLocalX - tVec.x;
  458.             tY = pLocalY - tVec.y;
  459.             tVec = m_normals[i];
  460.             dot = tVec.x * tX + tVec.y * tY;
  461.             if(dot > 0)
  462.             {
  463.                return false;
  464.             }
  465.          }
  466.          return true;
  467.       }
  468.    }
  469. }
  470.