[NUI.Physics2D] Add binding for Chipmunk2D physics engine
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Physics2D / src / public / chipmunk / SegmentQueryInfo.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     /// Segment queries return where a shape was hit and its surface normal at the point of contact.
30     /// Use <see cref="SegmentQueryInfo.Shape"/> == null to test if a shape was hit. Segment queries
31     /// are like ray casting, but because not all spatial indexes allow processing infinitely long
32     /// ray queries, it's limited to segments. In practice, this is still very fast and you don’t
33     /// need to worry too much about the performance as long as you aren’t using extremely long
34     /// segments for your queries.
35     /// </summary>
36     [EditorBrowsable(EditorBrowsableState.Never)]
37     public sealed class SegmentQueryInfo : IEquatable<SegmentQueryInfo>
38     {
39 #pragma warning disable IDE0032
40         private readonly Shape shape;
41         private readonly Vect point;
42         private readonly Vect normal;
43         private readonly double alpha;
44 #pragma warning restore IDE0032
45
46         /// <summary>
47         /// Shape that was hit, or None if no collision occured.
48         /// </summary>
49         [EditorBrowsable(EditorBrowsableState.Never)]
50         public Shape Shape => shape;
51
52         /// <summary>
53         /// The point of impact.
54         /// </summary>
55         [EditorBrowsable(EditorBrowsableState.Never)]
56         public Vect Point => point;
57
58         /// <summary>
59         /// The normal of the surface that was hit.
60         /// </summary>
61         [EditorBrowsable(EditorBrowsableState.Never)]
62         public Vect Normal => normal;
63
64         /// <summary>
65         /// The normalized distance along the query segment in the range [0, 1]
66         /// </summary>
67         [EditorBrowsable(EditorBrowsableState.Never)]
68         public double Alpha => alpha;
69
70         /// <summary>
71         /// Construct a Segment query info.
72         /// </summary>
73         [EditorBrowsable(EditorBrowsableState.Never)]
74         public SegmentQueryInfo(Shape s, Vect p, Vect n, double a)
75         {
76             shape = s;
77             point = p;
78             normal = n;
79             alpha = a;
80         }
81
82         /// <summary>
83         /// Return true if the given object is reference-equal to this one.
84         /// </summary>
85         /// <param name="obj"></param>
86         /// <returns></returns>
87         [EditorBrowsable(EditorBrowsableState.Never)]
88         public override bool Equals(object obj)
89         {
90             var other = obj as SegmentQueryInfo;
91
92             if (other == null)
93             {
94                 return false;
95             }
96
97             return this == other;
98         }
99
100         /// <summary>
101         /// Return true if both objects are reference-equal to each other.
102         /// </summary>
103         [EditorBrowsable(EditorBrowsableState.Never)]
104         public static bool operator ==(SegmentQueryInfo left, SegmentQueryInfo right)
105         {
106             if (ReferenceEquals(left, null))
107             {
108                 return ReferenceEquals(right, null);
109             }
110
111             return left.Equals(right);
112         }
113
114         /// <summary>
115         /// Return true if both objects are not reference-equal to each other.
116         /// </summary>
117         [EditorBrowsable(EditorBrowsableState.Never)]
118         public static bool operator !=(SegmentQueryInfo a, SegmentQueryInfo b)
119         {
120             return !(a == b);
121         }
122
123         /// <summary>
124         /// Create a SegmentQuery from a native struct cpSegmentQueryInfo.
125         /// </summary>
126         internal static SegmentQueryInfo FromQueryInfo(cpSegmentQueryInfo queryInfo)
127         {
128             Shape shape;
129
130             if (queryInfo.shape == IntPtr.Zero)
131             {
132                 shape = null;
133             }
134             else
135             {
136                 shape = Shape.FromHandle(queryInfo.shape);
137             }
138
139             return new SegmentQueryInfo(
140                 shape,
141                 queryInfo.point,
142                 queryInfo.normal,
143                 queryInfo.alpha);
144         }
145
146         /// <summary>
147         /// Return true if the fields in both objects are equivalent and the <see cref="alpha"/>
148         /// field is within <see cref="Single.Epsilon"/> of the other's.
149         /// </summary>
150         [EditorBrowsable(EditorBrowsableState.Never)]
151         public bool Equals(SegmentQueryInfo other)
152         {
153             if (ReferenceEquals(other, null) ||
154                 shape?.Handle != other.shape?.Handle ||
155                 point != other.point ||
156                 normal != other.normal)
157             {
158                 return false;
159             }
160
161             return Math.Abs(alpha - other.alpha) < float.Epsilon;
162         }
163
164         /// <summary>
165         /// Get the hash code.
166         /// </summary>
167         [EditorBrowsable(EditorBrowsableState.Never)]
168         public override int GetHashCode()
169         {
170             var hashCode = -1275187100;
171             hashCode = hashCode * -1521134295 + shape.GetHashCode();
172             hashCode = hashCode * -1521134295 + point.GetHashCode();
173             hashCode = hashCode * -1521134295 + normal.GetHashCode();
174             hashCode = hashCode * -1521134295 + alpha.GetHashCode();
175             return hashCode;
176         }
177     }
178 }