d1233d3cefbea552f2d2e2c40b1e7465ab5092ea
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Physics2D / src / public / chipmunk / ContactPoint.cs
1 /*
2  * Copyright (c) 2023 Codefoco (codefoco@codefoco.com)
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  * 
11  * The above copyright notice and this permission notice shall be included in all
12  * copies or substantial portions of the Software.
13  * 
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22
23 using System;
24 using System.ComponentModel;
25
26 namespace Tizen.NUI.Physics2D.Chipmunk
27 {
28     /// <summary>
29     ///  Contains information about a contact point. <see cref="PointA"/> and <see cref="PointB"/>
30     ///  are the contact positions on the surface of each shape. <see cref="Distance"/> is the
31     ///  penetration distance of the two, which is a negative value. This value is calculated as
32     ///  dot(point2 - point1), normal) and is ignored when you set the
33     ///  <see cref="Arbiter.ContactPointSet"/>.
34     /// </summary>
35     [EditorBrowsable(EditorBrowsableState.Never)]
36     public sealed class ContactPoint : IEquatable<ContactPoint>
37     {
38 #pragma warning disable IDE0032
39         private readonly Vect pointA;
40         private readonly Vect pointB;
41         private readonly double distance;
42 #pragma warning restore IDE0032
43
44         /// <summary>
45         /// Point A in the contact point.
46         /// </summary>
47         [EditorBrowsable(EditorBrowsableState.Never)]
48         public Vect PointA => pointA;
49
50         /// <summary>
51         ///  Point B in the contact point.
52         /// </summary>
53         [EditorBrowsable(EditorBrowsableState.Never)]
54         public Vect PointB => pointB;
55
56         /// <summary>
57         /// The penetration distance of the two shapes (as a negative value). This value is
58         /// calculated as  dot(point2 - point1), normal) and is ignored when you set the
59         /// <see cref="Arbiter.ContactPointSet"/>.
60         /// </summary>
61         [EditorBrowsable(EditorBrowsableState.Never)]
62         public double Distance => distance;
63
64         private ContactPoint(Vect pointA, Vect pointB, double distance)
65         {
66             this.pointA = pointA;
67             this.pointB = pointB;
68             this.distance = distance;
69         }
70
71         /// <summary>
72         /// Returns true if neither <see cref="ContactPoint"/> is null and the points are within
73         /// <see cref="float.Epsilon"/> distance of each other.
74         /// </summary>
75         [EditorBrowsable(EditorBrowsableState.Never)]
76         public bool Equals(ContactPoint other)
77         {
78             if (ReferenceEquals(other, null))
79             {
80                 return false;
81             }
82
83             return other.pointA.Equals(pointA)
84                 && other.pointB.Equals(pointB)
85                 && Math.Abs(other.distance - distance) < float.Epsilon;
86         }
87
88
89         /// <summary>
90         /// Check if this <see cref="ContactPoint"/> is equal to an object.
91         /// </summary>
92         [EditorBrowsable(EditorBrowsableState.Never)]
93         public override bool Equals(object obj)
94         {
95             var other = obj as ContactPoint;
96
97             if (other == null)
98             {
99                 return false;
100             }
101
102             return Equals(other);
103         }
104
105         /// <summary>
106         /// Get the <see cref="ContactPoint"/> hash set.
107         /// </summary>
108         [EditorBrowsable(EditorBrowsableState.Never)]
109         public override int GetHashCode()
110         {
111             var hashCode = -1285340573;
112
113             hashCode = hashCode * -1521134295 + pointA.GetHashCode();
114             hashCode = hashCode * -1521134295 + pointB.GetHashCode();
115             hashCode = hashCode * -1521134295 + distance.GetHashCode();
116
117             return hashCode;
118         }
119
120         /// <summary>
121         /// Returns a string in the format of "a: {pointA}, b: {pointB}, distance: {distance}".
122         /// </summary>
123         [EditorBrowsable(EditorBrowsableState.Never)]
124         public override string ToString()
125         {
126             return $"a: {pointA}, b: {pointB}, distance: {distance}";
127         }
128
129         /// <summary>
130         /// Returns true if both <see cref="ContactPoint"/>s are the same object or the dimensions
131         /// are within <see cref="float.Epsilon"/> distance of each other.
132         /// </summary>
133         [EditorBrowsable(EditorBrowsableState.Never)]
134         public static bool operator ==(ContactPoint left, ContactPoint right)
135         {
136             if (ReferenceEquals(left, null))
137             {
138                 return ReferenceEquals(right, null);
139             }
140
141             return left.Equals(right);
142         }
143
144         /// <summary>
145         /// Returns false if both <see cref="ContactPoint"/>s are the same object or the dimensions
146         /// are within <see cref="float.Epsilon"/> distance of each other.
147         /// </summary>
148         [EditorBrowsable(EditorBrowsableState.Never)]
149         public static bool operator !=(ContactPoint left, ContactPoint right)
150         {
151             return !(left == right);
152         }
153
154         internal static ContactPoint Empty => new ContactPoint(Vect.Zero, Vect.Zero, 0.0);
155
156         internal static ContactPoint FromCollidePoint(cpContactPoint contactPoint)
157         {
158             return new ContactPoint(
159                 contactPoint.pointA,
160                 contactPoint.pointB,
161                 contactPoint.distance);
162         }
163
164         internal cpContactPoint ToContactPoint()
165         {
166             return new cpContactPoint
167             {
168                 pointA = pointA,
169                 pointB = pointB,
170                 distance = distance
171             };
172         }
173     }
174 }