public void SetAsBox(float hx, float hy, b2Vec2 center, float angle) { m_vertexCount = 4; m_vertices[0].Set(-hx, -hy); m_vertices[1].Set(hx, -hy); m_vertices[2].Set(hx, hy); m_vertices[3].Set(-hx, hy); m_normals[0].Set(0.0f, -1.0f); m_normals[1].Set(1.0f, 0.0f); m_normals[2].Set(0.0f, 1.0f); m_normals[3].Set(-1.0f, 0.0f); m_centroid = center; b2Transform xf = b2Transform.Create(); xf.p = center; xf.q.Set(angle); // Transform vertices and normals. for (int i = 0; i < m_vertexCount; ++i) { m_vertices[i] = b2Math.b2Mul(xf, m_vertices[i]); m_normals[i] = b2Math.b2Mul(xf.q, m_normals[i]); } }
public void DrawFixture(b2Fixture fixture) { b2Color color = new b2Color(0.95f, 0.95f, 0.6f); b2Transform xf = fixture.Body.Transform; switch (fixture.ShapeType) { case b2ShapeType.e_circle: { b2CircleShape circle = (b2CircleShape)fixture.Shape; b2Vec2 center = b2Math.b2Mul(xf, circle.Position); float radius = circle.Radius; m_debugDraw.DrawCircle(center, radius, color); } break; case b2ShapeType.e_polygon: { b2PolygonShape poly = (b2PolygonShape)fixture.Shape; int vertexCount = poly.VertexCount; Debug.Assert(vertexCount <= b2Settings.b2_maxPolygonVertices); b2Vec2[] vertices = new b2Vec2[b2Settings.b2_maxPolygonVertices]; for (int i = 0; i < vertexCount; ++i) { vertices[i] = b2Math.b2Mul(xf, poly.Vertices[i]); } m_debugDraw.DrawPolygon(vertices, vertexCount, color); } break; } }
public ShapeCastInputNative() { transform = Physics2DNative.GetNewTransform(Vector2.Zero, 0f); _EndTransform = Physics2DNative.GetNewTransform(Vector2.Zero, 0f); aabb = new b2AABB(); _End = new b2AABB(); }
/** * @inheritDoc */ public override float ComputeSubmergedArea( b2Vec2 normal, float offset, b2Transform xf, b2Vec2 c) { b2Vec2 p = b2Math.MulX(xf, m_p); float l = -(b2Math.Dot(normal, p) - offset); if (l < -m_radius + float.MinValue) { //Completely dry return(0.0f); } if (l > m_radius) { //Completely wet c.SetV(p); return(Mathf.PI * m_radius * m_radius); } //Magic float r2 = m_radius * m_radius; float l2 = l * l; float area = r2 * (Mathf.Asin(l / m_radius) + Mathf.PI / 2.0f) + l * Mathf.Sqrt(r2 - l2); float com = -2.0f / 3.0f * Mathf.Pow(r2 - l2, 1.5f) / area; c.x = p.x + normal.x * com; c.y = p.y + normal.y * com; return(area); }
/// Compute the collision manifold between an edge and a circle. public static void b2CollideEdgeAndPolygon(ref b2Manifold manifold, b2EdgeShape edgeA, ref b2Transform xfA, b2PolygonShape polygonB, ref b2Transform xfB) { b2EPCollider b = new b2EPCollider(); b.Collide(ref manifold, edgeA, ref xfA, polygonB, ref xfB); }
/** * @inheritDoc */ public override void ComputeAABB(b2AABB aabb, b2Transform xf) { //var lower:b2Vec2 = b2Math.MulX(xf, m_vertices[0]); b2Mat22 tMat = xf.R; b2Vec2 tVec = m_vertices[0]; float lowerX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); float lowerY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); float upperX = lowerX; float upperY = lowerY; for (int i = 1; i < m_vertexCount; ++i) { tVec = m_vertices[i]; float vX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); float vY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); lowerX = lowerX < vX ? lowerX : vX; lowerY = lowerY < vY ? lowerY : vY; upperX = upperX > vX ? upperX : vX; upperY = upperY > vY ? upperY : vY; } aabb.lowerBound.x = lowerX - m_radius; aabb.lowerBound.y = lowerY - m_radius; aabb.upperBound.x = upperX + m_radius; aabb.upperBound.y = upperY + m_radius; }
public void SetAsBox(float hx, float hy, b2Vec2 center, float angle) { m_vertexCount = 4; Vertices[0].Set(-hx, -hy); Vertices[1].Set(hx, -hy); Vertices[2].Set(hx, hy); Vertices[3].Set(-hx, hy); Normals[0].Set(0.0f, -1.0f); Normals[1].Set(1.0f, 0.0f); Normals[2].Set(0.0f, 1.0f); Normals[3].Set(-1.0f, 0.0f); Centroid = center; b2Transform xf = b2Transform.Identity; xf.p = center; xf.q.Set(angle); // Transform vertices and normals. for (int i = 0; i < m_vertexCount; ++i) { Vertices[i] = b2Math.b2Mul(ref xf, ref Vertices[i]); Normals[i] = b2Math.b2Mul(ref xf.q, ref Normals[i]); } }
/** * @inheritDoc */ public override bool TestPoint(b2Transform xf, b2Vec2 p) { b2Vec2 tVec; //b2Vec2 pLocal = b2MulT(xf.R, p - xf.position); b2Mat22 tMat = xf.R; float tX = p.x - xf.position.x; float tY = p.y - xf.position.y; float pLocalX = (tX * tMat.col1.x + tY * tMat.col1.y); float pLocalY = (tX * tMat.col2.x + tY * tMat.col2.y); for (int i = 0; i < m_vertexCount; ++i) { //float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]); tVec = m_vertices[i]; tX = pLocalX - tVec.x; tY = pLocalY - tVec.y; tVec = m_normals[i]; float dot = (tVec.x * tX + tVec.y * tY); if (dot > 0.0f) { return(false); } } return(true); }
/// Implement b2Shape. public override bool TestPoint(b2Transform transform, b2Vec2 p) { b2Vec2 center = transform.p + Utils.b2Mul(transform.q, m_p); b2Vec2 d = p - center; return(Utils.b2Dot(d, d) <= m_radius * m_radius); }
/// Compute the collision manifold between two circles. public static void b2CollideCircles(ref b2Manifold manifold, b2CircleShape circleA, ref b2Transform xfA, b2CircleShape circleB, ref b2Transform xfB) { manifold.pointCount = 0; b2Vec2 pA = b2Math.b2Mul(xfA, circleA.Position); b2Vec2 pB = b2Math.b2Mul(xfB, circleB.Position); b2Vec2 d = pB - pA; float distSqr = b2Math.b2Dot(d, d); float rA = circleA.Radius, rB = circleB.Radius; float radius = rA + rB; if (distSqr > radius * radius) { return; } manifold.type = b2ManifoldType.e_circles; manifold.localPoint = circleA.Position; manifold.localNormal.SetZero(); manifold.pointCount = 1; manifold.points[0].localPoint = circleB.Position; manifold.points[0].id = b2ContactFeature.Zero; }
private void testQueryShape_poly() { Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); b2WorldQueryCallback cb = delegate(b2Fixture fixture) { b2Body body = fixture.GetBody(); body.SetAwake(true); return(true); }; b2Vec2[] vertices = new b2Vec2[4]; vertices [0] = new b2Vec2(-100.0f / ptm_ratio, 0.0f / ptm_ratio); vertices [1] = new b2Vec2(0.0f / ptm_ratio, 100.0f / ptm_ratio); vertices [2] = new b2Vec2(100.0f / ptm_ratio, 0.0f / ptm_ratio); vertices [3] = new b2Vec2(0.0f / ptm_ratio, -200.0f / ptm_ratio); b2PolygonShape shape = b2PolygonShape.AsArray(vertices, vertices.Length); b2Transform transform = new b2Transform(new b2Vec2(mousePos.x, mousePos.y), b2Mat22.FromAngle(0)); _world.QueryShape(cb, shape, transform); for (int i = 0; i < vertices.Length; i++) { vertices[i].x += mousePos.x; vertices[i].y += mousePos.y; } b2Color color = new b2Color(1.0f, 0.0f, 0.0f); _debugDraw.DrawPolygon(vertices, vertices.Length, color); }
/** * @inheritDoc */ public override void ComputeAABB(b2AABB aabb, b2Transform transform) { b2Mat22 tMat = transform.R; //b2Vec2 v1 = b2Mul(transform, m_v1); float v1X = transform.position.x + (tMat.col1.x * m_v1.x + tMat.col2.x * m_v1.y); float v1Y = transform.position.y + (tMat.col1.y * m_v1.x + tMat.col2.y * m_v1.y); //b2Vec2 v2 = b2Mul(transform, m_v2); float v2X = transform.position.x + (tMat.col1.x * m_v2.x + tMat.col2.x * m_v2.y); float v2Y = transform.position.y + (tMat.col1.y * m_v2.x + tMat.col2.y * m_v2.y); if (v1X < v2X) { aabb.lowerBound.x = v1X; aabb.upperBound.x = v2X; } else { aabb.lowerBound.x = v2X; aabb.upperBound.x = v1X; } if (v1Y < v2Y) { aabb.lowerBound.y = v1Y; aabb.upperBound.y = v2Y; } else { aabb.lowerBound.y = v2Y; aabb.upperBound.y = v1Y; } }
public virtual void Synchronize(b2BroadPhase broadPhase, ref b2Transform transform1, ref b2Transform transform2) { if (m_proxyCount == 0) { return; } for (int i = 0, count = m_proxyCount; i < count; ++i) { b2FixtureProxy proxy = m_proxies[i]; // Compute an AABB that covers the swept shape (may miss some rotation effect). b2AABB aabb1, aabb2; Shape.ComputeAABB(out aabb1, ref transform1, proxy.childIndex); Shape.ComputeAABB(out aabb2, ref transform2, proxy.childIndex); proxy.aabb.Combine(ref aabb1, ref aabb2); b2Vec2 displacement; displacement.x = transform2.p.x - transform1.p.x; displacement.y = transform2.p.y - transform1.p.y; broadPhase.MoveProxy(proxy.proxyId, ref proxy.aabb, ref displacement); } }
public virtual bool TestPoint(b2Transform transform, b2Vec2 p) { b2Vec2 center = transform.p + b2Math.b2Mul(transform.q, m_p); b2Vec2 d = p - center; return(b2Math.b2Dot(d, d) <= m_radius * m_radius); }
public static Vector2 b2Mul(b2Transform T, Vector2 v) { float x = (T.q.c * v.x - T.q.s * v.y) + T.p.x; float y = (T.q.s * v.x + T.q.c * v.y) + T.p.y; return(new Vector2(x, y)); }
public override void ComputeAABB(out b2AABB output, ref b2Transform xf, int childIndex) { b2Vec2 v1; v1.x = (xf.q.c * Vertex1.x - xf.q.s * Vertex1.y) + xf.p.x; v1.y = (xf.q.s * Vertex1.x + xf.q.c * Vertex1.y) + xf.p.y; b2Vec2 v2; v2.x = (xf.q.c * Vertex2.x - xf.q.s * Vertex2.y) + xf.p.x; v2.y = (xf.q.s * Vertex2.x + xf.q.c * Vertex2.y) + xf.p.y; b2Vec2 lower; lower.x = v1.x < v2.x ? v1.x : v2.x; lower.y = v1.y < v2.y ? v1.y : v2.y; //b2Math.b2Min(v1, v2); b2Vec2 upper; upper.x = v1.x > v2.x ? v1.x : v2.x; upper.y = v1.y > v2.y ? v1.y : v2.y; // = b2Math.b2Max(v1, v2); output.LowerBound = lower; output.UpperBound = upper; output.Fatten(Radius); }
/// Implement b2Shape. // Collision Detection in Interactive 3D Environments by Gino van den Bergen // From Section 3.1.2 // x = s + a * r // norm(x) = radius public override bool RayCast(b2RayCastOutput output, b2RayCastInput input, b2Transform transform, int childIndex) { b2Vec2 position = transform.p + Utils.b2Mul(transform.q, m_p); b2Vec2 s = input.p1 - position; float b = Utils.b2Dot(s, s) - m_radius * m_radius; // Solve quadratic equation. b2Vec2 r = input.p2 - input.p1; float c = Utils.b2Dot(s, r); float rr = Utils.b2Dot(r, r); float sigma = c * c - rr * b; // Check for negative discriminant and short segment. if (sigma < 0.0f || rr < float.Epsilon) { return(false); } // Find the point of intersection of the line with the circle. float a = -(c + (float)Math.Sqrt(sigma)); // Is the intersection point on the segment? if (0.0f <= a && a <= input.maxFraction * rr) { a /= rr; output.fraction = a; output.normal = s + a * r; output.normal.Normalize(); return(true); } return(false); }
public static float b2EdgeSeparation(b2PolygonShape poly1, b2Transform xf1, int edge1, b2PolygonShape poly2, b2Transform xf2) { b2Vec2[] vertices1 = poly1.Vertices; b2Vec2[] normals1 = poly1.Normals; int count2 = poly2.VertexCount; b2Vec2[] vertices2 = poly2.Vertices; // Convert normal from poly1's frame into poly2's frame. b2Vec2 normal1World = b2Math.b2Mul(xf1.q, normals1[edge1]); b2Vec2 normal1 = b2Math.b2MulT(xf2.q, normal1World); // Find support vertex on poly2 for -normal. int index = 0; float minDot = b2Settings.b2_maxFloat; for (int i = 0; i < count2; ++i) { float dot = b2Math.b2Dot(ref vertices2[i], ref normal1); if (dot < minDot) { minDot = dot; index = i; } } b2Vec2 v1 = b2Math.b2Mul(xf1, vertices1[edge1]); b2Vec2 v2 = b2Math.b2Mul(xf2, vertices2[index]); float separation = b2Math.b2Dot(v2 - v1, normal1World); return separation; }
public void SetAsOrientedBox(float hx, float hy, b2Vec2 center = null, float angle = 0.0f) { m_vertexCount = 4; Reserve(4); m_vertices[0].Set(-hx, -hy); m_vertices[1].Set(hx, -hy); m_vertices[2].Set(hx, hy); m_vertices[3].Set(-hx, hy); m_normals[0].Set(0.0f, -1.0f); m_normals[1].Set(1.0f, 0.0f); m_normals[2].Set(0.0f, 1.0f); m_normals[3].Set(-1.0f, 0.0f); m_centroid = center; b2Transform xf = new b2Transform(); xf.position = center; xf.R.Set(angle); // Transform vertices and normals. for (int i = 0; i < m_vertexCount; ++i) { m_vertices[i] = b2Math.MulX(xf, m_vertices[i]); m_normals[i] = b2Math.MulMV(xf.R, m_normals[i]); } }
/// @see b2Shape::ComputeAABB public override void ComputeAABB(ref b2AABB aabb, b2Transform transform, int childIndex) { b2Vec2 p = transform.p + Utils.b2Mul(transform.q, m_p); aabb.lowerBound.Set(p.x - m_radius, p.y - m_radius); aabb.upperBound.Set(p.x + m_radius, p.y + m_radius); }
public override bool TestPoint(b2Transform transform, b2Vec2 p) { b2Vec2 center = transform.p + b2Math.b2Mul(transform.q, m_p); b2Vec2 d = p - center; return(d.LengthSquared <= m_radius * m_radius); }
/// Compute the collision manifold between two circles. public static void b2CollideCircles(ref b2Manifold manifold, b2CircleShape circleA, ref b2Transform xfA, b2CircleShape circleB, ref b2Transform xfB) { manifold.pointCount = 0; b2Vec2 pA = b2Math.b2Mul(xfA, circleA.Position); b2Vec2 pB = b2Math.b2Mul(xfB, circleB.Position); b2Vec2 d;// = pB - pA; d.x = pB.x - pA.x; d.y = pB.y - pA.y; float distSqr = d.LengthSquared; float rA = circleA.Radius, rB = circleB.Radius; float radius = rA + rB; if (distSqr > radius * radius) { return; } manifold.type = b2ManifoldType.e_circles; manifold.localPoint = circleA.Position; manifold.localNormal.SetZero(); manifold.pointCount = 1; manifold.points[0].localPoint = circleB.Position; manifold.points[0].id.key = 0; }
/// Build vertices to represent an oriented box. /// @param hx the half-width. /// @param hy the half-height. /// @param center the center of the box in local coordinates. /// @param angle the rotation of the box in local coordinates. public b2PolygonShape SetAsBox(float hx, float hy, b2Vec2 center, float angle) { m_count = 4; m_vertices[0].Set(-hx, -hy); m_vertices[1].Set(hx, -hy); m_vertices[2].Set(hx, hy); m_vertices[3].Set(-hx, hy); m_normals[0].Set(0.0f, -1.0f); m_normals[1].Set(1.0f, 0.0f); m_normals[2].Set(0.0f, 1.0f); m_normals[3].Set(-1.0f, 0.0f); m_centroid = center; b2Transform xf = new b2Transform(); xf.p = center; xf.q.Set(angle); // Transform vertices and normals. for (int i = 0; i < m_count; ++i) { m_vertices[i] = Utils.b2Mul(xf, m_vertices[i]); m_normals[i] = Utils.b2Mul(xf.q, m_normals[i]); } return(this); }
/** * Get the first vertex and apply the supplied transform. */ public b2Vec2 GetFirstVertex(b2Transform xf) { //return b2Mul(xf, m_coreV1); b2Mat22 tMat = xf.R; return(new b2Vec2(xf.position.x + (tMat.col1.x * m_coreV1.x + tMat.col2.x * m_coreV1.y), xf.position.y + (tMat.col1.y * m_coreV1.x + tMat.col2.y * m_coreV1.y))); }
public override void ComputeAABB(b2AABB aabb, b2Transform transform, int childIndex) { Box2DPINVOKE.b2CircleShape_ComputeAABB(swigCPtr, b2AABB.getCPtr(aabb), b2Transform.getCPtr(transform), childIndex); if (Box2DPINVOKE.SWIGPendingException.Pending) { throw Box2DPINVOKE.SWIGPendingException.Retrieve(); } }
public virtual void ComputeAABB(b2AABB aabb, b2Transform xf, int childIndex) { Box2DPINVOKE.b2Shape_ComputeAABB(swigCPtr, b2AABB.getCPtr(aabb), b2Transform.getCPtr(xf), childIndex); if (Box2DPINVOKE.SWIGPendingException.Pending) { throw Box2DPINVOKE.SWIGPendingException.Retrieve(); } }
public override void Evaluate(b2Manifold manifold, b2Transform xfA, b2Transform xfB) { b2ChainShape chain = (b2ChainShape)m_fixtureA.GetShape(); b2EdgeShape edge = new b2EdgeShape(); chain.GetChildEdge(edge, m_indexA); Utils.b2CollideEdgeAndPolygon(manifold, edge, xfA, (b2PolygonShape)m_fixtureB.GetShape(), xfB); }
public virtual void DrawTransform(b2Transform xf) { Box2DPINVOKE.b2Draw_DrawTransform(swigCPtr, b2Transform.getCPtr(xf)); if (Box2DPINVOKE.SWIGPendingException.Pending) { throw Box2DPINVOKE.SWIGPendingException.Retrieve(); } }
/** * This supports body activation/deactivation. */ public void CreateProxy(IBroadPhase broadPhase, b2Transform xf) { //b2Assert(m_proxyId == b2BroadPhase::e_nullProxy); // Create proxy in the broad-phase. m_shape.ComputeAABB(m_aabb, xf); m_proxy = broadPhase.CreateProxy(m_aabb, this); }
public void Initialize(b2Manifold manifold, b2Transform xfA, float radiusA, b2Transform xfB, float radiusB) { Box2DPINVOKE.b2WorldManifold_Initialize(swigCPtr, b2Manifold.getCPtr(manifold), b2Transform.getCPtr(xfA), radiusA, b2Transform.getCPtr(xfB), radiusB); if (Box2DPINVOKE.SWIGPendingException.Pending) { throw Box2DPINVOKE.SWIGPendingException.Retrieve(); } }
public static Vector2 b2Mul(b2Transform T, Vector2 v) { float x = (T.q.c * v.x - T.q.s * v.y) + T.p.x; float y = (T.q.s * v.x + T.q.c * v.y) + T.p.y; return new Vector2(x, y); }
public override void DrawTransform(b2Transform xf) { b2Vec2 p1 = xf.position, p2; const float k_axisScale = 0.4f; Gl.glBegin(Gl.GL_LINES); Gl.glColor3f(1.0f, 0.0f, 0.0f); Gl.glVertex2f(p1.x, p1.y); p2 = p1 + k_axisScale * xf.R.col1; Gl.glVertex2f(p2.x, p2.y); Gl.glColor3f(0.0f, 1.0f, 0.0f); Gl.glVertex2f(p1.x, p1.y); p2 = p1 + k_axisScale * xf.R.col2; Gl.glVertex2f(p2.x, p2.y); Gl.glEnd(); }
// Use this for initialization protected override void Init() { API.SetGravity(world,Vector2.zero); var ground = API.CreateBody(world, new Vector2(0,20), 0, BodyType.STATIC_BODY ); ShapeDef sp = new ShapeDef(0); sp.restitution = 0.4f; API.AddEdgeShape(ground, new Vector2(-20,-20), new Vector2(-20,20), sp); API.AddEdgeShape(ground, new Vector2(20,-20), new Vector2(20,20), sp); API.AddEdgeShape(ground, new Vector2(-20,20), new Vector2(20,20), sp); API.AddEdgeShape(ground, new Vector2(-20,-20), new Vector2(20,-20), sp); BodyDef bd = new BodyDef(BodyType.DYNAMIC_BODY); bd.allowSleep = false; bd.angle = 3.14159265359f; bd.angularDamping = 5.0f; bd.linearDamping = 0.1f; bd.position = new Vector2(0,2); m_body = API.CreateBody(world,bd); sp.restitution = 0.0f; sp.density = 4.0f; b2Transform xf1 = new b2Transform(); xf1.q = new b2Rot(0.3524f * Mathf.PI); xf1.p = xf1.q.GetXAxis(); Vector2[] vertices = new Vector2[3]; vertices[0] = b2Math.b2Mul(xf1, new Vector2(-1.0f, 0.0f)); vertices[1] = b2Math.b2Mul(xf1, new Vector2(1.0f, 0.0f)); vertices[2] = b2Math.b2Mul(xf1, new Vector2(0.0f, 0.5f)); API.AddPolygonShape(m_body, vertices, vertices.Length, sp); sp.density = 2.0f; xf1.q = new b2Rot(-0.3524f * Mathf.PI); xf1.p = -xf1.q.GetXAxis(); vertices[0] = b2Math.b2Mul(xf1, new Vector2(-1.0f, 0.0f)); vertices[1] = b2Math.b2Mul(xf1, new Vector2(1.0f, 0.0f)); vertices[2] = b2Math.b2Mul(xf1, new Vector2(0.0f, 0.5f)); API.AddPolygonShape(m_body, vertices, vertices.Length, sp); sp.density = 1.0f; sp.friction = 0.3f; float gravity = 10; FrictionJointDef jd = new FrictionJointDef(); for(int i=0; i<10; ++i) { var b = API.CreateBody(world, new Vector2(0,5.0f+1.54f*i), 0, BodyType.DYNAMIC_BODY ); API.AddBoxShape(b, 0.5f, 0.5f, Vector2.zero, 0, sp); float I = API.GetInertia(b); float mass = API.GetMass(b); float radius = Mathf.Sqrt(2.0f*I/mass); jd.bodyA = ground; jd.bodyB = b; jd.collideConnected = true; jd.maxForce = mass*gravity; jd.maxTorque = mass*radius*gravity; API.CreateFrictionJoint(world,jd); } }