topical media & game development

talk show tell print

#javascript-physics-js-box2d-collision-shapes-b2PolyShape.js / js



  /*
  * Copyright (c) 2006-2007 Erin Catto 
* This software is provided 'as-is', without any express or implied
* warranty.  In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/

// A convex polygon. The position of the polygon (m_position) is the
// position of the centroid. The vertices of the incoming polygon are pre-rotated
// according to the local rotation. The vertices are also shifted to be centered
// on the centroid. Since the local rotation is absorbed into the vertex
// coordinates, the polygon rotation is equal to the body rotation. However,
// the polygon position is centered on the polygon centroid. This simplifies
// some collision algorithms.

var b2PolyShape = Class.create();
Object.extend(b2PolyShape.prototype, b2Shape.prototype);
Object.extend(b2PolyShape.prototype, 
{
        TestPoint: function(p){

                //var pLocal = b2Math.b2MulTMV(this.m_R, b2Math.SubtractVV(p, this.m_position));
                var pLocal = new b2Vec2();
                pLocal.SetV(p);
                pLocal.Subtract(this.m_position);
                pLocal.MulTM(this.m_R);

                for (var i = 0; i < this.m_vertexCount; ++i)
                {
                        //var dot = b2Math.b2Dot(this.m_normals[i], b2Math.SubtractVV(pLocal, this.m_vertices[i]));
                        var tVec = new b2Vec2();
                        tVec.SetV(pLocal);
                        tVec.Subtract(this.m_vertices[i]);

                        var dot = b2Math.b2Dot(this.m_normals[i], tVec);
                        if (dot > 0.0)
                        {
                                return false;
                        }
                }

                return true;
        },

        //--------------- Internals Below -------------------
        // Temp vec for b2Shape.PolyCentroid

        initialize: function(def, body, newOrigin){
                // initialize instance variables for references
                this.m_R = new b2Mat22();
                this.m_position = new b2Vec2();
                //

                // The constructor for b2Shape
                this.m_userData = def.userData;

                this.m_friction = def.friction;
                this.m_restitution = def.restitution;
                this.m_body = body;

                this.m_proxyId = b2Pair.b2_nullProxy;

                this.m_maxRadius = 0.0;

                this.m_categoryBits = def.categoryBits;
                this.m_maskBits = def.maskBits;
                this.m_groupIndex = def.groupIndex;
                //

                // initialize instance variables for references
                this.syncAABB = new b2AABB();
                this.syncMat = new b2Mat22();
                this.m_localCentroid = new b2Vec2();
                this.m_localOBB = new b2OBB();
                //

                //super(def, body);

                var i = 0;

                var hX;
                var hY;

                var tVec;

                var aabb = new b2AABB();

                // Vertices
                this.m_vertices = new Array(b2Settings.b2_maxPolyVertices);
                this.m_coreVertices = new Array(b2Settings.b2_maxPolyVertices);
                //for (i = 0; i < b2Settings.b2_maxPolyVertices; i++)
                //        this.m_vertices[i] = new b2Vec2();

                // Normals
                this.m_normals = new Array(b2Settings.b2_maxPolyVertices);
                //for (i = 0; i < b2Settings.b2_maxPolyVertices; i++)
                //        this.m_normals[i] = new b2Vec2();

                //b2Settings.b2Assert(def.type == b2Shape.e_boxShape || def.type == b2Shape.e_polyShape);
                this.m_type = b2Shape.e_polyShape;

                var localR = new b2Mat22(def.localRotation);

                // Get the vertices transformed into the body frame.
                if (def.type == b2Shape.e_boxShape)
                {
                        //this.m_localCentroid = def.localPosition - newOrigin;
                        this.m_localCentroid.x = def.localPosition.x - newOrigin.x;
                        this.m_localCentroid.y = def.localPosition.y - newOrigin.y;

                        var box = def;
                        this.m_vertexCount = 4;
                        hX = box.extents.x;
                        hY = box.extents.y;

                        //hc.x = b2Max(0.0f, h.x - 2.0f * b2_linearSlop);
                        var hcX = Math.max(0.0, hX - 2.0 * b2Settings.b2_linearSlop);
                        //hc.y = b2Max(0.0f, h.y - 2.0f * b2_linearSlop);
                        var hcY = Math.max(0.0, hY - 2.0 * b2Settings.b2_linearSlop);

                        //this.m_vertices[0] = b2Mul(localR, b2Vec2(h.x, h.y));
                        tVec = this.m_vertices[0] = new b2Vec2();
                        tVec.x = localR.col1.x * hX + localR.col2.x * hY;
                        tVec.y = localR.col1.y * hX + localR.col2.y * hY;
                        //this.m_vertices[1] = b2Mul(localR, b2Vec2(-h.x, h.y));
                        tVec = this.m_vertices[1] = new b2Vec2();
                        tVec.x = localR.col1.x * -hX + localR.col2.x * hY;
                        tVec.y = localR.col1.y * -hX + localR.col2.y * hY;
                        //this.m_vertices[2] = b2Mul(localR, b2Vec2(-h.x, -h.y));
                        tVec = this.m_vertices[2] = new b2Vec2();
                        tVec.x = localR.col1.x * -hX + localR.col2.x * -hY;
                        tVec.y = localR.col1.y * -hX + localR.col2.y * -hY;
                        //this.m_vertices[3] = b2Mul(localR, b2Vec2(h.x, -h.y));
                        tVec = this.m_vertices[3] = new b2Vec2();
                        tVec.x = localR.col1.x * hX + localR.col2.x * -hY;
                        tVec.y = localR.col1.y * hX + localR.col2.y * -hY;

                        //this.m_coreVertices[0] = b2Mul(localR, b2Vec2(hc.x, hc.y));
                        tVec = this.m_coreVertices[0] = new b2Vec2();
                        tVec.x = localR.col1.x * hcX + localR.col2.x * hcY;
                        tVec.y = localR.col1.y * hcX + localR.col2.y * hcY;
                        //this.m_coreVertices[1] = b2Mul(localR, b2Vec2(-hc.x, hc.y));
                        tVec = this.m_coreVertices[1] = new b2Vec2();
                        tVec.x = localR.col1.x * -hcX + localR.col2.x * hcY;
                        tVec.y = localR.col1.y * -hcX + localR.col2.y * hcY;
                        //this.m_coreVertices[2] = b2Mul(localR, b2Vec2(-hc.x, -hc.y));
                        tVec = this.m_coreVertices[2] = new b2Vec2();
                        tVec.x = localR.col1.x * -hcX + localR.col2.x * -hcY;
                        tVec.y = localR.col1.y * -hcX + localR.col2.y * -hcY;
                        //this.m_coreVertices[3] = b2Mul(localR, b2Vec2(hc.x, -hc.y));
                        tVec = this.m_coreVertices[3] = new b2Vec2();
                        tVec.x = localR.col1.x * hcX + localR.col2.x * -hcY;
                        tVec.y = localR.col1.y * hcX + localR.col2.y * -hcY;
                }
                else
                {
      
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the authors be held liable for any damages
  * arising from the use of this software.
  * Permission is granted to anyone to use this software for any purpose,
  * including commercial applications, and to alter it and redistribute it
  * freely, subject to the following restrictions:
  * 1. The origin of this software must not be misrepresented; you must not
  * claim that you wrote the original software. If you use this software
  * in a product, an acknowledgment in the product documentation would be
  * appreciated but is not required.
  * 2. Altered source versions must be plainly marked, and must not be
  * misrepresented the original software.
  * 3. This notice may not be removed or altered from any source distribution.
  */
  
  // A convex polygon. The position of the polygon (m_position) is the
  // position of the centroid. The vertices of the incoming polygon are pre-rotated
  // according to the local rotation. The vertices are also shifted to be centered
  // on the centroid. Since the local rotation is absorbed into the vertex
  // coordinates, the polygon rotation is equal to the body rotation. However,
  // the polygon position is centered on the polygon centroid. This simplifies
  // some collision algorithms.
  
  var b2PolyShape = Class.create();
  Object.extend(b2PolyShape.prototype, b2Shape.prototype);
  Object.extend(b2PolyShape.prototype, 
  {
          TestPoint: function(p){
  
                  //var pLocal = b2Math.b2MulTMV(this.m_R, b2Math.SubtractVV(p, this.m_position));
                  var pLocal = new b2Vec2();
                  pLocal.SetV(p);
                  pLocal.Subtract(this.m_position);
                  pLocal.MulTM(this.m_R);
  
                  for (var i = 0; i < this.m_vertexCount; ++i)
                  {
                          //var dot = b2Math.b2Dot(this.m_normals[i], b2Math.SubtractVV(pLocal, this.m_vertices[i]));
                          var tVec = new b2Vec2();
                          tVec.SetV(pLocal);
                          tVec.Subtract(this.m_vertices[i]);
  
                          var dot = b2Math.b2Dot(this.m_normals[i], tVec);
                          if (dot > 0.0)
                          {
                                  return false;
                          }
                  }
  
                  return true;
          },
  
          //--------------- Internals Below -------------------
          // Temp vec for b2Shape.PolyCentroid
  
          initialize: function(def, body, newOrigin){
                  // initialize instance variables for references
                  this.m_R = new b2Mat22();
                  this.m_position = new b2Vec2();
                  //
  
                  // The constructor for b2Shape
                  this.m_userData = def.userData;
  
                  this.m_friction = def.friction;
                  this.m_restitution = def.restitution;
                  this.m_body = body;
  
                  this.m_proxyId = b2Pair.b2_nullProxy;
  
                  this.m_maxRadius = 0.0;
  
                  this.m_categoryBits = def.categoryBits;
                  this.m_maskBits = def.maskBits;
                  this.m_groupIndex = def.groupIndex;
                  //
  
                  // initialize instance variables for references
                  this.syncAABB = new b2AABB();
                  this.syncMat = new b2Mat22();
                  this.m_localCentroid = new b2Vec2();
                  this.m_localOBB = new b2OBB();
                  //
  
                  //super(def, body);
  
                  var i = 0;
  
                  var hX;
                  var hY;
  
                  var tVec;
  
                  var aabb = new b2AABB();
  
                  // Vertices
                  this.m_vertices = new Array(b2Settings.b2_maxPolyVertices);
                  this.m_coreVertices = new Array(b2Settings.b2_maxPolyVertices);
                  //for (i = 0; i < b2Settings.b2_maxPolyVertices; i++)
                  //        this.m_vertices[i] = new b2Vec2();
  
                  // Normals
                  this.m_normals = new Array(b2Settings.b2_maxPolyVertices);
                  //for (i = 0; i < b2Settings.b2_maxPolyVertices; i++)
                  //        this.m_normals[i] = new b2Vec2();
  
                  //b2Settings.b2Assert(def.type == b2Shape.e_boxShape || def.type == b2Shape.e_polyShape);
                  this.m_type = b2Shape.e_polyShape;
  
                  var localR = new b2Mat22(def.localRotation);
  
                  // Get the vertices transformed into the body frame.
                  if (def.type == b2Shape.e_boxShape)
                  {
                          //this.m_localCentroid = def.localPosition - newOrigin;
                          this.m_localCentroid.x = def.localPosition.x - newOrigin.x;
                          this.m_localCentroid.y = def.localPosition.y - newOrigin.y;
  
                          var box = def;
                          this.m_vertexCount = 4;
                          hX = box.extents.x;
                          hY = box.extents.y;
  
                          //hc.x = b2Max(0.0f, h.x - 2.0f * b2_linearSlop);
                          var hcX = Math.max(0.0, hX - 2.0 * b2Settings.b2_linearSlop);
                          //hc.y = b2Max(0.0f, h.y - 2.0f * b2_linearSlop);
                          var hcY = Math.max(0.0, hY - 2.0 * b2Settings.b2_linearSlop);
  
                          //this.m_vertices[0] = b2Mul(localR, b2Vec2(h.x, h.y));
                          tVec = this.m_vertices[0] = new b2Vec2();
                          tVec.x = localR.col1.x * hX + localR.col2.x * hY;
                          tVec.y = localR.col1.y * hX + localR.col2.y * hY;
                          //this.m_vertices[1] = b2Mul(localR, b2Vec2(-h.x, h.y));
                          tVec = this.m_vertices[1] = new b2Vec2();
                          tVec.x = localR.col1.x * -hX + localR.col2.x * hY;
                          tVec.y = localR.col1.y * -hX + localR.col2.y * hY;
                          //this.m_vertices[2] = b2Mul(localR, b2Vec2(-h.x, -h.y));
                          tVec = this.m_vertices[2] = new b2Vec2();
                          tVec.x = localR.col1.x * -hX + localR.col2.x * -hY;
                          tVec.y = localR.col1.y * -hX + localR.col2.y * -hY;
                          //this.m_vertices[3] = b2Mul(localR, b2Vec2(h.x, -h.y));
                          tVec = this.m_vertices[3] = new b2Vec2();
                          tVec.x = localR.col1.x * hX + localR.col2.x * -hY;
                          tVec.y = localR.col1.y * hX + localR.col2.y * -hY;
  
                          //this.m_coreVertices[0] = b2Mul(localR, b2Vec2(hc.x, hc.y));
                          tVec = this.m_coreVertices[0] = new b2Vec2();
                          tVec.x = localR.col1.x * hcX + localR.col2.x * hcY;
                          tVec.y = localR.col1.y * hcX + localR.col2.y * hcY;
                          //this.m_coreVertices[1] = b2Mul(localR, b2Vec2(-hc.x, hc.y));
                          tVec = this.m_coreVertices[1] = new b2Vec2();
                          tVec.x = localR.col1.x * -hcX + localR.col2.x * hcY;
                          tVec.y = localR.col1.y * -hcX + localR.col2.y * hcY;
                          //this.m_coreVertices[2] = b2Mul(localR, b2Vec2(-hc.x, -hc.y));
                          tVec = this.m_coreVertices[2] = new b2Vec2();
                          tVec.x = localR.col1.x * -hcX + localR.col2.x * -hcY;
                          tVec.y = localR.col1.y * -hcX + localR.col2.y * -hcY;
                          //this.m_coreVertices[3] = b2Mul(localR, b2Vec2(hc.x, -hc.y));
                          tVec = this.m_coreVertices[3] = new b2Vec2();
                          tVec.x = localR.col1.x * hcX + localR.col2.x * -hcY;
                          tVec.y = localR.col1.y * hcX + localR.col2.y * -hcY;
                  }
                  else
                  {
                          var poly = def;
  
                          this.m_vertexCount = poly.vertexCount;
                          //b2Settings.b2Assert(3 <= this.m_vertexCount && this.m_vertexCount <= b2Settings.b2_maxPolyVertices);
                          //b2Vec2 centroid = b2Shape.PolyCentroid(poly->vertices, poly->vertexCount);
                          b2Shape.PolyCentroid(poly.vertices, poly.vertexCount, b2PolyShape.tempVec);
                          var centroidX = b2PolyShape.tempVec.x;
                          var centroidY = b2PolyShape.tempVec.y;
                          //this.m_localCentroid = def->localPosition + b2Mul(localR, centroid) - newOrigin;
                          this.m_localCentroid.x = def.localPosition.x + (localR.col1.x * centroidX + localR.col2.x * centroidY) - newOrigin.x;
                          this.m_localCentroid.y = def.localPosition.y + (localR.col1.y * centroidX + localR.col2.y * centroidY) - newOrigin.y;
  
                          for (i = 0; i < this.m_vertexCount; ++i)
                          {
                                  this.m_vertices[i] = new b2Vec2();
                                  this.m_coreVertices[i] = new b2Vec2();
  
                                  //this.m_vertices[i] = b2Mul(localR, poly->vertices[i] - centroid);
                                  hX = poly.vertices[i].x - centroidX;
                                  hY = poly.vertices[i].y - centroidY;
                                  this.m_vertices[i].x = localR.col1.x * hX + localR.col2.x * hY;
                                  this.m_vertices[i].y = localR.col1.y * hX + localR.col2.y * hY;
  
                                  //b2Vec2 u = this.m_vertices[i];
                                  var uX = this.m_vertices[i].x;
                                  var uY = this.m_vertices[i].y;
                                  //float32 length = u.Length();
                                  var length = Math.sqrt(uX*uX + uY*uY);
                                  if (length > Number.MIN_VALUE)
                                  {
                                          uX *= 1.0 / length;
                                          uY *= 1.0 / length;
                                  }
  
                                  //this.m_coreVertices[i] = this.m_vertices[i] - 2.0f * b2_linearSlop * u;
                                  this.m_coreVertices[i].x = this.m_vertices[i].x - 2.0 * b2Settings.b2_linearSlop * uX;
                                  this.m_coreVertices[i].y = this.m_vertices[i].y - 2.0 * b2Settings.b2_linearSlop * uY;
                          }
  
                  }
  
                  // Compute bounding box. TODO_ERIN optimize OBB
                  //var minVertex = new b2Vec2(Number.MAX_VALUE, Number.MAX_VALUE);
                  var minVertexX = Number.MAX_VALUE;
                  var minVertexY = Number.MAX_VALUE;
                  var maxVertexX = -Number.MAX_VALUE;
                  var maxVertexY = -Number.MAX_VALUE;
                  this.m_maxRadius = 0.0;
                  for (i = 0; i < this.m_vertexCount; ++i)
                  {
                          var v = this.m_vertices[i];
                          //minVertex = b2Math.b2MinV(minVertex, this.m_vertices[i]);
                          minVertexX = Math.min(minVertexX, v.x);
                          minVertexY = Math.min(minVertexY, v.y);
                          //maxVertex = b2Math.b2MaxV(maxVertex, this.m_vertices[i]);
                          maxVertexX = Math.max(maxVertexX, v.x);
                          maxVertexY = Math.max(maxVertexY, v.y);
                          //this.m_maxRadius = b2Max(this.m_maxRadius, v.Length());
                          this.m_maxRadius = Math.max(this.m_maxRadius, v.Length());
                  }
  
                  this.m_localOBB.R.SetIdentity();
                  //this.m_localOBB.center = 0.5 * (minVertex + maxVertex);
                  this.m_localOBB.center.Set((minVertexX + maxVertexX) * 0.5, (minVertexY + maxVertexY) * 0.5);
                  //this.m_localOBB.extents = 0.5 * (maxVertex - minVertex);
                  this.m_localOBB.extents.Set((maxVertexX - minVertexX) * 0.5, (maxVertexY - minVertexY) * 0.5);
  
                  // Compute the edge normals and next index map.
                  var i1 = 0;
                  var i2 = 0;
                  for (i = 0; i < this.m_vertexCount; ++i)
                  {
                          this.m_normals[i] =  new b2Vec2();
                          i1 = i;
                          i2 = i + 1 < this.m_vertexCount ? i + 1 : 0;
                          //b2Vec2 edge = this.m_vertices[i2] - this.m_vertices[i1];
                          //var edgeX = this.m_vertices[i2].x - this.m_vertices[i1].x;
                          //var edgeY = this.m_vertices[i2].y - this.m_vertices[i1].y;
                          //this.m_normals[i] = b2Cross(edge, 1.0f);
                          this.m_normals[i].x = this.m_vertices[i2].y - this.m_vertices[i1].y;
                          this.m_normals[i].y = -(this.m_vertices[i2].x - this.m_vertices[i1].x);
                          this.m_normals[i].Normalize();
                  }
  
                  // Ensure the polygon in convex. TODO_ERIN compute convex hull.
                  for (i = 0; i < this.m_vertexCount; ++i)
                  {
                          i1 = i;
                          i2 = i + 1 < this.m_vertexCount ? i + 1 : 0;
  
                          //b2Settings.b2Assert(b2Math.b2CrossVV(this.m_normals[i1], this.m_normals[i2]) > Number.MIN_VALUE);
                  }
  
                  this.m_R.SetM(this.m_body.m_R);
                  //this.m_position.SetV( this.m_body.m_position  + b2Mul(this.m_body->this.m_R, this.m_localCentroid) );
                  this.m_position.x = this.m_body.m_position.x + (this.m_R.col1.x * this.m_localCentroid.x + this.m_R.col2.x * this.m_localCentroid.y);
                  this.m_position.y = this.m_body.m_position.y + (this.m_R.col1.y * this.m_localCentroid.x + this.m_R.col2.y * this.m_localCentroid.y);
  
                  //var R = b2Math.b2MulMM(this.m_R, this.m_localOBB.R);
                          //R.col1 = b2MulMV(this.m_R, this.m_localOBB.R.col1);
                          b2PolyShape.tAbsR.col1.x = this.m_R.col1.x * this.m_localOBB.R.col1.x + this.m_R.col2.x * this.m_localOBB.R.col1.y;
                          b2PolyShape.tAbsR.col1.y = this.m_R.col1.y * this.m_localOBB.R.col1.x + this.m_R.col2.y * this.m_localOBB.R.col1.y;
                          //R.col2 = b2MulMV(this.m_R, this.m_localOBB.R.col2)
                          b2PolyShape.tAbsR.col2.x = this.m_R.col1.x * this.m_localOBB.R.col2.x + this.m_R.col2.x * this.m_localOBB.R.col2.y;
                          b2PolyShape.tAbsR.col2.y = this.m_R.col1.y * this.m_localOBB.R.col2.x + this.m_R.col2.y * this.m_localOBB.R.col2.y;
                  //var absR = b2Math.b2AbsM(R);
                  b2PolyShape.tAbsR.Abs()
  
                  //h = b2Math.b2MulMV(b2PolyShape.tAbsR, this.m_localOBB.extents);
                  hX = b2PolyShape.tAbsR.col1.x * this.m_localOBB.extents.x + b2PolyShape.tAbsR.col2.x * this.m_localOBB.extents.y;
                  hY = b2PolyShape.tAbsR.col1.y * this.m_localOBB.extents.x + b2PolyShape.tAbsR.col2.y * this.m_localOBB.extents.y;
  
                  //var position = this.m_position + b2Mul(this.m_R, this.m_localOBB.center);
                  var positionX = this.m_position.x + (this.m_R.col1.x * this.m_localOBB.center.x + this.m_R.col2.x * this.m_localOBB.center.y);
                  var positionY = this.m_position.y + (this.m_R.col1.y * this.m_localOBB.center.x + this.m_R.col2.y * this.m_localOBB.center.y);
  
                  //aabb.minVertex = b2Math.SubtractVV(this.m_position, h);
                  aabb.minVertex.x = positionX - hX;
                  aabb.minVertex.y = positionY - hY;
                  //aabb.maxVertex = b2Math.AddVV(this.m_position, h);
                  aabb.maxVertex.x = positionX + hX;
                  aabb.maxVertex.y = positionY + hY;
  
                  var broadPhase = this.m_body.m_world.m_broadPhase;
                  if (broadPhase.InRange(aabb))
                  {
                          this.m_proxyId = broadPhase.CreateProxy(aabb, this);
                  }
                  else
                  {
                          this.m_proxyId = b2Pair.b2_nullProxy;
                  }
  
                  if (this.m_proxyId == b2Pair.b2_nullProxy)
                  {
                          this.m_body.Freeze();
                  }
          },
  
          // Temp AABB for Synch function
          syncAABB: new b2AABB(),
          syncMat: new b2Mat22(),
          Synchronize: function(position1, R1, position2, R2){
                  // The body transform is copied for convenience.
                  this.m_R.SetM(R2);
                  //this.m_position = this.m_body->this.m_position + b2Mul(this.m_body->this.m_R, this.m_localCentroid)
                  this.m_position.x = this.m_body.m_position.x + (R2.col1.x * this.m_localCentroid.x + R2.col2.x * this.m_localCentroid.y);
                  this.m_position.y = this.m_body.m_position.y + (R2.col1.y * this.m_localCentroid.x + R2.col2.y * this.m_localCentroid.y);
  
                  if (this.m_proxyId == b2Pair.b2_nullProxy)
                  {
                          return;
                  }
  
                  //b2AABB aabb1, aabb2;
                  var hX;
                  var hY;
  
                  //b2Mat22 obbR = b2Mul(R1, this.m_localOBB.R);
                          var v1 = R1.col1;
                          var v2 = R1.col2;
                          var v3 = this.m_localOBB.R.col1;
                          var v4 = this.m_localOBB.R.col2;
                          //this.syncMat.col1 = b2MulMV(R1, this.m_localOBB.R.col1);
                          this.syncMat.col1.x = v1.x * v3.x + v2.x * v3.y;
                          this.syncMat.col1.y = v1.y * v3.x + v2.y * v3.y;
                          //this.syncMat.col2 = b2MulMV(R1, this.m_localOBB.R.col2);
                          this.syncMat.col2.x = v1.x * v4.x + v2.x * v4.y;
                          this.syncMat.col2.y = v1.y * v4.x + v2.y * v4.y;
                  //b2Mat22 absR = b2Abs(obbR);
                  this.syncMat.Abs();
                  //b2Vec2 center = position1 + b2Mul(R1, this.m_localCentroid + this.m_localOBB.center);
                  hX = this.m_localCentroid.x + this.m_localOBB.center.x;
                  hY = this.m_localCentroid.y + this.m_localOBB.center.y;
                  var centerX = position1.x + (R1.col1.x * hX + R1.col2.x * hY);
                  var centerY = position1.y + (R1.col1.y * hX + R1.col2.y * hY);
                  //b2Vec2 h = b2Mul(this.syncMat, this.m_localOBB.extents);
                  hX = this.syncMat.col1.x * this.m_localOBB.extents.x + this.syncMat.col2.x * this.m_localOBB.extents.y;
                  hY = this.syncMat.col1.y * this.m_localOBB.extents.x + this.syncMat.col2.y * this.m_localOBB.extents.y;
                  //aabb1.minVertex = center - h;
                  this.syncAABB.minVertex.x = centerX - hX;
                  this.syncAABB.minVertex.y = centerY - hY;
                  //aabb1.maxVertex = center + h;
                  this.syncAABB.maxVertex.x = centerX + hX;
                  this.syncAABB.maxVertex.y = centerY + hY;
  
                  //b2Mat22 obbR = b2Mul(R2, this.m_localOBB.R);
                          v1 = R2.col1;
                          v2 = R2.col2;
                          v3 = this.m_localOBB.R.col1;
                          v4 = this.m_localOBB.R.col2;
                          //this.syncMat.col1 = b2MulMV(R1, this.m_localOBB.R.col1);
                          this.syncMat.col1.x = v1.x * v3.x + v2.x * v3.y;
                          this.syncMat.col1.y = v1.y * v3.x + v2.y * v3.y;
                          //this.syncMat.col2 = b2MulMV(R1, this.m_localOBB.R.col2);
                          this.syncMat.col2.x = v1.x * v4.x + v2.x * v4.y;
                          this.syncMat.col2.y = v1.y * v4.x + v2.y * v4.y;
                  //b2Mat22 absR = b2Abs(obbR);
                  this.syncMat.Abs();
                  //b2Vec2 center = position2 + b2Mul(R2, this.m_localCentroid + this.m_localOBB.center);
                  hX = this.m_localCentroid.x + this.m_localOBB.center.x;
                  hY = this.m_localCentroid.y + this.m_localOBB.center.y;
                  centerX = position2.x + (R2.col1.x * hX + R2.col2.x * hY);
                  centerY = position2.y + (R2.col1.y * hX + R2.col2.y * hY);
                  //b2Vec2 h = b2Mul(absR, this.m_localOBB.extents);
                  hX = this.syncMat.col1.x * this.m_localOBB.extents.x + this.syncMat.col2.x * this.m_localOBB.extents.y;
                  hY = this.syncMat.col1.y * this.m_localOBB.extents.x + this.syncMat.col2.y * this.m_localOBB.extents.y;
                  //aabb2.minVertex = center - h;
                  //aabb2.maxVertex = center + h;
  
                  //aabb.minVertex = b2Min(aabb1.minVertex, aabb2.minVertex);
                  this.syncAABB.minVertex.x = Math.min(this.syncAABB.minVertex.x, centerX - hX);
                  this.syncAABB.minVertex.y = Math.min(this.syncAABB.minVertex.y, centerY - hY);
                  //aabb.maxVertex = b2Max(aabb1.maxVertex, aabb2.maxVertex);
                  this.syncAABB.maxVertex.x = Math.max(this.syncAABB.maxVertex.x, centerX + hX);
                  this.syncAABB.maxVertex.y = Math.max(this.syncAABB.maxVertex.y, centerY + hY);
  
                  var broadPhase = this.m_body.m_world.m_broadPhase;
                  if (broadPhase.InRange(this.syncAABB))
                  {
                          broadPhase.MoveProxy(this.m_proxyId, this.syncAABB);
                  }
                  else
                  {
                          this.m_body.Freeze();
                  }
          },
  
          QuickSync: function(position, R){
                  //this.m_R = R;
                  this.m_R.SetM(R);
                  //this.m_position = position + b2Mul(R, this.m_localCentroid);
                  this.m_position.x = position.x + (R.col1.x * this.m_localCentroid.x + R.col2.x * this.m_localCentroid.y);
                  this.m_position.y = position.y + (R.col1.y * this.m_localCentroid.x + R.col2.y * this.m_localCentroid.y);
          },
  
          ResetProxy: function(broadPhase){
  
                  if (this.m_proxyId == b2Pair.b2_nullProxy)
                  {
                          return;
                  }
  
                  var proxy = broadPhase.GetProxy(this.m_proxyId);
  
                  broadPhase.DestroyProxy(this.m_proxyId);
                  proxy = null;
  
                  var R = b2Math.b2MulMM(this.m_R, this.m_localOBB.R);
                  var absR = b2Math.b2AbsM(R);
                  var h = b2Math.b2MulMV(absR, this.m_localOBB.extents);
                  //var position = this.m_position + b2Mul(this.m_R, this.m_localOBB.center);
                  var position = b2Math.b2MulMV(this.m_R, this.m_localOBB.center);
                  position.Add(this.m_position);
  
                  var aabb = new b2AABB();
                  //aabb.minVertex = position - h;
                  aabb.minVertex.SetV(position);
                  aabb.minVertex.Subtract(h);
                  //aabb.maxVertex = position + h;
                  aabb.maxVertex.SetV(position);
                  aabb.maxVertex.Add(h);
  
                  if (broadPhase.InRange(aabb))
                  {
                          this.m_proxyId = broadPhase.CreateProxy(aabb, this);
                  }
                  else
                  {
                          this.m_proxyId = b2Pair.b2_nullProxy;
                  }
  
                  if (this.m_proxyId == b2Pair.b2_nullProxy)
                  {
                          this.m_body.Freeze();
                  }
          },
  
          Support: function(dX, dY, out)
          {
                  //b2Vec2 dLocal = b2MulT(this.m_R, d);
                  var dLocalX = (dX*this.m_R.col1.x + dY*this.m_R.col1.y);
                  var dLocalY = (dX*this.m_R.col2.x + dY*this.m_R.col2.y);
  
                  var bestIndex = 0;
                  //float32 bestValue = b2Dot(this.m_vertices[0], dLocal);
                  var bestValue = (this.m_coreVertices[0].x * dLocalX + this.m_coreVertices[0].y * dLocalY);
                  for (var i = 1; i < this.m_vertexCount; ++i)
                  {
                          //float32 value = b2Dot(this.m_vertices[i], dLocal);
                          var value = (this.m_coreVertices[i].x * dLocalX + this.m_coreVertices[i].y * dLocalY);
                          if (value > bestValue)
                          {
                                  bestIndex = i;
                                  bestValue = value;
                          }
                  }
  
                  //return this.m_position + b2Mul(this.m_R, this.m_vertices[bestIndex]);
                  out.Set(        this.m_position.x + (this.m_R.col1.x * this.m_coreVertices[bestIndex].x + this.m_R.col2.x * this.m_coreVertices[bestIndex].y),
                                          this.m_position.y + (this.m_R.col1.y * this.m_coreVertices[bestIndex].x + this.m_R.col2.y * this.m_coreVertices[bestIndex].y));
  
          },
  
          // Local position of the shape centroid in parent body frame.
          m_localCentroid: new b2Vec2(),
  
          // Local position oriented bounding box. The OBB center is relative to
          // shape centroid.
          m_localOBB: new b2OBB(),
          m_vertices: null,
          m_coreVertices: null,
          m_vertexCount: 0,
          m_normals: null});
  
  b2PolyShape.tempVec = new b2Vec2();
  b2PolyShape.tAbsR = new b2Mat22();
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.