Box2DX.Collision.PolygonShape.ComputeOBB C# (CSharp) Method

ComputeOBB() public static method

public static ComputeOBB ( OBB &obb, Vec2 vs, int count ) : void
obb OBB
vs Box2DX.Common.Vec2
count int
return void
		public static void ComputeOBB(out OBB obb, Vec2[] vs, int count)
		{
			obb = new OBB();

			Box2DXDebug.Assert(count <= Settings.MaxPolygonVertices);
			Vec2[] p = new Vec2[Settings.MaxPolygonVertices + 1];
			for (int i = 0; i < count; ++i)
			{
				p[i] = vs[i];
			}
			p[count] = p[0];

			float minArea = Common.Settings.FLT_MAX;

			for (int i = 1; i <= count; ++i)
			{
				Vec2 root = p[i - 1];
				Vec2 ux = p[i] - root;
				float length = ux.Normalize();
				Box2DXDebug.Assert(length > Common.Settings.FLT_EPSILON);
				Vec2 uy = new Vec2(-ux.Y, ux.X);
				Vec2 lower = new Vec2(Common.Settings.FLT_MAX, Common.Settings.FLT_MAX);
				Vec2 upper = new Vec2(-Common.Settings.FLT_MAX, -Common.Settings.FLT_MAX);

				for (int j = 0; j < count; ++j)
				{
					Vec2 d = p[j] - root;
					Vec2 r = new Vec2();
					r.X = Vec2.Dot(ux, d);
					r.Y = Vec2.Dot(uy, d);
					lower = Common.Math.Min(lower, r);
					upper = Common.Math.Max(upper, r);
				}

				float area = (upper.X - lower.X) * (upper.Y - lower.Y);
				if (area < 0.95f * minArea)
				{
					minArea = area;
					obb.R.Col1 = ux;
					obb.R.Col2 = uy;
					Vec2 center = 0.5f * (lower + upper);
					obb.Center = root + Common.Math.Mul(obb.R, center);
					obb.Extents = 0.5f * (upper - lower);
				}
			}

			Box2DXDebug.Assert(minArea < Common.Settings.FLT_MAX);
		}
	}

Usage Example

Example #1
0
        internal PolygonShape(ShapeDef def) : base(def)
        {
            Box2DXDebug.Assert(def.Type == ShapeType.PolygonShape);
            this._type = ShapeType.PolygonShape;
            PolygonDef polygonDef = (PolygonDef)def;

            this._vertexCount = polygonDef.VertexCount;
            Box2DXDebug.Assert(3 <= this._vertexCount && this._vertexCount <= Settings.MaxPolygonVertices);
            for (int i = 0; i < this._vertexCount; i++)
            {
                this._vertices[i] = polygonDef.Vertices[i];
            }
            for (int i = 0; i < this._vertexCount; i++)
            {
                int  num  = i;
                int  num2 = (i + 1 < this._vertexCount) ? (i + 1) : 0;
                Vec2 a    = this._vertices[num2] - this._vertices[num];
                Box2DXDebug.Assert(a.LengthSquared() > Settings.FLT_EPSILON * Settings.FLT_EPSILON);
                this._normals[i] = Vec2.Cross(a, 1f);
                this._normals[i].Normalize();
            }
            for (int i = 0; i < this._vertexCount; i++)
            {
                for (int j = 0; j < this._vertexCount; j++)
                {
                    if (j != i && j != (i + 1) % this._vertexCount)
                    {
                        float num3 = Vec2.Dot(this._normals[i], this._vertices[j] - this._vertices[i]);
                        Box2DXDebug.Assert(num3 < -Settings.LinearSlop);
                    }
                }
            }
            for (int i = 1; i < this._vertexCount; i++)
            {
                float num4 = Vec2.Cross(this._normals[i - 1], this._normals[i]);
                num4 = Box2DX.Common.Math.Clamp(num4, -1f, 1f);
                float num5 = (float)System.Math.Asin((double)num4);
                Box2DXDebug.Assert(num5 > Settings.AngularSlop);
            }
            this._centroid = PolygonShape.ComputeCentroid(polygonDef.Vertices, polygonDef.VertexCount);
            PolygonShape.ComputeOBB(out this._obb, this._vertices, this._vertexCount);
            for (int i = 0; i < this._vertexCount; i++)
            {
                int  num  = (i - 1 >= 0) ? (i - 1) : (this._vertexCount - 1);
                int  num2 = i;
                Vec2 a2   = this._normals[num];
                Vec2 a3   = this._normals[num2];
                Vec2 b    = this._vertices[i] - this._centroid;
                Vec2 b2   = default(Vec2);
                b2.X = Vec2.Dot(a2, b) - Settings.ToiSlop;
                b2.Y = Vec2.Dot(a3, b) - Settings.ToiSlop;
                Box2DXDebug.Assert(b2.X >= 0f);
                Box2DXDebug.Assert(b2.Y >= 0f);
                Mat22 mat = default(Mat22);
                mat.Col1.X            = a2.X;
                mat.Col2.X            = a2.Y;
                mat.Col1.Y            = a3.X;
                mat.Col2.Y            = a3.Y;
                this._coreVertices[i] = mat.Solve(b2) + this._centroid;
            }
        }