/* * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ using System; using System.ComponentModel; namespace Tizen.NUI.Physics2D.Chipmunk { /// /// Contains information about a contact point. and /// are the contact positions on the surface of each shape. is the /// penetration distance of the two, which is a negative value. This value is calculated as /// dot(point2 - point1), normal) and is ignored when you set the /// . /// [EditorBrowsable(EditorBrowsableState.Never)] public sealed class ContactPoint : IEquatable { #pragma warning disable IDE0032 private readonly Vect pointA; private readonly Vect pointB; private readonly double distance; #pragma warning restore IDE0032 /// /// Point A in the contact point. /// [EditorBrowsable(EditorBrowsableState.Never)] public Vect PointA => pointA; /// /// Point B in the contact point. /// [EditorBrowsable(EditorBrowsableState.Never)] public Vect PointB => pointB; /// /// The penetration distance of the two shapes (as a negative value). This value is /// calculated as dot(point2 - point1), normal) and is ignored when you set the /// . /// [EditorBrowsable(EditorBrowsableState.Never)] public double Distance => distance; private ContactPoint(Vect pointA, Vect pointB, double distance) { this.pointA = pointA; this.pointB = pointB; this.distance = distance; } /// /// Returns true if neither is null and the points are within /// distance of each other. /// [EditorBrowsable(EditorBrowsableState.Never)] public bool Equals(ContactPoint other) { if (ReferenceEquals(other, null)) { return false; } return other.pointA.Equals(pointA) && other.pointB.Equals(pointB) && Math.Abs(other.distance - distance) < float.Epsilon; } /// /// Check if this is equal to an object. /// [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object obj) { var other = obj as ContactPoint; if (other == null) { return false; } return Equals(other); } /// /// Get the hash set. /// [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { unchecked { var hashCode = -1285340573; hashCode = hashCode * -1521134295 + pointA.GetHashCode(); hashCode = hashCode * -1521134295 + pointB.GetHashCode(); hashCode = hashCode * -1521134295 + distance.GetHashCode(); return hashCode; } } /// /// Returns a string in the format of "a: {pointA}, b: {pointB}, distance: {distance}". /// [EditorBrowsable(EditorBrowsableState.Never)] public override string ToString() { return $"a: {pointA}, b: {pointB}, distance: {distance}"; } /// /// Returns true if both s are the same object or the dimensions /// are within distance of each other. /// [EditorBrowsable(EditorBrowsableState.Never)] public static bool operator ==(ContactPoint left, ContactPoint right) { if (ReferenceEquals(left, null)) { return ReferenceEquals(right, null); } return left.Equals(right); } /// /// Returns false if both s are the same object or the dimensions /// are within distance of each other. /// [EditorBrowsable(EditorBrowsableState.Never)] public static bool operator !=(ContactPoint left, ContactPoint right) { return !(left == right); } internal static ContactPoint Empty => new ContactPoint(Vect.Zero, Vect.Zero, 0.0); internal static ContactPoint FromCollidePoint(cpContactPoint contactPoint) { return new ContactPoint( contactPoint.pointA, contactPoint.pointB, contactPoint.distance); } internal cpContactPoint ToContactPoint() { return new cpContactPoint { pointA = pointA, pointB = pointB, distance = distance }; } } }