internal static Shape Create(ShapeDef def) { Shape result; switch (def.Type) { case ShapeType.CircleShape: { result = new CircleShape(def); break; } case ShapeType.PolygonShape: { result = new PolygonShape(def); break; } default: { Box2DXDebug.Assert(false); result = null; break; } } return(result); }
internal CircleShape(ShapeDef def) : base(def) { Box2DXDebug.Assert(def.Type == ShapeType.CircleShape); CircleDef circleDef = (CircleDef)def; this._type = ShapeType.CircleShape; this._localPosition = circleDef.LocalPosition; this._radius = circleDef.Radius; }
protected Shape(ShapeDef def) { this._userData = def.UserData; this._friction = def.Friction; this._restitution = def.Restitution; this._density = def.Density; this._body = null; this._sweepRadius = 0f; this._next = null; this._proxyId = PairManager.NullProxy; this._filter = def.Filter; this._isSensor = def.IsSensor; }
protected Shape(ShapeDef def) { _userData = def.UserData; _friction = def.Friction; _restitution = def.Restitution; _density = def.Density; _body = null; _sweepRadius = 0.0f; _next = null; _proxyId = PairManager.NullProxy; _filter = def.Filter; _isSensor = def.IsSensor; }
internal static Shape Create(ShapeDef def) { switch (def.Type) { case ShapeType.CircleShape: { return(new CircleShape(def)); } case ShapeType.PolygonShape: { return(new PolygonShape(def)); } default: Box2DXDebug.Assert(false); return(null); } }
internal PolygonShape(ShapeDef def) : base(def) { Box2DXDebug.Assert(def.Type == ShapeType.PolygonShape); _type = ShapeType.PolygonShape; PolygonDef poly = (PolygonDef)def; // Get the vertices transformed into the body frame. _vertexCount = poly.VertexCount; Box2DXDebug.Assert(3 <= _vertexCount && _vertexCount <= Settings.MaxPolygonVertices); // Copy vertices. for (int i = 0; i < _vertexCount; ++i) { _vertices[i] = poly.Vertices[i]; } // Compute normals. Ensure the edges have non-zero length. for (int i = 0; i < _vertexCount; ++i) { int i1 = i; int i2 = i + 1 < _vertexCount ? i + 1 : 0; Vec2 edge = _vertices[i2] - _vertices[i1]; Box2DXDebug.Assert(edge.LengthSquared() > Common.Settings.FLT_EPSILON * Common.Settings.FLT_EPSILON); _normals[i] = Vec2.Cross(edge, 1.0f); _normals[i].Normalize(); } #if DEBUG // Ensure the polygon is convex. for (int i = 0; i < _vertexCount; ++i) { for (int j = 0; j < _vertexCount; ++j) { // Don't check vertices on the current edge. if (j == i || j == (i + 1) % _vertexCount) { continue; } // Your polygon is non-convex (it has an indentation). // Or your polygon is too skinny. float s = Vec2.Dot(_normals[i], _vertices[j] - _vertices[i]); Box2DXDebug.Assert(s < -Settings.LinearSlop); } } // Ensure the polygon is counter-clockwise. for (int i = 1; i < _vertexCount; ++i) { float cross = Vec2.Cross(_normals[i - 1], _normals[i]); // Keep asinf happy. cross = Common.Math.Clamp(cross, -1.0f, 1.0f); // You have consecutive edges that are almost parallel on your polygon. float angle = (float)System.Math.Asin(cross); Box2DXDebug.Assert(angle > Settings.AngularSlop); } #endif // Compute the polygon centroid. _centroid = ComputeCentroid(poly.Vertices, poly.VertexCount); // Compute the oriented bounding box. ComputeOBB(out _obb, _vertices, _vertexCount); // Create core polygon shape by shifting edges inward. // Also compute the min/max radius for CCD. for (int i = 0; i < _vertexCount; ++i) { int i1 = i - 1 >= 0 ? i - 1 : _vertexCount - 1; int i2 = i; Vec2 n1 = _normals[i1]; Vec2 n2 = _normals[i2]; Vec2 v = _vertices[i] - _centroid; ; Vec2 d = new Vec2(); d.X = Vec2.Dot(n1, v) - Settings.ToiSlop; d.Y = Vec2.Dot(n2, v) - Settings.ToiSlop; // Shifting the edge inward by b2_toiSlop should // not cause the plane to pass the centroid. // Your shape has a radius/extent less than b2_toiSlop. Box2DXDebug.Assert(d.X >= 0.0f); Box2DXDebug.Assert(d.Y >= 0.0f); Mat22 A = new Mat22(); A.Col1.X = n1.X; A.Col2.X = n1.Y; A.Col1.Y = n2.X; A.Col2.Y = n2.Y; _coreVertices[i] = A.Solve(d) + _centroid; } }
internal static Shape Create(ShapeDef def) { Shape result; switch (def.Type) { case ShapeType.CircleShape: { result = new CircleShape(def); break; } case ShapeType.PolygonShape: { result = new PolygonShape(def); break; } default: { Box2DXDebug.Assert(false); result = null; break; } } return result; }
internal PolygonShape(ShapeDef def) : base(def) { Box2DXDebug.Assert(def.Type == ShapeType.PolygonShape); _type = ShapeType.PolygonShape; PolygonDef poly = (PolygonDef)def; // Get the vertices transformed into the body frame. _vertexCount = poly.VertexCount; Box2DXDebug.Assert(3 <= _vertexCount && _vertexCount <= Settings.MaxPolygonVertices); // Copy vertices. for (int i = 0; i < _vertexCount; ++i) { _vertices[i] = poly.Vertices[i]; } // Compute normals. Ensure the edges have non-zero length. for (int i = 0; i < _vertexCount; ++i) { int i1 = i; int i2 = i + 1 < _vertexCount ? i + 1 : 0; Vec2 edge = _vertices[i2] - _vertices[i1]; Box2DXDebug.Assert(edge.LengthSquared() > Common.Settings.FLT_EPSILON * Common.Settings.FLT_EPSILON); _normals[i] = Vec2.Cross(edge, 1.0f); _normals[i].Normalize(); } #if DEBUG // Ensure the polygon is convex. for (int i = 0; i < _vertexCount; ++i) { for (int j = 0; j < _vertexCount; ++j) { // Don't check vertices on the current edge. if (j == i || j == (i + 1) % _vertexCount) { continue; } // Your polygon is non-convex (it has an indentation). // Or your polygon is too skinny. float s = Vec2.Dot(_normals[i], _vertices[j] - _vertices[i]); Box2DXDebug.Assert(s < -Settings.LinearSlop); } } // Ensure the polygon is counter-clockwise. for (int i = 1; i < _vertexCount; ++i) { float cross = Vec2.Cross(_normals[i - 1], _normals[i]); // Keep asinf happy. cross = Common.Math.Clamp(cross, -1.0f, 1.0f); // You have consecutive edges that are almost parallel on your polygon. float angle = (float)System.Math.Asin(cross); Box2DXDebug.Assert(angle > Settings.AngularSlop); } #endif // Compute the polygon centroid. _centroid = ComputeCentroid(poly.Vertices, poly.VertexCount); // Compute the oriented bounding box. ComputeOBB(out _obb, _vertices, _vertexCount); // Create core polygon shape by shifting edges inward. // Also compute the min/max radius for CCD. for (int i = 0; i < _vertexCount; ++i) { int i1 = i - 1 >= 0 ? i - 1 : _vertexCount - 1; int i2 = i; Vec2 n1 = _normals[i1]; Vec2 n2 = _normals[i2]; Vec2 v = _vertices[i] - _centroid;; Vec2 d = new Vec2(); d.X = Vec2.Dot(n1, v) - Settings.ToiSlop; d.Y = Vec2.Dot(n2, v) - Settings.ToiSlop; // Shifting the edge inward by b2_toiSlop should // not cause the plane to pass the centroid. // Your shape has a radius/extent less than b2_toiSlop. Box2DXDebug.Assert(d.X >= 0.0f); Box2DXDebug.Assert(d.Y >= 0.0f); Mat22 A = new Mat22(); A.Col1.X = n1.X; A.Col2.X = n1.Y; A.Col1.Y = n2.X; A.Col2.Y = n2.Y; _coreVertices[i] = A.Solve(d) + _centroid; } }
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; } }
internal static Shape Create(ShapeDef def) { switch (def.Type) { case ShapeType.CircleShape: { return new CircleShape(def); } case ShapeType.PolygonShape: { return new PolygonShape(def); } default: Box2DXDebug.Assert(false); return null; } }
/// <summary> /// Creates a shape and attach it to this body. /// @warning This function is locked during callbacks. /// </summary> /// <param name="shapeDef">The shape definition.</param> /// <returns></returns> public Shape CreateShape(ShapeDef shapeDef) { Box2DXDebug.Assert(_world._lock == false); if (_world._lock == true) { return null; } Shape s = Shape.Create(shapeDef); s._next = _shapeList; _shapeList = s; ++_shapeCount; s._body = this; // Add the shape to the world's broad-phase. s.CreateProxy(_world._broadPhase, _xf); // Compute the sweep radius for CCD. s.UpdateSweepRadius(_sweep.LocalCenter); return s; }
public Shape CreateShape(ShapeDef shapeDef) { Box2DXDebug.Assert(!this._world._lock); Shape result; if (this._world._lock) { result = null; } else { Shape shape = Shape.Create(shapeDef); shape._next = this._shapeList; this._shapeList = shape; this._shapeCount++; shape._body = this; shape.CreateProxy(this._world._broadPhase, this._xf); shape.UpdateSweepRadius(this._sweep.LocalCenter); result = shape; } return result; }