/*
* 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
};
}
}
}