[NUI.Physics2D] Add binding for Chipmunk2D physics engine
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Physics2D / src / public / chipmunk / ContactPointSet.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.Collections.Generic;
25 using System.ComponentModel;
26 using System.Linq;
27
28 namespace Tizen.NUI.Physics2D.Chipmunk
29 {
30     /// <summary>
31     /// Contact point sets make getting contact information simpler. There can be at most 2 contact
32     /// points.
33     /// </summary>
34     [EditorBrowsable(EditorBrowsableState.Never)]
35     public sealed class ContactPointSet : IEquatable<ContactPointSet>
36     {
37 #pragma warning disable IDE0032
38         private readonly int count;
39         private readonly Vect normal;
40         private readonly ContactPoint[] points;
41 #pragma warning restore IDE0032
42
43         private ContactPointSet(int count, Vect normal, ContactPoint[] points)
44         {
45             this.count = count;
46             this.normal = normal;
47             this.points = points;
48         }
49
50         /// <summary>
51         /// Get the number of contact points in the contact set (maximum of two).
52         /// </summary>
53         [EditorBrowsable(EditorBrowsableState.Never)]
54         public int Count => count;
55
56         /// <summary>
57         /// Get the normal of the collision.
58         /// </summary>
59         [EditorBrowsable(EditorBrowsableState.Never)]
60         public Vect Normal => normal;
61
62         /// <summary>
63         /// List of points in the contact point set
64         /// </summary>
65         [EditorBrowsable(EditorBrowsableState.Never)]
66         public IReadOnlyList<ContactPoint> Points => points;
67
68         /// <summary>
69         /// Return true if the contact point set is sequence-equal to another.
70         /// </summary>
71         [EditorBrowsable(EditorBrowsableState.Never)]
72         public bool Equals(ContactPointSet other)
73         {
74             if (ReferenceEquals(other, null)
75                 || count != other.count
76                 || normal != other.normal
77                 || points.Length != other.points.Length)
78             {
79                 return false;
80             }
81
82             return points.SequenceEqual(other.points);
83         }
84
85         /// <summary>
86         /// Get the hash code.
87         /// </summary>
88         [EditorBrowsable(EditorBrowsableState.Never)]
89         public override int GetHashCode()
90         {
91             var hashCode = -475635172;
92
93             hashCode = hashCode * -1521134295 + count.GetHashCode();
94             hashCode = hashCode * -1521134295 + normal.GetHashCode();
95             hashCode = hashCode * -1521134295 + EqualityComparer<ContactPoint[]>.Default.GetHashCode(points);
96
97             return hashCode;
98         }
99
100         /// <summary>
101         /// Return true if the <see cref="ContactPointSet"/> is sequence-equal to another.
102         /// </summary>
103         [EditorBrowsable(EditorBrowsableState.Never)]
104         public override bool Equals(object obj)
105         {
106             var other = obj as ContactPointSet;
107
108             if (other == null)
109             {
110                 return false;
111             }
112
113             return Equals(other);
114         }
115
116         /// <summary>
117         /// Return true if the contact point sets are sequence-equal.
118         /// </summary>
119         [EditorBrowsable(EditorBrowsableState.Never)]
120         public static bool operator ==(ContactPointSet left, ContactPointSet right)
121         {
122             if (ReferenceEquals(left, null))
123             {
124                 return ReferenceEquals(right, null);
125             }
126
127             return left.Equals(right);
128         }
129
130         /// <summary>
131         /// Return true if the contact point sets are sequence-inequal.
132         /// </summary>
133         [EditorBrowsable(EditorBrowsableState.Never)]
134         public static bool operator !=(ContactPointSet left, ContactPointSet right)
135         {
136             return !(left == right);
137         }
138
139         internal static ContactPointSet FromContactPointSet(cpContactPointSet contactPointSet)
140         {
141             var points = new ContactPoint[2];
142
143             if (contactPointSet.count > 0)
144             {
145                 points[0] = ContactPoint.FromCollidePoint(contactPointSet.points0);
146             }
147             else
148             {
149                 points[0] = ContactPoint.Empty;
150             }
151
152             if (contactPointSet.count > 1)
153             {
154                 points[1] = ContactPoint.FromCollidePoint(contactPointSet.points1);
155             }
156             else
157             {
158                 points[1] = ContactPoint.Empty;
159             }
160
161             return new ContactPointSet(
162                 contactPointSet.count,
163                 contactPointSet.normal,
164                 points);
165         }
166
167         internal cpContactPointSet ToContactPointSet()
168         {
169             return new cpContactPointSet
170             {
171                 normal = normal,
172                 points0 = points[0].ToContactPoint(),
173                 points1 = points[1].ToContactPoint(),
174                 count = count
175             };
176         }
177     }
178 }