/// <summary> /// Draw method /// </summary> /// <param name="gameTime"></param> public override void Draw(TimeSpan gameTime) { if (this.behavior == null) { return; } foreach (var tuple in this.behavior.fixturePairs) { ICollider2D fixtureA = tuple.Item1; ICollider2D fixtureB = tuple.Item2; float density = fixtureA.Density; Vector2[] intersectionPoints; Vector2[] polygonPointsA = BuoyancyBehavior.GetPolygonPoints(fixtureA); Vector2[] polygonPointsB = BuoyancyBehavior.GetPolygonPoints(fixtureB); intersectionPoints = BuoyancyBehavior.GetIntersectedPolygon(polygonPointsA, polygonPointsB); if (intersectionPoints.Length > 0) { // find centroid float area = 0; Vector2 centroid = BuoyancyBehavior.ComputeCentroid(intersectionPoints, out area); this.RenderManager.LineBatch2D.DrawPoint(centroid, 10, Color.Blue, 0); //this.DrawPolygon(polygonPointsA, Color.Yellow); //this.DrawPolygon(polygonPointsB, Color.Purple); this.DrawPolygon(intersectionPoints, Color.Red); } } }
// MISSING callback to the different things (Enter, Stay, Exit - Trigger,Collision) public ColliderData(ICollider2D collider2D, bool isTrigger, int layerNumber, Transform2D transform) { Collider2D = collider2D; IsTrigger = isTrigger; //LayerMask = 1 << layerNumber; LayerNumber = layerNumber; GlobalAABB = Collider2D.CreateAABB(transform); }
/// <summary> /// Get Polygon points of a physic collider /// </summary> /// <param name="collider">physic collider</param> /// <returns>polygon points</returns> public static Vector2[] GetPolygonPoints(ICollider2D collider) { IPolygonColliderShape2D shape = (IPolygonColliderShape2D)collider.Shape; Vector2[] result = new Vector2[shape.Vertices.Length]; var transform = ((Collider2D)collider.UserData).Owner.FindComponent <Transform2D>(); for (int i = 0; i < shape.Vertices.Length; i++) { //result[i] = shape.Vertices[i]; Vector2 size = new Vector2(transform.Rectangle.Width, transform.Rectangle.Height); result[i] = Vector2.Transform(shape.Vertices[i] - (transform.Origin * size), transform.WorldTransform); //collider.RigidBody.GetWorldVector(shape.Vertices[i]); } return(result); }
/// <summary> /// Update method /// </summary> /// <param name="gameTime">game time</param> protected override void Update(TimeSpan gameTime) { foreach (var tuple in this.fixturePairs) { ICollider2D fixtureA = tuple.Item1; ICollider2D fixtureB = tuple.Item2; float density = fixtureA.Density; Vector2[] intersectionPoints; Vector2[] polygonPointsA = GetPolygonPoints(fixtureA); Vector2[] polygonPointsB = GetPolygonPoints(fixtureB); intersectionPoints = GetIntersectedPolygon(polygonPointsA, polygonPointsB); if (intersectionPoints.Length > 0) { // find centroid float area = 0; Vector2 centroid = ComputeCentroid(intersectionPoints, out area); area = Math.Abs(area) / this.AreaDivisor; Labels.Add("Area", area); // Apply buoyancy force float displacedMass = fixtureA.Density * area; Vector2 buoyancyForce = displacedMass * -this.gravity; fixtureB.RigidBody.ApplyForce(buoyancyForce, centroid); Labels.Add("buoyancyForce", buoyancyForce); // Apply complex drag //for (int i = 0; i < intersectionPoints.Length; i++) //{ // Vector2 v0 = intersectionPoints[i]; // Vector2 v1 = intersectionPoints[(i + 1) % intersectionPoints.Length]; // Vector2 midPoint = 0.5f * (v0 + v1); // //find relative velocity between object and fluid at edge midpoint // Vector2 velDir = fixtureB.RigidBody.GetLinearVelocityFromWorldPoint(midPoint) - fixtureA.RigidBody.GetLinearVelocityFromWorldPoint(midPoint); // float vel = velDir.Normalize(); // Vector2 edge = v1 - v0; // float edgeLength = edge.Normalize(); // Vector2 normal = b2Cross(-1, ref edge); // float dragDot = Vector2.Dot(normal, velDir); // if (dragDot < 0) // continue;//normal points backwards - this is not a leading edge // //apply drag // float dragMag = dragDot * this.DragMod * edgeLength * density * vel * vel; // dragMag = Math.Min(dragMag, this.MaxDrag); // Vector2 dragForce = dragMag * -velDir; // if (!float.IsNaN(dragForce.X) && !float.IsNaN(dragForce.Y)) // { // fixtureB.RigidBody.ApplyForce(dragForce, midPoint); // Labels.Add("dragForce", dragForce); // } // //apply lift // float liftDot = Vector2.Dot(edge, velDir); // float liftMag = dragDot * liftDot * this.LiftMod * edgeLength * density * vel * vel; // liftMag = Math.Min(liftMag, this.MaxLift); // Vector2 liftDir = b2Cross(1, ref velDir); // Vector2 liftForce = liftMag * liftDir; // if (!float.IsNaN(liftForce.X) && !float.IsNaN(liftForce.Y)) // { // fixtureB.RigidBody.ApplyForce(liftForce, midPoint); // Labels.Add("liftForce", liftForce); // } //} } } }
private void OnDrawGizmos() { if (Level.Instance == null) { return; } for (int apmCount = 0; apmCount < SuperPhysicsManager.Instance.PhysicsManagers.Count; ++apmCount) { Vector2Int offsetTiles = new Vector2Int( apmCount % SuperPhysicsManager.Instance.PhysicsManagers.Count, apmCount / SuperPhysicsManager.Instance.PhysicsManagers.Count ); Vector2 offset = offsetTiles * m_offset; int rbCount = -1; foreach (Rigidbody rb in SuperPhysicsManager.Instance.PhysicsManagers[apmCount].Rigidbodies) { ++rbCount; ICollider2D col = rb.ColliderData.Collider2D; Color color = Color.black; switch (m_objectColor) { case ObjectColor.Greyscale: { //float f = (1 / (rb.ID + 1) * 364.24f) + rb.ID * ((719.1532f + 35 * rb.ID) + 17.546f * rb.ID); float f = (1 / (rbCount + 1) * 364.24f) + rbCount * ((719.1532f + 35 * rbCount) + 17.546f * rbCount); f /= 32; f %= 1.0f; f = 0.5f + (f / 2); color = new Color(f, f, f, 1); } break; case ObjectColor.Layers: { switch (rb.ColliderData.LayerNumber) { case 0: float f = (1 / (rbCount + 1) * 364.24f) + rbCount * ((719.1532f + 35 * rbCount) + 17.546f * rbCount); f /= 32; f %= 1.0f; f = 0.5f + (f / 2); color = new Color(f, f, f, 1); break; case 1: color = Color.green; break; case 2: color = Color.magenta; break; case 3: color = Color.blue; break; case 4: color = Color.cyan; break; case 5: color = (Color.magenta + Color.black) / 2; break; case 6: color = (Color.yellow + Color.red) / 2; break; } break; } case ObjectColor.Static: { //TODO break; } case ObjectColor.Trigger: { if (rb.ColliderData.IsTrigger) { color = (Color.blue + Color.white) / 2; } else { color = (Color.green + Color.white) / 2; } break; } } Gizmos.color = color; switch (col) { case AABB aabb: { Gizmos.DrawCube(rb.GameObject.Transform.Position.Vector2 + offset, rb.GameObject.Transform.Scale * new Vector3(aabb.Right.Float - aabb.Left.Float, aabb.Top.Float - aabb.Bottom.Float, 1)); break; } case Circle circle: { Gizmos.DrawSphere(new Vector3(0, 0, 100) + (Vector3)(rb.GameObject.Transform.Position.Vector2 + offset), rb.GameObject.Transform.Scale * circle.Radius.Float); break; } } } foreach (ulong id in (SuperPhysicsManager.Instance.PhysicsManagers[apmCount]).CheckStates.Keys) { CheckState cs = (SuperPhysicsManager.Instance.PhysicsManagers[apmCount]).CheckStates[id]; uint id1 = (uint)(id >> 32); uint id2 = (uint)id; Color color = Color.blue; switch (cs) { case CheckState.BroadCheck: if (!m_showBroad) { continue; } color = Color.red; break; case CheckState.NarrowCheck: if (!m_showNear) { continue; } color = Color.yellow; break; case CheckState.Trigger: if (!m_showTrigger) { continue; } color = Color.blue; break; case CheckState.Collision: if (!m_showCollision) { continue; } color = Color.green; break; } Gizmos.color = color; Gizmos.DrawLine(Rigidbody.GetRigidbody(id1).GameObject.Transform.Position.Vector2 + offset, Rigidbody.GetRigidbody(id2).GameObject.Transform.Position.Vector2 + offset); } if (m_drawPMGizmos) { SuperPhysicsManager.Instance.PhysicsManagers[apmCount].Draw(offset); } } }
/// <summary> /// Get Polygon points of a physic collider /// </summary> /// <param name="collider">physic collider</param> /// <returns>polygon points</returns> public static Vector2[] GetPolygonPoints(ICollider2D collider) { IPolygonColliderShape2D shape = (IPolygonColliderShape2D)collider.Shape; Vector2[] result = new Vector2[shape.Vertices.Length]; var transform = ((Collider2D)collider.UserData).Owner.FindComponent<Transform2D>(); for (int i = 0; i < shape.Vertices.Length; i++) { //result[i] = shape.Vertices[i]; Vector2 size = new Vector2(transform.Rectangle.Width, transform.Rectangle.Height); result[i] = Vector2.Transform(shape.Vertices[i] - (transform.Origin * size), transform.WorldTransform); //collider.RigidBody.GetWorldVector(shape.Vertices[i]); } return result; }