[NUI.Physics2D] Add binding for Chipmunk2D physics engine
authorRichard Huang <r.huang@samsung.com>
Tue, 12 Sep 2023 09:32:17 +0000 (10:32 +0100)
committerbshsqa <32317749+bshsqa@users.noreply.github.com>
Thu, 14 Sep 2023 10:40:33 +0000 (19:40 +0900)
57 files changed:
src/Tizen.NUI.Physics2D/Properties/AssemblyInfo.cs [new file with mode: 0755]
src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj [new file with mode: 0755]
src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.sln [new file with mode: 0755]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/DelegateExtensions.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/Delegates.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeInterop.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeMethods.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/PostStepCallbackInfo.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpCollisionHandler.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPoint.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPointSet.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPointQueryInfo.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPolyline.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSegmentQueryInfo.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Arbiter.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/AutoGeometry.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/BodyType.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/BoundingBox.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/CollisionHandler.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/Constraint.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedRotarySpring.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedSpring.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GearJoint.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GrooveJoint.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PinJoint.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PivotJoint.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RatchetJoint.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RotaryLimitJoint.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SimpleMotor.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SlideJoint.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPoint.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPointSet.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugColor.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawColors.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawFlags.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/HastySpace.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/IDebugDraw.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/MarchData.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/PointQueryInfo.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/SegmentQueryInfo.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/ShapeFilter.cs [new file with mode: 0755]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Box.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Circle.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Polygon.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Segment.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Shape.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs [new file with mode: 0755]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Transform.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/CircleExtensions.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/PolygonExtensions.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/SegmentExtensions.cs [new file with mode: 0644]
src/Tizen.NUI.Physics2D/src/public/chipmunk/Vect.cs [new file with mode: 0644]
test/Tizen.NUI.Physics2D.Sample/Physics2DSample.cs [new file with mode: 0644]
test/Tizen.NUI.Physics2D.Sample/Tizen.NUI.Physics2D.Sample.csproj [new file with mode: 0644]
test/Tizen.NUI.Physics2D.Sample/tizen-manifest.xml [new file with mode: 0644]

diff --git a/src/Tizen.NUI.Physics2D/Properties/AssemblyInfo.cs b/src/Tizen.NUI.Physics2D/Properties/AssemblyInfo.cs
new file mode 100755 (executable)
index 0000000..3110dbc
--- /dev/null
@@ -0,0 +1,4 @@
+using Tizen.NUI;
+
+// Xamarin.Forms.Loader.dll Xamarin.Forms.Xaml.XamlLoader.Load(object, string), kzu@microsoft.com
+[assembly: XmlnsDefinition("http://tizen.org/Tizen.NUI/2018/XAML", "Tizen.NUI.Physics2D")]
diff --git a/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj b/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj
new file mode 100755 (executable)
index 0000000..ab51d11
--- /dev/null
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net6.0</TargetFramework>
+    <NoWarn>$(NoWarn);CS0618;CA1054;CA1056</NoWarn>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+    <ProjectReference Include="..\Tizen.NUI\Tizen.NUI.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Folder Include="chipmunk\" />
+  </ItemGroup>
+
+</Project>
diff --git a/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.sln b/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.sln
new file mode 100755 (executable)
index 0000000..f72eb28
--- /dev/null
@@ -0,0 +1,79 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31515.178
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.NUI.Physics2D", "Tizen.NUI.Physics2D.csproj", "{F6CEE887-775A-4623-8BF8-DCA18C363D62}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.NUI", "..\Tizen.NUI\Tizen.NUI.csproj", "{F9DAA9C3-593D-467E-B02C-FFF51F1BC8CD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Applications.Common", "..\Tizen.Applications.Common\Tizen.Applications.Common.csproj", "{CE90CD24-82F7-45A3-96B2-2E3C97D25C30}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.System.SystemSettings", "..\Tizen.System.SystemSettings\Tizen.System.SystemSettings.csproj", "{D726EEB8-6382-4BA3-BE0C-D9E61B5D8374}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen", "..\Tizen\Tizen.csproj", "{6D5FFD69-6DCC-4953-85E9-C23AC18B190E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.System.Information", "..\Tizen.System.Information\Tizen.System.Information.csproj", "{A951EAFE-D191-4F45-9AEF-7D97C382A747}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Log", "..\Tizen.Log\Tizen.Log.csproj", "{E1E30AEC-AD46-4E53-B9B1-780A68B59963}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Applications.ComponentBased", "..\Tizen.Applications.ComponentBased\Tizen.Applications.ComponentBased.csproj", "{70341AA2-1324-4215-9DB8-BFB13389D932}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Applications.ThemeManager", "..\Tizen.Applications.ThemeManager\Tizen.Applications.ThemeManager.csproj", "{F6A776BF-6743-4C1D-A8AF-F3E9F8CEFA0A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Tracer", "..\Tizen.Tracer\Tizen.Tracer.csproj", "{6DABE78F-1816-4F2E-8966-F909173194C8}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Release|Any CPU = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {F6CEE887-775A-4623-8BF8-DCA18C363D62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {F6CEE887-775A-4623-8BF8-DCA18C363D62}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {F6CEE887-775A-4623-8BF8-DCA18C363D62}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {F6CEE887-775A-4623-8BF8-DCA18C363D62}.Release|Any CPU.Build.0 = Release|Any CPU
+               {F9DAA9C3-593D-467E-B02C-FFF51F1BC8CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {F9DAA9C3-593D-467E-B02C-FFF51F1BC8CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {F9DAA9C3-593D-467E-B02C-FFF51F1BC8CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {F9DAA9C3-593D-467E-B02C-FFF51F1BC8CD}.Release|Any CPU.Build.0 = Release|Any CPU
+               {CE90CD24-82F7-45A3-96B2-2E3C97D25C30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {CE90CD24-82F7-45A3-96B2-2E3C97D25C30}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {CE90CD24-82F7-45A3-96B2-2E3C97D25C30}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {CE90CD24-82F7-45A3-96B2-2E3C97D25C30}.Release|Any CPU.Build.0 = Release|Any CPU
+               {D726EEB8-6382-4BA3-BE0C-D9E61B5D8374}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {D726EEB8-6382-4BA3-BE0C-D9E61B5D8374}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {D726EEB8-6382-4BA3-BE0C-D9E61B5D8374}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {D726EEB8-6382-4BA3-BE0C-D9E61B5D8374}.Release|Any CPU.Build.0 = Release|Any CPU
+               {6D5FFD69-6DCC-4953-85E9-C23AC18B190E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {6D5FFD69-6DCC-4953-85E9-C23AC18B190E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {6D5FFD69-6DCC-4953-85E9-C23AC18B190E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {6D5FFD69-6DCC-4953-85E9-C23AC18B190E}.Release|Any CPU.Build.0 = Release|Any CPU
+               {A951EAFE-D191-4F45-9AEF-7D97C382A747}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {A951EAFE-D191-4F45-9AEF-7D97C382A747}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {A951EAFE-D191-4F45-9AEF-7D97C382A747}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {A951EAFE-D191-4F45-9AEF-7D97C382A747}.Release|Any CPU.Build.0 = Release|Any CPU
+               {E1E30AEC-AD46-4E53-B9B1-780A68B59963}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {E1E30AEC-AD46-4E53-B9B1-780A68B59963}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {E1E30AEC-AD46-4E53-B9B1-780A68B59963}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {E1E30AEC-AD46-4E53-B9B1-780A68B59963}.Release|Any CPU.Build.0 = Release|Any CPU
+               {70341AA2-1324-4215-9DB8-BFB13389D932}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {70341AA2-1324-4215-9DB8-BFB13389D932}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {70341AA2-1324-4215-9DB8-BFB13389D932}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {70341AA2-1324-4215-9DB8-BFB13389D932}.Release|Any CPU.Build.0 = Release|Any CPU
+               {F6A776BF-6743-4C1D-A8AF-F3E9F8CEFA0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {F6A776BF-6743-4C1D-A8AF-F3E9F8CEFA0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {F6A776BF-6743-4C1D-A8AF-F3E9F8CEFA0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {F6A776BF-6743-4C1D-A8AF-F3E9F8CEFA0A}.Release|Any CPU.Build.0 = Release|Any CPU
+               {6DABE78F-1816-4F2E-8966-F909173194C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {6DABE78F-1816-4F2E-8966-F909173194C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {6DABE78F-1816-4F2E-8966-F909173194C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {6DABE78F-1816-4F2E-8966-F909173194C8}.Release|Any CPU.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(ExtensibilityGlobals) = postSolution
+               SolutionGuid = {83C85CFB-3AB8-403A-9F6D-CC2783C6C559}
+       EndGlobalSection
+EndGlobal
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/DelegateExtensions.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/DelegateExtensions.cs
new file mode 100644 (file)
index 0000000..dc2aed0
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * 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.Runtime.InteropServices;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Create a ToFunctionPointer extension method for each delegate type. Unfortunately C# 7.0
+    /// can't do something like that (you will need C# 7.3), thus we create one extension method for
+    /// each delegate public static IntPtr ToFunctionPointer T (this T d) where T : Delegate
+    /// </summary>
+    static internal class DelegateExtensions
+    {
+        public static IntPtr ToFunctionPointer(this BodyArbiterIteratorFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<BodyArbiterIteratorFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this BodyConstraintIteratorFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<BodyConstraintIteratorFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this BodyShapeIteratorFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<BodyShapeIteratorFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this BodyVelocityFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<BodyVelocityFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this BodyPositionFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<BodyPositionFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this CollisionBeginFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<CollisionBeginFunction>(d);
+        }
+
+
+        public static IntPtr ToFunctionPointer(this CollisionPreSolveFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<CollisionPreSolveFunction>(d);
+        }
+
+
+        public static IntPtr ToFunctionPointer(this CollisionPostSolveFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<CollisionPostSolveFunction>(d);
+        }
+
+
+        public static IntPtr ToFunctionPointer(this CollisionSeparateFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<CollisionSeparateFunction>(d);
+        }
+
+
+        public static IntPtr ToFunctionPointer(this PostStepFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<PostStepFunction>(d);
+        }
+
+
+        public static IntPtr ToFunctionPointer(this SpaceSegmentQueryFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<SpaceSegmentQueryFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this SpacePointQueryFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<SpacePointQueryFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this SpaceBBQueryFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<SpaceBBQueryFunction>(d);
+        }
+
+
+        public static IntPtr ToFunctionPointer(this SpaceObjectIteratorFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<SpaceObjectIteratorFunction>(d);
+        }
+
+
+        public static IntPtr ToFunctionPointer(this SpaceDebugDrawCircleImpl d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<SpaceDebugDrawCircleImpl>(d);
+        }
+
+
+        public static IntPtr ToFunctionPointer(this SpaceDebugDrawSegmentImpl d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<SpaceDebugDrawSegmentImpl>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this SpaceDebugDrawFatSegmentImpl d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<SpaceDebugDrawFatSegmentImpl>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this SpaceDebugDrawPolygonImpl d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<SpaceDebugDrawPolygonImpl>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this SpaceDebugDrawDotImpl d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<SpaceDebugDrawDotImpl>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this SpaceDebugDrawColorForShapeImpl d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<SpaceDebugDrawColorForShapeImpl>(d);
+        }
+
+
+        public static IntPtr ToFunctionPointer(this ConstraintSolveFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<ConstraintSolveFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this DampedSpringForceFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<DampedSpringForceFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this DampedRotarySpringTorqueFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<DampedRotarySpringTorqueFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this SpaceShapeQueryFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<SpaceShapeQueryFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this MarchSegmentFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<MarchSegmentFunction>(d);
+        }
+
+        public static IntPtr ToFunctionPointer(this MarchSampleFunction d)
+        {
+            if (d == null)
+            {
+                return IntPtr.Zero;
+            }
+
+            return Marshal.GetFunctionPointerForDelegate<MarchSampleFunction>(d);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/Delegates.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/Delegates.cs
new file mode 100644 (file)
index 0000000..8c2d219
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * 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.Runtime.InteropServices;
+using System.Security;
+using cpArbiter = System.IntPtr;
+using cpBody = System.IntPtr;
+using cpBool = System.Byte;
+using cpConstraint = System.IntPtr;
+using cpContactPointSetPointer = System.IntPtr;
+using cpHandle = System.IntPtr;
+using cpShape = System.IntPtr;
+using cpSpace = System.IntPtr;
+using cpVertPointer = System.IntPtr;
+using voidptr_t = System.IntPtr;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+using ObjCRuntime;
+#endif
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Delegate method to iterate over arbiters.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void BodyArbiterIteratorFunction(cpBody body, cpArbiter arbiter, voidptr_t data);
+
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void BodyVelocityFunction(cpBody body, Vect gravity, double damping, double dt);
+
+    /// <summary>
+    /// Rigid body position update function type.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void BodyPositionFunction(cpBody body, double dt);
+
+    /// <summary>
+    /// Delegate method to iterate over constraints.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void BodyConstraintIteratorFunction(cpBody body, cpConstraint constraint, voidptr_t data);
+
+    /// <summary>
+    /// Delegate method to iterate over shapes.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void BodyShapeIteratorFunction(cpBody body, cpShape shape, voidptr_t data);
+
+    /// <summary>
+    /// Collision begin event function callback type. Returning false from a begin callback causes
+    /// the collision to be ignored until the the separate callback is called when the objects stop
+    /// colliding.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void CollisionBeginFunction(cpArbiter arbiter, cpSpace space, voidptr_t userData);
+
+    /// <summary>
+    /// Collision pre-solve event function callback type. Returning false from a pre-step callback
+    /// causes the collision to be ignored until the next step.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate cpBool CollisionPreSolveFunction(cpArbiter arbiter, cpSpace space, voidptr_t userData);
+
+    /// <summary>
+    /// Collision Post-Solve .
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void CollisionPostSolveFunction(cpArbiter arbiter, cpSpace space, voidptr_t userData);
+
+    /// <summary>
+    /// Collision separate event function callback type.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void CollisionSeparateFunction(cpArbiter arbiter, cpSpace space, voidptr_t userData);
+
+    /// <summary>
+    /// Post Step callback function type.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void PostStepFunction(cpSpace space, voidptr_t key, voidptr_t data);
+
+    /// <summary>
+    /// Nearest point query callback function type.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void SpacePointQueryFunction(cpShape shape, Vect point, double distance, Vect gradient, voidptr_t data);
+
+    /// <summary>
+    /// Segment query callback function type.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void SpaceSegmentQueryFunction(cpShape shape, Vect point, Vect normal, double alpha, voidptr_t data);
+
+    /// <summary>
+    /// Rectangle Query callback function type.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void SpaceBBQueryFunction(cpShape shape, voidptr_t data);
+
+    /// <summary>
+    /// Space/object iterator callback function type.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void SpaceObjectIteratorFunction(cpHandle handle, voidptr_t data);
+
+    /// <summary>
+    /// Callback type for a function that draws a filled, stroked circle.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void SpaceDebugDrawCircleImpl(Vect pos, double angle, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data);
+
+    /// <summary>
+    /// Callback type for a function that draws a line segment.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void SpaceDebugDrawSegmentImpl(Vect a, Vect b, DebugColor color, voidptr_t data);
+
+    /// <summary>
+    /// Callback type for a function that draws a thick line segment.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void SpaceDebugDrawFatSegmentImpl(Vect a, Vect b, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data);
+
+    /// <summary>
+    /// Callback type for a function that draws a convex polygon.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void SpaceDebugDrawPolygonImpl(int count, cpVertPointer verts, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data);
+
+    /// <summary>
+    /// Callback type for a function that draws a dot.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void SpaceDebugDrawDotImpl(double size, Vect pos, DebugColor color, voidptr_t data);
+
+    /// <summary>
+    /// Callback type for a function that returns a color for a given shape. This gives you an
+    /// opportunity to color shapes based on how they are used in your engine.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate DebugColor SpaceDebugDrawColorForShapeImpl(cpShape shape, voidptr_t data);
+
+    /// <summary>
+    /// Callback function type that gets called after/before solving a joint.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void ConstraintSolveFunction(cpConstraint constraint, cpSpace space);
+
+    /// <summary>
+    /// Function type used for damped spring force callbacks.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate double DampedSpringForceFunction(cpConstraint spring, double dist);
+
+    /// <summary>
+    /// Function type used for damped rotary spring force callbacks
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate double DampedRotarySpringTorqueFunction(cpConstraint spring, double relativeAngle);
+
+    /// <summary>
+    /// Shape query callback function type.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void SpaceShapeQueryFunction(cpShape shape, cpContactPointSetPointer points, voidptr_t data);
+
+    /// <summary>
+    /// Function type used as a callback from the marching squares algorithm to output a line
+    /// segment. It passes you the two endpoints and your context pointer.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate void MarchSegmentFunction(Vect v0, Vect v1, voidptr_t data);
+
+    /// <summary>
+    /// Function type used as a callback from the marching squares algorithm to sample an image function.
+    /// It passes you the point to sample and your context pointer, and you return the density.
+    /// </summary>
+    [SuppressUnmanagedCodeSecurity]
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+    [MonoNativeFunctionWrapper]
+#endif
+    internal delegate double MarchSampleFunction(Vect point, voidptr_t data);
+}
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeInterop.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeInterop.cs
new file mode 100644 (file)
index 0000000..5859c0b
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * 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.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    internal static class NativeInterop
+    {
+        public static IntPtr RegisterHandle(object obj)
+        {
+            var gcHandle = GCHandle.Alloc(obj);
+            return GCHandle.ToIntPtr(gcHandle);
+        }
+
+        public static T FromIntPtr<T>(IntPtr pointer)
+        {
+            Debug.Assert(pointer != IntPtr.Zero, "IntPtr parameter should never be Zero");
+
+            var handle = GCHandle.FromIntPtr(pointer);
+
+            Debug.Assert(handle.IsAllocated, "GCHandle not allocated.");
+            Debug.Assert(handle.Target is T, "Target is not of type T.");
+
+            return (T)handle.Target;
+        }
+
+        public static void ReleaseHandle(IntPtr pointer)
+        {
+            Debug.Assert(pointer != IntPtr.Zero, "IntPtr parameter should never be Zero");
+
+            var handle = GCHandle.FromIntPtr(pointer);
+
+            Debug.Assert(handle.IsAllocated, "GCHandle not allocated.");
+
+            handle.Free();
+        }
+
+        public static T FromIntPtrAndFree<T>(IntPtr pointer)
+        {
+            Debug.Assert(pointer != IntPtr.Zero, "IntPtr parameter should never be Zero");
+
+            var handle = GCHandle.FromIntPtr(pointer);
+
+            Debug.Assert(handle.IsAllocated, "GCHandle not allocated.");
+            Debug.Assert(handle.Target is T, "Target is not of type T.");
+            T obj = (T)handle.Target;
+
+            handle.Free();
+
+            return obj;
+        }
+
+        public static int SizeOf<T>()
+        {
+            return Marshal.SizeOf<T>();
+        }
+
+        public static IntPtr AllocStructure<T>()
+        {
+            int size = SizeOf<T>();
+            return Marshal.AllocHGlobal(size);
+        }
+
+        public static void FreeStructure(IntPtr ptr)
+        {
+            Marshal.FreeHGlobal(ptr);
+        }
+
+        public static T PtrToStructure<T>(IntPtr intPtr)
+        {
+            return Marshal.PtrToStructure<T>(intPtr);
+        }
+
+        public static T[] PtrToStructureArray<T>(IntPtr intPtr, int count)
+        {
+            var items = new T[count];
+            var size = SizeOf<T>();
+
+            for (var i = 0; i < count; i++)
+            {
+                var newPtr = new IntPtr(intPtr.ToInt64() + (i * size));
+                items[i] = PtrToStructure<T>(newPtr);
+            }
+
+            return items;
+        }
+
+        internal static IntPtr StructureArrayToPtr<T>(IReadOnlyList<T> items)
+        {
+            var size = SizeOf<T>();
+            var memory = Marshal.AllocHGlobal(size * items.Count);
+
+            for (var i = 0; i < items.Count; i++)
+            {
+                var ptr = new IntPtr(memory.ToInt64() + (i * size));
+                Marshal.StructureToPtr<T>(items[i], ptr, true);
+            }
+
+            return memory;
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeMethods.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeMethods.cs
new file mode 100644 (file)
index 0000000..305d403
--- /dev/null
@@ -0,0 +1,1228 @@
+/*
+ * 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.
+ */
+
+// ReSharper disable IdentifierTypo
+using System;
+using System.Runtime.InteropServices;
+using System.Security;
+using cpArbiter = System.IntPtr;
+using cpBitmask = System.UInt32;
+using cpBody = System.IntPtr;
+using cpBodyArbiterIteratorFunc = System.IntPtr;
+using cpBodyConstraintIteratorFunc = System.IntPtr;
+using cpBodyPositionFunc = System.IntPtr;
+using cpBodyShapeIteratorFunc = System.IntPtr;
+using cpBodyType = System.Int32;
+using cpBodyVelocityFunc = System.IntPtr;
+using cpBool = System.Byte;
+using cpCollisionHandlerPointer = System.IntPtr;
+using cpCollisionType = System.UIntPtr;
+using cpConstraint = System.IntPtr;
+using cpConstraintPostSolveFunc = System.IntPtr;
+using cpConstraintPreSolveFunc = System.IntPtr;
+using cpDampedRotarySpringTorqueFunc = System.IntPtr;
+using cpDampedSpringForceFunc = System.IntPtr;
+using cpDataPointer = System.IntPtr;
+using cpFloat = System.Double;
+using cpGroup = System.UIntPtr;
+using cpMarchSampleFunc = System.IntPtr;
+using cpMarchSegmentFunc = System.IntPtr;
+using cpPolyline = System.IntPtr;
+using cpPolylineSet = System.IntPtr;
+using cpPostStepFunc = System.IntPtr;
+using cpShape = System.IntPtr;
+using cpSpace = System.IntPtr;
+using cpSpaceBBQueryFunc = System.IntPtr;
+using cpSpaceBodyIteratorFunc = System.IntPtr;
+using cpSpaceConstraintIteratorFunc = System.IntPtr;
+using cpSpaceDebugDrawOptionsPointer = System.IntPtr;
+using cpSpaceHash = System.IntPtr;
+using cpSpacePointQueryFunc = System.IntPtr;
+using cpSpaceSegmentQueryFunc = System.IntPtr;
+using cpSpaceShapeIteratorFunc = System.IntPtr;
+using cpSpaceShapeQueryFunc = System.IntPtr;
+using cpSpatialIndex = System.IntPtr;
+using cpSpatialIndexBBFunc = System.IntPtr;
+using cpSpatialIndexQueryFunc = System.IntPtr;
+using cpSweep1D = System.IntPtr;
+using cpTimestamp = System.UInt32;
+using cpVectPointer = System.IntPtr;
+using VoidPointer = System.IntPtr;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    [SuppressUnmanagedCodeSecurity]
+    internal static class NativeMethods
+    {
+
+#pragma warning disable CA1823 // Unused field 'ChipmunkLibraryName'
+
+#if __MACOS__ 
+        private const string ChipmunkLibraryName = "libchipmunk.dylib";
+#else
+        private const string ChipmunkLibraryName = "libchipmunk.so";
+#endif
+
+#pragma warning restore CA1823 // Unused field 'ChipmunkLibraryName'
+
+#pragma warning disable IDE1006 // Naming Styles
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterCallWildcardBeginA(cpArbiter arb, cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterCallWildcardBeginB(cpArbiter arb, cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterCallWildcardPostSolveA(cpArbiter arb, cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterCallWildcardPostSolveB(cpArbiter arb, cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpArbiterCallWildcardPreSolveA(cpArbiter arb, cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpArbiterCallWildcardPreSolveB(cpArbiter arb, cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterCallWildcardSeparateA(cpArbiter arb, cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterCallWildcardSeparateB(cpArbiter arb, cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterGetBodies(cpArbiter arb, out cpBody a, out cpBody b);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpContactPointSet cpArbiterGetContactPointSet(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern int cpArbiterGetCount(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpArbiterGetDepth(cpArbiter arb, int i);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpArbiterGetFriction(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpArbiterGetNormal(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpArbiterGetPointA(cpArbiter arb, int i);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpArbiterGetPointB(cpArbiter arb, int i);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpArbiterGetRestitution(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterGetShapes(cpArbiter arb, out cpShape a, out cpShape b);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpArbiterGetSurfaceVelocity(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpDataPointer cpArbiterGetUserData(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpArbiterIgnore(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpArbiterIsFirstContact(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpArbiterIsRemoval(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterSetContactPointSet(cpArbiter arb, ref cpContactPointSet set);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterSetFriction(cpArbiter arb, cpFloat friction);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterSetRestitution(cpArbiter arb, cpFloat restitution);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterSetSurfaceVelocity(cpArbiter arb, Vect vr);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpArbiterSetUserData(cpArbiter arb, cpDataPointer userData);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpArbiterTotalImpulse(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpArbiterTotalKE(cpArbiter arb);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpAreaForPoly(int count, cpVectPointer verts, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpAreaForSegment(Vect a, Vect b, cpFloat radius);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpBBTree cpBBTreeAlloc();
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSpatialIndex cpBBTreeInit(cpBBTree tree, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSpatialIndex cpBBTreeNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern void cpBBTreeOptimize(cpSpatialIndex index);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern void cpBBTreeSetVelocityFunc(cpSpatialIndex index, cpBBTreeVelocityFunc func);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyActivate(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyActivateStatic(cpBody body, cpShape filter);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpBody cpBodyAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyApplyForceAtLocalPoint(cpBody body, Vect force, Vect point);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyApplyForceAtWorldPoint(cpBody body, Vect force, Vect point);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyApplyTorque(cpBody body, cpFloat torque);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyApplyAngularImpulse(cpBody body, cpFloat impulse);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyApplyImpulseAtLocalPoint(cpBody body, Vect impulse, Vect point);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyApplyImpulseAtWorldPoint(cpBody body, Vect impulse, Vect point);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern void cpBodyDestroy(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpBodyContactWith(cpBody bodyA, cpBody bodyB);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyEachArbiter(cpBody body, cpBodyArbiterIteratorFunc func, VoidPointer data);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyEachConstraint(cpBody body, cpBodyConstraintIteratorFunc func, VoidPointer data);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyEachShape(cpBody body, cpBodyShapeIteratorFunc func, VoidPointer data);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyFree(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpBodyGetAngle(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpBodyGetAngularVelocity(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpBodyGetCenterOfGravity(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern int cpBodyGetContactedBodiesCount(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyGetUserDataContactedBodies(cpBody body, IntPtr userDataArray);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBodyPositionFunc cpBodyGetDefaultPositionUpdateFunc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBodyVelocityFunc cpBodyGetDefaultVelocityUpdateFunc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpBodyGetForce(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpBodyGetMass(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpBodyGetMoment(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpBodyGetPosition(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpBodyGetRotation(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpSpace cpBodyGetSpace(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyGetTransform(cpBody body, out Vect pos, out cpFloat angle);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpBodyGetTorque(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBodyType cpBodyGetType(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpDataPointer cpBodyGetUserData(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpBodyGetVelocity(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpBodyGetVelocityAtLocalPoint(cpBody body, Vect point);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpBodyGetVelocityAtWorldPoint(cpBody body, Vect point);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpBody cpBodyInit(cpBody body, cpFloat mass, cpFloat moment);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpBodyIsSleeping(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpBodyKineticEnergy(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpBodyLocalToWorld(cpBody body, Vect point);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBody cpBodyNew(cpFloat mass, cpFloat moment);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBody cpBodyNewKinematic();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBody cpBodyNewStatic();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetAngle(cpBody body, cpFloat a);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetAngularVelocity(cpBody body, cpFloat angularVelocity);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetCenterOfGravity(cpBody body, Vect cog);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetForce(cpBody body, Vect force);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetMass(cpBody body, cpFloat m);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetMoment(cpBody body, cpFloat i);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetPosition(cpBody body, Vect pos);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetPositionUpdateFunc(cpBody body, cpBodyPositionFunc positionFunc);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetTransform(cpBody body, Vect pos, cpFloat angle);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetTorque(cpBody body, cpFloat torque);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetType(cpBody body, cpBodyType type);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetUserData(cpBody body, cpDataPointer userData);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetVelocity(cpBody body, Vect velocity);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySetVelocityUpdateFunc(cpBody body, cpBodyVelocityFunc velocityFunc);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySleep(cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodySleepWithGroup(cpBody body, cpBody group);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyUpdatePosition(cpBody body, cpFloat dt);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpBodyUpdateVelocity(cpBody body, Vect gravity, cpFloat damping, cpFloat dt);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpBodyWorldToLocal(cpBody body, Vect point);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpPolyShape cpBoxShapeInit(cpPolyShape poly, cpBody body, cpFloat width, cpFloat height, cpFloat radius);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpPolyShape cpBoxShapeInit2(cpPolyShape poly, cpBody body, BoundingBox box, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpShape cpBoxShapeNew(cpBody body, cpFloat width, cpFloat height, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpShape cpBoxShapeNew2(cpBody body, BoundingBox box, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpCentroidForPoly(int count, cpVectPointer verts);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpCircleShape cpCircleShapeAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpCircleShapeGetOffset(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpCircleShapeGetRadius(cpShape shape);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpCircleShape cpCircleShapeInit(cpCircleShape circle, cpBody body, cpFloat radius, Vect offset);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpShape cpCircleShapeNew(cpBody body, cpFloat radius, Vect offset);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpCircleShapeSetOffset(cpShape shape, Vect offset);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpCircleShapeSetRadius(cpShape shape, cpFloat radius);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern void cpConstraintDestroy(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpConstraintFree(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBody cpConstraintGetBodyA(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBody cpConstraintGetBodyB(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpConstraintGetCollideBodies(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpConstraintGetErrorBias(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpConstraintGetImpulse(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpConstraintGetMaxBias(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpConstraintGetMaxForce(cpConstraint constraint);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpConstraintPostSolveFunc cpConstraintGetPostSolveFunc(cpConstraint constraint);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpConstraintPreSolveFunc cpConstraintGetPreSolveFunc(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpSpace cpConstraintGetSpace(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpDataPointer cpConstraintGetUserData(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpConstraintIsDampedRotarySpring(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpConstraintIsDampedSpring(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpConstraintIsGearJoint(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpConstraintIsGrooveJoint(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpConstraintIsPinJoint(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpConstraintIsPivotJoint(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpConstraintIsRatchetJoint(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpConstraintIsRotaryLimitJoint(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpConstraintIsSimpleMotor(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpConstraintIsSlideJoint(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpConstraintSetCollideBodies(cpConstraint constraint, cpBool collideBodies);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpConstraintSetErrorBias(cpConstraint constraint, cpFloat errorBias);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpConstraintSetMaxBias(cpConstraint constraint, cpFloat maxBias);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpConstraintSetMaxForce(cpConstraint constraint, cpFloat maxForce);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpConstraintSetPostSolveFunc(cpConstraint constraint, cpConstraintPostSolveFunc postSolveFunc);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpConstraintSetPreSolveFunc(cpConstraint constraint, cpConstraintPreSolveFunc preSolveFunc);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpConstraintSetUserData(cpConstraint constraint, cpDataPointer userData);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern int cpConvexHull(int count, cpVectPointer verts, cpVectPointer result, IntPtr first, cpFloat tol);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpDampedRotarySpring cpDampedRotarySpringAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpDampedRotarySpringGetDamping(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpDampedRotarySpringGetRestAngle(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpDampedRotarySpringTorqueFunc cpDampedRotarySpringGetSpringTorqueFunc(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpDampedRotarySpringGetStiffness(cpConstraint constraint);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpDampedRotarySpring cpDampedRotarySpringInit(cpDampedRotarySpring joint, cpBody a, cpBody b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpDampedRotarySpringNew(cpBody a, cpBody b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpDampedRotarySpringSetDamping(cpConstraint constraint, cpFloat damping);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpDampedRotarySpringSetRestAngle(cpConstraint constraint, cpFloat restAngle);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpDampedRotarySpringSetSpringTorqueFunc(cpConstraint constraint, cpDampedRotarySpringTorqueFunc springTorqueFunc);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpDampedRotarySpringSetStiffness(cpConstraint constraint, cpFloat stiffness);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpDampedSpring cpDampedSpringAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpDampedSpringGetAnchorA(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpDampedSpringGetAnchorB(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpDampedSpringGetDamping(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpDampedSpringGetRestLength(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpDampedSpringForceFunc cpDampedSpringGetSpringForceFunc(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpDampedSpringGetStiffness(cpConstraint constraint);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpDampedSpring cpDampedSpringInit(cpDampedSpring joint, cpBody a, cpBody b, Vect anchorA, Vect anchorB, cpFloat restLength, cpFloat stiffness, cpFloat damping);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpDampedSpringNew(cpBody a, cpBody b, Vect anchorA, Vect anchorB, cpFloat restLength, cpFloat stiffness, cpFloat damping);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpDampedSpringSetAnchorA(cpConstraint constraint, Vect anchorA);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpDampedSpringSetAnchorB(cpConstraint constraint, Vect anchorB);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpDampedSpringSetDamping(cpConstraint constraint, cpFloat damping);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpDampedSpringSetRestLength(cpConstraint constraint, cpFloat restLength);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpDampedSpringSetSpringForceFunc(cpConstraint constraint, cpDampedSpringForceFunc springForceFunc);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpDampedSpringSetStiffness(cpConstraint constraint, cpFloat stiffness);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpGearJoint cpGearJointAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpGearJointGetPhase(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpGearJointGetRatio(cpConstraint constraint);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpGearJoint cpGearJointInit(cpGearJoint joint, cpBody a, cpBody b, cpFloat phase, cpFloat ratio);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpGearJointNew(cpBody a, cpBody b, cpFloat phase, cpFloat ratio);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpGearJointSetPhase(cpConstraint constraint, cpFloat phase);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpGearJointSetRatio(cpConstraint constraint, cpFloat ratio);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpGrooveJoint cpGrooveJointAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpGrooveJointGetAnchorB(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpGrooveJointGetGrooveA(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpGrooveJointGetGrooveB(cpConstraint constraint);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpGrooveJoint cpGrooveJointInit(cpGrooveJoint joint, cpBody a, cpBody b, Vect groove_a, Vect groove_b, Vect anchorB);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpGrooveJointNew(cpBody a, cpBody b, Vect groove_a, Vect groove_b, Vect anchorB);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpGrooveJointSetAnchorB(cpConstraint constraint, Vect anchorB);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpGrooveJointSetGrooveA(cpConstraint constraint, Vect grooveA);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpGrooveJointSetGrooveB(cpConstraint constraint, Vect grooveB);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpHastySpaceFree(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern uint cpHastySpaceGetThreads(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpSpace cpHastySpaceNew();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpHastySpaceSetThreads(cpSpace space, uint threads);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpHastySpaceStep(cpSpace space, cpFloat dt);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpMarchHard(
+          BoundingBox bb, uint x_samples, uint y_samples, cpFloat threshold,
+          cpMarchSegmentFunc segment, IntPtr segment_data,
+          cpMarchSampleFunc sample, IntPtr sample_data
+        );
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpMarchSoft(
+          BoundingBox bb, uint x_samples, uint y_samples, cpFloat threshold,
+          cpMarchSegmentFunc segment, IntPtr segment_data,
+          cpMarchSampleFunc sample, IntPtr sample_data
+        );
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpMomentForBox2(cpFloat m, BoundingBox box);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, Vect offset);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpMomentForPoly(cpFloat m, int count, cpVectPointer verts, Vect offset, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpMomentForSegment(cpFloat m, Vect a, Vect b, cpFloat radius);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpPinJoint cpPinJointAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpPinJointGetAnchorA(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpPinJointGetAnchorB(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpPinJointGetDist(cpConstraint constraint);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpPinJoint cpPinJointInit(cpPinJoint joint, cpBody a, cpBody b, Vect anchorA, Vect anchorB);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpPinJointNew(cpBody a, cpBody b, Vect anchorA, Vect anchorB);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpPinJointSetAnchorA(cpConstraint constraint, Vect anchorA);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpPinJointSetAnchorB(cpConstraint constraint, Vect anchorB);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpPinJointSetDist(cpConstraint constraint, cpFloat dist);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpPivotJoint cpPivotJointAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpPivotJointGetAnchorA(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpPivotJointGetAnchorB(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpPivotJoint cpPivotJointInit(cpPivotJoint joint, cpBody a, cpBody b, Vect anchorA, Vect anchorB);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpPivotJointNew(cpBody a, cpBody b, Vect pivot);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpPivotJointNew2(cpBody a, cpBody b, Vect anchorA, Vect anchorB);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpPivotJointSetAnchorA(cpConstraint constraint, Vect anchorA);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpPivotJointSetAnchorB(cpConstraint constraint, Vect anchorB);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpPolyShape cpPolyShapeAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern int cpPolyShapeGetCount(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpPolyShapeGetRadius(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpPolyShapeGetVert(cpShape shape, int index);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpPolyShape cpPolyShapeInit(cpPolyShape poly, cpBody body, int count, cpVectPointer verts, Transform transform, cpFloat radius);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpPolyShape cpPolyShapeInitRaw(cpPolyShape poly, cpBody body, int count, cpVectPointer verts, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpShape cpPolyShapeNew(cpBody body, int count, cpVectPointer verts, Transform transform, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpShape cpPolyShapeNewRaw(cpBody body, int count, cpVectPointer verts, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpPolyShapeSetRadius(cpShape shape, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpPolyShapeSetVerts(cpShape shape, int count, cpVectPointer verts, Transform transform);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpPolyShapeSetVertsRaw(cpShape shape, int count, cpVectPointer verts);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpPolylineSet cpPolylineConvexDecomposition(cpPolyline line, cpFloat tol);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpPolylineFree(cpPolyline line);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpPolyline cpPolylineSimplifyCurves(cpPolyline line, cpFloat tol);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpPolylineSet cpPolylineSetAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpPolylineSetCollectSegment(Vect v0, Vect v1, cpPolylineSet lines);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern void cpPolylineSetDestroy(cpPolylineSet set, cpBool freePolylines);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpPolylineSetFree(cpPolylineSet set, cpBool freePolylines);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpPolylineSet cpPolylineSetInit(cpPolylineSet set);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpPolylineSet cpPolylineSetNew();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpPolyline cpPolylineSimplifyVertexes(cpPolyline line, cpFloat tol);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpPolyline cpPolylineToConvexHull(cpPolyline line, cpFloat tol);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpRatchetJoint cpRatchetJointAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpRatchetJointGetAngle(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpRatchetJointGetPhase(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpRatchetJointGetRatchet(cpConstraint constraint);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpRatchetJoint cpRatchetJointInit(cpRatchetJoint joint, cpBody a, cpBody b, cpFloat phase, cpFloat ratchet);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpRatchetJointNew(cpBody a, cpBody b, cpFloat phase, cpFloat ratchet);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpRatchetJointSetAngle(cpConstraint constraint, cpFloat angle);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpRatchetJointSetPhase(cpConstraint constraint, cpFloat phase);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpRatchetJointSetRatchet(cpConstraint constraint, cpFloat ratchet);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpRotaryLimitJoint cpRotaryLimitJointAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpRotaryLimitJointGetMax(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpRotaryLimitJointGetMin(cpConstraint constraint);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpRotaryLimitJoint cpRotaryLimitJointInit(cpRotaryLimitJoint joint, cpBody a, cpBody b, cpFloat min, cpFloat max);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpRotaryLimitJointNew(cpBody a, cpBody b, cpFloat min, cpFloat max);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpRotaryLimitJointSetMax(cpConstraint constraint, cpFloat max);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpRotaryLimitJointSetMin(cpConstraint constraint, cpFloat min);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSegmentShape cpSegmentShapeAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpSegmentShapeGetA(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpSegmentShapeGetB(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpSegmentShapeGetNormal(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpSegmentShapeGetRadius(cpShape shape);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSegmentShape cpSegmentShapeInit(cpSegmentShape seg, cpBody body, Vect a, Vect b, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpShape cpSegmentShapeNew(cpBody body, Vect a, Vect b, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSegmentShapeSetEndpoints(cpShape shape, Vect a, Vect b);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSegmentShapeSetNeighbors(cpShape shape, Vect prev, Vect next);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSegmentShapeSetRadius(cpShape shape, cpFloat radius);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern BoundingBox cpShapeCacheBB(cpShape shape);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern void cpShapeDestroy(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpShapeFree(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpShapeGetArea(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern BoundingBox cpShapeGetBB(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBody cpShapeGetBody(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpShapeGetCenterOfGravity(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpCollisionType cpShapeGetCollisionType(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpShapeGetDensity(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpShapeGetElasticity(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpShapeGetFriction(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpShapeGetMass(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpShapeGetMoment(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpShapeGetSensor(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpSpace cpShapeGetSpace(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpShapeGetSurfaceVelocity(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpDataPointer cpShapeGetUserData(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern ShapeFilter cpShapeGetFilter(cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpShapePointQuery(cpShape shape, Vect p, ref cpPointQueryInfo output);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpShapeSegmentQuery(cpShape shape, Vect a, Vect b, cpFloat radius, ref cpSegmentQueryInfo info);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpShapeSetBody(cpShape shape, cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpShapeSetCollisionType(cpShape shape, cpCollisionType collisionType);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpShapeSetDensity(cpShape shape, cpFloat density);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpShapeSetElasticity(cpShape shape, cpFloat elasticity);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpShapeSetFriction(cpShape shape, cpFloat friction);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpShapeSetMass(cpShape shape, cpFloat mass);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpShapeSetSensor(cpShape shape, cpBool sensor);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpShapeSetSurfaceVelocity(cpShape shape, Vect surfaceVelocity);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpShapeSetUserData(cpShape shape, cpDataPointer userData);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpShapeSetFilter(cpShape shape, ShapeFilter filter);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern BoundingBox cpShapeUpdate(cpShape shape, Transform transform);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpContactPointSet cpShapesCollide(cpShape a, cpShape b);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSimpleMotor cpSimpleMotorAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpSimpleMotorGetRate(cpConstraint constraint);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSimpleMotor cpSimpleMotorInit(cpSimpleMotor joint, cpBody a, cpBody b, cpFloat rate);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpSimpleMotorNew(cpBody a, cpBody b, cpFloat rate);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSimpleMotorSetRate(cpConstraint constraint, cpFloat rate);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSlideJoint cpSlideJointAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpSlideJointGetAnchorA(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpSlideJointGetAnchorB(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpSlideJointGetMax(cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpSlideJointGetMin(cpConstraint constraint);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSlideJoint cpSlideJointInit(cpSlideJoint joint, cpBody a, cpBody b, Vect anchorA, Vect anchorB, cpFloat min, cpFloat max);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpSlideJointNew(cpBody a, cpBody b, Vect anchorA, Vect anchorB, cpFloat min, cpFloat max);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSlideJointSetAnchorA(cpConstraint constraint, Vect anchorA);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSlideJointSetAnchorB(cpConstraint constraint, Vect anchorB);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSlideJointSetMax(cpConstraint constraint, cpFloat max);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSlideJointSetMin(cpConstraint constraint, cpFloat min);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBody cpSpaceAddBody(cpSpace space, cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpCollisionHandlerPointer cpSpaceAddCollisionHandler(cpSpace space, cpCollisionType a, cpCollisionType b);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpConstraint cpSpaceAddConstraint(cpSpace space, cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpCollisionHandlerPointer cpSpaceAddDefaultCollisionHandler(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpSpaceAddPostStepCallback(cpSpace space, cpPostStepFunc func, IntPtr key, IntPtr data);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpShape cpSpaceAddShape(cpSpace space, cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpCollisionHandlerPointer cpSpaceAddWildcardHandler(cpSpace space, cpCollisionType type);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSpace cpSpaceAlloc();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceBBQuery(cpSpace space, BoundingBox bb, ShapeFilter filter, cpSpaceBBQueryFunc func, IntPtr data);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpSpaceContainsShape(cpSpace space, cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpSpaceContainsBody(cpSpace space, cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpSpaceContainsConstraint(cpSpace space, cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceDebugDraw(cpSpace space, cpSpaceDebugDrawOptionsPointer options);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern void cpSpaceDestroy(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceEachBody(cpSpace space, cpSpaceBodyIteratorFunc func, IntPtr data);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceEachConstraint(cpSpace space, cpSpaceConstraintIteratorFunc func, IntPtr data);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern int cpSpaceGetBodyCount(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceGetBodiesUserDataArray(cpSpace space, IntPtr userDataArray);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern int cpSpaceGetDynamicBodyCount(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceGetDynamicBodiesUserDataArray(cpSpace space, IntPtr userDataArray);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceEachShape(cpSpace space, cpSpaceShapeIteratorFunc func, IntPtr data);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceFree(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpSpaceGetCollisionBias(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpTimestamp cpSpaceGetCollisionPersistence(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpSpaceGetCollisionSlop(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpSpaceGetCurrentTimeStep(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpSpaceGetDamping(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern Vect cpSpaceGetGravity(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpSpaceGetIdleSpeedThreshold(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern int cpSpaceGetIterations(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpFloat cpSpaceGetSleepTimeThreshold(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBody cpSpaceGetStaticBody(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpDataPointer cpSpaceGetUserData(cpSpace space);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSpaceHash cpSpaceHashAlloc();
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSpatialIndex cpSpaceHashInit(cpSpaceHash hash, cpFloat celldim, int numcells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSpatialIndex cpSpaceHashNew(cpFloat celldim, int cells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern void cpSpaceHashResize(cpSpaceHash hash, cpFloat celldim, int numcells);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSpace cpSpaceInit(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpSpaceIsLocked(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpSpace cpSpaceNew();
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpacePointQuery(cpSpace space, Vect point, cpFloat maxDistance, ShapeFilter filter, cpSpacePointQueryFunc func, IntPtr data);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpShape cpSpacePointQueryNearest(cpSpace space, Vect point, cpFloat maxDistance, ShapeFilter filter, ref cpPointQueryInfo output);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceReindexShape(cpSpace space, cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceReindexShapesForBody(cpSpace space, cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceReindexStatic(cpSpace space);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceRemoveBody(cpSpace space, cpBody body);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceRemoveConstraint(cpSpace space, cpConstraint constraint);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceRemoveShape(cpSpace space, cpShape shape);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceSegmentQuery(cpSpace space, Vect start, Vect end, cpFloat radius, ShapeFilter filter, cpSpaceSegmentQueryFunc func, IntPtr data);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpShape cpSpaceSegmentQueryFirst(cpSpace space, Vect start, Vect end, cpFloat radius, ShapeFilter filter, ref cpSegmentQueryInfo output);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceSetCollisionBias(cpSpace space, cpFloat collisionBias);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceSetCollisionPersistence(cpSpace space, cpTimestamp collisionPersistence);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceSetCollisionSlop(cpSpace space, cpFloat collisionSlop);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceSetDamping(cpSpace space, cpFloat damping);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceSetGravity(cpSpace space, Vect gravity);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceSetIdleSpeedThreshold(cpSpace space, cpFloat idleSpeedThreshold);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceSetIterations(cpSpace space, int iterations);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceSetSleepTimeThreshold(cpSpace space, cpFloat sleepTimeThreshold);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceSetUserData(cpSpace space, cpDataPointer userData);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern cpBool cpSpaceShapeQuery(cpSpace space, cpShape shape, cpSpaceShapeQueryFunc func, IntPtr data);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceStep(cpSpace space, cpFloat dt);
+
+        [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void cpSpaceUseSpatialHash(cpSpace space, cpFloat dim, int count);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern void cpSpatialIndexCollideStatic(cpSpatialIndex dynamicIndex, cpSpatialIndex staticIndex, cpSpatialIndexQueryFunc func, IntPtr data);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern void cpSpatialIndexFree(cpSpatialIndex index);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSweep1D cpSweep1DAlloc();
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSpatialIndex cpSweep1DInit(cpSweep1D sweep, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex);
+
+        //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)]
+        //internal static extern cpSpatialIndex cpSweep1DNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex);
+
+#pragma warning restore IDE1006 // Naming Styles
+
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/PostStepCallbackInfo.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/PostStepCallbackInfo.cs
new file mode 100644 (file)
index 0000000..05cbdc1
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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.Collections.Generic;
+using System.Text;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// This class stores the data for the post-step callback.
+    /// </summary>
+    internal class PostStepCallbackInfo
+    {
+        Action<Space, object, object> callback;
+        object data;
+
+        /// <summary>
+        /// Creates an instance of the PostStepCallbackInfo class.
+        /// </summary>
+        /// <param name="c">The post-step callback.</param>
+        /// <param name="d">The data for the callback.</param>
+        public PostStepCallbackInfo(Action<Space, object, object> c, object d)
+        {
+            callback = c;
+            data = d;
+        }
+
+        /// <summary>
+        /// The post-step callback.
+        /// </summary>
+        public Action<Space, object, object> Callback => callback;
+
+        /// <summary>
+        /// The data for the callback.
+        /// </summary>
+        public object Data => data;
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpCollisionHandler.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpCollisionHandler.cs
new file mode 100644 (file)
index 0000000..22a266e
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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.Runtime.InteropServices;
+using cpCollisionFunction = System.IntPtr;
+using cpCollisionHandlerPointer = System.IntPtr;
+using cpCollisionType = System.UIntPtr;
+using cpDataPointer = System.IntPtr;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Struct that holds function callback pointers to configure custom collision handling.
+    /// Collision handlers have a pair of types;
+    /// when a collision occurs between two shapes that have these types, the collision handler functions are triggered.
+    /// </summary>
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct cpCollisionHandler
+    {
+        /// <summary>
+        /// Collision type identifier of the first shape that this handler recognizes.
+        /// In the collision handler callback, the shape with this type will be the first argument. Read only.
+        /// </summary>
+        public cpCollisionType typeA;
+
+        /// <summary>
+        /// Collision type identifier of the second shape that this handler recognizes.
+        /// In the collision handler callback, the shape with this type will be the second argument. Read only.
+        /// </summary>
+        public cpCollisionType typeB;
+
+        /// <summary>
+        /// This function is called when two shapes with types that match this collision handler begin colliding.
+        /// </summary>
+        public cpCollisionFunction beginFunction;
+
+        /// <summary>
+        /// This function is called each step when two shapes with types that match this collision handler are colliding.
+        /// It's called before the collision solver runs so that you can affect a collision's outcome.
+        /// </summary>
+        public cpCollisionFunction preSolveFunction;
+
+        /// <summary>
+        /// This function is called each step when two shapes with types that match this collision handler are colliding.
+        /// It's called after the collision solver runs so that you can read back information about the collision to trigger events in your game.
+        /// </summary>
+        public cpCollisionFunction postSolveFunction;
+
+        /// <summary>
+        /// This function is called when two shapes with types that match this collision handler stop colliding.
+        /// </summary>
+        public cpCollisionFunction separateFunction;
+
+        /// <summary>
+        /// This is a user definable context pointer that is passed to all of the collision handler functions.
+        /// </summary>
+        public cpDataPointer userData;
+
+        public static cpCollisionHandler FromHandle(cpCollisionHandlerPointer handle)
+        {
+            return Marshal.PtrToStructure<cpCollisionHandler>(handle);
+        }
+
+        internal static void ToPointer(cpCollisionHandler handler, cpCollisionFunction handle)
+        {
+            Marshal.StructureToPtr(handler, handle, false);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPoint.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPoint.cs
new file mode 100644 (file)
index 0000000..ed3f8ef
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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.Runtime.InteropServices;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// The array of contact points.
+    /// </summary>
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct cpContactPoint
+    {
+        /// <summary>
+        /// The position of the contact on the surface of the first shape.
+        /// </summary>
+        public Vect pointA;
+
+        /// <summary>
+        /// The position of the contact on the surface of the second shape.
+        /// </summary>
+        public Vect pointB;
+        
+        /// <summary>
+        /// Penetration distance of the two shapes. Overlapping means it will be negative.
+        /// </summary>
+        public double distance;
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPointSet.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPointSet.cs
new file mode 100644 (file)
index 0000000..82c0d8f
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.Runtime.InteropServices;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// A struct that wraps up the important collision data for an arbiter.
+    /// </summary>
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct cpContactPointSet
+    {
+        /// <summary>
+        /// The number of contact points in the set.
+        /// </summary>
+        public int count;
+        
+        /// <summary>
+        /// The normal of the collision.
+        /// </summary>
+        public Vect normal;
+
+        /// <summary>
+        /// The first contact point.
+        /// </summary>
+        public cpContactPoint points0;
+
+        /// <summary>
+        /// The second contact point.
+        /// </summary>
+        public cpContactPoint points1;
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPointQueryInfo.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPointQueryInfo.cs
new file mode 100644 (file)
index 0000000..fc9bfb5
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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.Runtime.InteropServices;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Point query info.
+    /// </summary>
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct cpPointQueryInfo
+    {
+        /// <summary>
+        /// The nearest shape, null if no shape was within range.
+        /// </summary>
+        public IntPtr shape;
+
+        /// <summary>
+        /// The closest point on the shape's surface. (in world space coordinates)
+        /// </summary>
+        public Vect point;
+
+        /// <summary>
+        /// The distance to the point. The distance is negative if the point is inside the shape.
+        /// </summary>
+        public double distance;
+
+        /// <summary>
+        /// The gradient of the signed distance function.
+        /// </summary>
+        public Vect gradient;
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPolyline.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPolyline.cs
new file mode 100644 (file)
index 0000000..0278215
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.Runtime.InteropServices;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Polylines are just arrays of vertices.
+    /// They are looped if the first vertex is equal to the last.
+    /// </summary>
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct cpPolyline
+    {
+        /// <summary>
+        /// The number of vertices.
+        /// </summary>
+        public int count;
+
+        /// <summary>
+        /// The capacity of the vertex array.
+        /// </summary>
+        public int capacity;
+        
+        /// <summary>
+        /// The vertex array that stores the vertices.
+        /// </summary>
+        public IntPtr verts;
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSegmentQueryInfo.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSegmentQueryInfo.cs
new file mode 100644 (file)
index 0000000..2804746
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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.Runtime.InteropServices;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Segment query info
+    /// </summary>
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct cpSegmentQueryInfo
+    {
+        /// <summary>
+        /// The shape that was hit, or null if no collision occured.
+        /// </summary>
+        public IntPtr shape;
+
+        /// <summary>
+        /// The point of impact.
+        /// </summary>
+        public Vect point;
+
+        /// <summary>
+        /// The normal of the surface hit.
+        /// </summary>
+        public Vect normal;
+
+        /// <summary>
+        /// The normalized distance along the query segment in the range [0, 1].
+        /// </summary>
+        public double alpha;
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs
new file mode 100644 (file)
index 0000000..18e7fd7
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 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.Runtime.InteropServices;
+using cpDataPointer = System.IntPtr;
+using cpShape = System.IntPtr;
+using cpSpaceDebugDrawCircleImpl = System.IntPtr;
+using cpSpaceDebugDrawColorForShapeImpl = System.IntPtr;
+using cpSpaceDebugDrawDotImpl = System.IntPtr;
+using cpSpaceDebugDrawFatSegmentImpl = System.IntPtr;
+using cpSpaceDebugDrawFlags = System.Int32;
+using cpSpaceDebugDrawPolygonImpl = System.IntPtr;
+using cpSpaceDebugDrawSegmentImpl = System.IntPtr;
+using cpVertPointer = System.IntPtr;
+using voidptr_t = System.IntPtr;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+using ObjCRuntime;
+#endif
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Struct used with Space.DebugDraw() containing drawing callbacks and other drawing settings.
+    /// </summary>
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct cpSpaceDebugDrawOptions
+    {
+        /// <summary>
+        /// Function that will be invoked to draw circles.
+        /// </summary>
+        cpSpaceDebugDrawCircleImpl drawCircle;
+
+        /// <summary>
+        /// Function that will be invoked to draw line segments.
+        /// </summary>
+        cpSpaceDebugDrawSegmentImpl drawSegment;
+
+        /// <summary>
+        /// Function that will be invoked to draw thick line segments.
+        /// </summary>
+        cpSpaceDebugDrawFatSegmentImpl drawFatSegment;
+
+        /// <summary>
+        /// Function that will be invoked to draw convex polygons.
+        /// </summary>
+        cpSpaceDebugDrawPolygonImpl drawPolygon;
+
+        /// <summary>
+        /// Function that will be invoked to draw dots.
+        /// </summary>
+        cpSpaceDebugDrawDotImpl drawDot;
+
+        /// <summary>
+        /// Flags that request which things to draw (collision shapes, constraints, contact points).
+        /// </summary>
+        cpSpaceDebugDrawFlags flags;
+
+        /// <summary>
+        /// Outline color passed to the drawing function.
+        /// </summary>
+        DebugColor shapeOutlineColor;
+
+        /// <summary>
+        /// Function that decides what fill color to draw shapes using.
+        /// </summary>
+        cpSpaceDebugDrawColorForShapeImpl colorForShape;
+
+        /// <summary>
+        /// Color passed to drawing functions for constraints.
+        /// </summary>
+        DebugColor constraintColor;
+
+        /// <summary>
+        /// Color passed to drawing functions for collision points.
+        /// </summary>
+        DebugColor collisionPointColor;
+
+        /// <summary>
+        /// User defined context pointer passed to all of the callback functions as the 'data' argument.
+        /// </summary>
+        cpDataPointer data;
+
+        private IntPtr ToPointer()
+        {
+            IntPtr drawOptionsPtr = NativeInterop.AllocStructure<cpSpaceDebugDrawOptions>();
+
+            Marshal.StructureToPtr<cpSpaceDebugDrawOptions>(this, drawOptionsPtr, false);
+            return drawOptionsPtr;
+        }
+
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpaceDebugDrawCircleImpl))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void SpaceDebugDrawCircleCallback(Vect pos, double angle, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data)
+        {
+            IDebugDraw debugDraw = NativeInterop.FromIntPtr<IDebugDraw>(data);
+
+            debugDraw.DrawCircle(pos, angle, radius, outlineColor, fillColor);
+        }
+
+        private static SpaceDebugDrawCircleImpl spaceDebugDrawCircleCallback = SpaceDebugDrawCircleCallback;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpaceDebugDrawSegmentImpl))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void SpaceDebugDrawSegmentCallback(Vect a, Vect b, DebugColor color, voidptr_t data)
+        {
+            IDebugDraw debugDraw = NativeInterop.FromIntPtr<IDebugDraw>(data);
+
+            debugDraw.DrawSegment(a, b, color);
+        }
+
+        private static SpaceDebugDrawSegmentImpl spaceDebugDrawSegmentCallback = SpaceDebugDrawSegmentCallback;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpaceDebugDrawFatSegmentImpl))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void SpaceDebugDrawFatSegmentCallback(Vect a, Vect b, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data)
+        {
+            IDebugDraw debugDraw = NativeInterop.FromIntPtr<IDebugDraw>(data);
+
+            debugDraw.DrawFatSegment(a, b, radius, outlineColor, fillColor);
+        }
+
+        private static SpaceDebugDrawFatSegmentImpl spaceDebugDrawFatSegmentCallback = SpaceDebugDrawFatSegmentCallback;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpaceDebugDrawPolygonImpl))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void SpaceDebugDrawPolygonCallback(int count, cpVertPointer verts, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data)
+        {
+            IDebugDraw debugDraw = NativeInterop.FromIntPtr<IDebugDraw>(data);
+
+            Vect[] vectors = NativeInterop.PtrToStructureArray<Vect>(verts, count);
+
+            debugDraw.DrawPolygon(vectors, radius, outlineColor, fillColor);
+        }
+
+        private static SpaceDebugDrawPolygonImpl spaceDebugDrawPolygonCallback = SpaceDebugDrawPolygonCallback;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpaceDebugDrawDotImpl))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void SpaceDebugDrawDotCallback(double size, Vect pos, DebugColor color, voidptr_t data)
+        {
+            IDebugDraw debugDraw = NativeInterop.FromIntPtr<IDebugDraw>(data);
+
+            debugDraw.DrawDot(size, pos, color);
+        }
+
+        private static SpaceDebugDrawDotImpl spaceDebugDrawDotCallback = SpaceDebugDrawDotCallback;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpaceDebugDrawColorForShapeImpl))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static DebugColor SpaceDebugDrawColorForShapeCallback(cpShape handleShape, voidptr_t data)
+        {
+            IDebugDraw debugDraw = NativeInterop.FromIntPtr<IDebugDraw>(data);
+            var shape = Shape.FromHandle(handleShape);
+
+            return debugDraw.ColorForShape(shape);
+        }
+
+        private static SpaceDebugDrawColorForShapeImpl spaceDebugDrawColorForShapeCallback = SpaceDebugDrawColorForShapeCallback;
+
+
+        public IntPtr AcquireDebugDrawOptions(IDebugDraw debugDraw, DebugDrawFlags flags, DebugDrawColors colors)
+        {
+            this.flags = (int)flags;
+            collisionPointColor = colors.CollisionPoint;
+            constraintColor = colors.Constraint;
+            shapeOutlineColor = colors.ShapeOutline;
+
+            drawCircle = spaceDebugDrawCircleCallback.ToFunctionPointer();
+            drawSegment = spaceDebugDrawSegmentCallback.ToFunctionPointer();
+            drawFatSegment = spaceDebugDrawFatSegmentCallback.ToFunctionPointer();
+            drawPolygon = spaceDebugDrawPolygonCallback.ToFunctionPointer();
+            drawDot = spaceDebugDrawDotCallback.ToFunctionPointer();
+            colorForShape = spaceDebugDrawColorForShapeCallback.ToFunctionPointer();
+
+            data = NativeInterop.RegisterHandle(debugDraw);
+
+            return ToPointer();
+        }
+
+        public void ReleaseDebugDrawOptions(IntPtr debugDrawOptionsPointer)
+        {
+            NativeInterop.ReleaseHandle(data);
+            NativeInterop.FreeStructure(debugDrawOptionsPointer);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Arbiter.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Arbiter.cs
new file mode 100644 (file)
index 0000000..0a7a05a
--- /dev/null
@@ -0,0 +1,387 @@
+/*
+ * 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.Collections.Generic;
+using System.ComponentModel;
+using cpArbiter = System.IntPtr;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// The <see cref="Arbiter"/> object encapsulates a pair of colliding shapes and all of the data
+    /// about their collision.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public struct Arbiter : IEquatable<Arbiter>
+    {
+#pragma warning disable IDE0032
+        readonly cpArbiter arbiter;
+#pragma warning restore IDE0032
+
+        /// <summary>
+        /// Native handle of <see cref="Arbiter"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public cpArbiter Handle => arbiter;
+
+        internal Arbiter(cpArbiter handle)
+        {
+            arbiter = handle;
+        }
+
+        /// <summary>
+        /// The restitution (elasticity) that will be applied to the pair of colliding objects.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Restitution
+        {
+            get => NativeMethods.cpArbiterGetRestitution(arbiter);
+            set => NativeMethods.cpArbiterSetRestitution(arbiter, value);
+        }
+
+        /// <summary>
+        /// Friction coefficient that will be applied to the pair of colliding objects.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Friction
+        {
+            get => NativeMethods.cpArbiterGetFriction(arbiter);
+            set => NativeMethods.cpArbiterSetFriction(arbiter, value);
+        }
+
+        /// <summary>
+        /// The relative surface velocity of the two shapes in contact.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect SurfaceVelocity
+        {
+            get => NativeMethods.cpArbiterGetSurfaceVelocity(arbiter);
+            set => NativeMethods.cpArbiterSetSurfaceVelocity(arbiter, value);
+        }
+
+        /// <summary>
+        /// Calculate the total impulse including the friction that was applied by this arbiter.
+        /// This function should only be called from a post-solve, post-step or cpBodyEachArbiter
+        /// callback.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect TotalImpulse => NativeMethods.cpArbiterTotalImpulse(arbiter);
+
+        /// <summary>
+        /// Calculate the amount of energy lost in a collision including static, but not dynamic friction.
+        /// This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double TotalKE => NativeMethods.cpArbiterTotalKE(arbiter);
+
+        /// <summary>
+        /// Mark a collision pair to be ignored until the two objects separate. Pre-solve and
+        /// post-solve callbacks will not be called, but the separate callback will be called.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Ignore() => NativeMethods.cpArbiterIgnore(arbiter) != 0;
+
+        /// <summary>
+        /// Return the colliding shapes involved for this arbiter. The order of their
+        /// <see cref="Shape.CollisionType"/> values will match the order set when the collision
+        /// handler was registered.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void GetShapes(out Shape a, out Shape b)
+        {
+            IntPtr ptrA;
+            IntPtr ptrB;
+
+            NativeMethods.cpArbiterGetShapes(arbiter, out ptrA, out ptrB);
+
+            a = Shape.FromHandle(ptrA);
+            b = Shape.FromHandle(ptrB);
+        }
+
+        /// <summary>
+        /// Return the colliding bodies involved for this arbiter. The order of the
+        /// <see cref="Shape.CollisionType"/> values the bodies are associated with will match the
+        /// order set when the collision handler was registered.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void GetBodies(out Body a, out Body b)
+        {
+            IntPtr ptrA;
+            IntPtr ptrB;
+
+            NativeMethods.cpArbiterGetBodies(arbiter, out ptrA, out ptrB);
+
+            a = Body.FromHandle(ptrA);
+            b = Body.FromHandle(ptrB);
+        }
+
+        /// <summary>
+        /// The contact point set for an arbiter. This can be a very powerful feature, but use it
+        /// with caution!
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ContactPointSet ContactPointSet
+        {
+            get
+            {
+                cpContactPointSet pointSet = NativeMethods.cpArbiterGetContactPointSet(arbiter);
+                return ContactPointSet.FromContactPointSet(pointSet);
+            }
+            set
+            {
+                cpContactPointSet pointSet = value.ToContactPointSet();
+                NativeMethods.cpArbiterSetContactPointSet(arbiter, ref pointSet);
+            }
+        }
+
+        /// <summary>
+        /// Arbitrary user data.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object Data
+        {
+            get
+            {
+                IntPtr handle = NativeMethods.cpArbiterGetUserData(arbiter);
+
+                if (handle == IntPtr.Zero)
+                {
+                    return null;
+                }
+
+                return NativeInterop.FromIntPtrAndFree<object>(handle);
+            }
+            set
+            {
+                var gcHandle = IntPtr.Zero;
+
+                if (value != null)
+                {
+                    gcHandle = NativeInterop.RegisterHandle(value);
+                }
+
+                NativeMethods.cpArbiterSetUserData(arbiter, gcHandle);
+            }
+        }
+
+        /// <summary>
+        /// Returns true if this is the first step a pair of objects started colliding.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsFirstContact => NativeMethods.cpArbiterIsFirstContact(arbiter) != 0;
+
+        /// <summary>
+        /// Returns true if the separate callback is due to a shape being removed from the space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsRemoval => NativeMethods.cpArbiterIsRemoval(arbiter) != 0;
+
+        /// <summary>
+        /// Get the number of contact points for this arbiter.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int Count => NativeMethods.cpArbiterGetCount(arbiter);
+
+        /// <summary>
+        /// Get the normal of the collision.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Normal => NativeMethods.cpArbiterGetNormal(arbiter);
+
+        /// <summary>
+        /// Get the position of the <paramref name="i"/>th contact point on the surface of the first
+        /// shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect GetPointA(int i)
+        {
+            return NativeMethods.cpArbiterGetPointA(arbiter, i);
+        }
+
+        /// <summary>
+        /// Get the position of the <paramref name="i"/>th contact point on the surface of the
+        /// second shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect GetPointB(int i)
+        {
+            return NativeMethods.cpArbiterGetPointB(arbiter, i);
+        }
+
+        /// <summary>
+        /// Get the depth (amount of overlap) of the <paramref name="i"/>th contact point.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double GetDepth(int i)
+        {
+            return NativeMethods.cpArbiterGetDepth(arbiter, i);
+        }
+
+        /// <summary>
+        /// If you want a custom callback to invoke the wildcard callback for the first collision
+        /// type, you must call this function explicitly. You must decide how to handle the
+        /// wildcard's return value since it may disagree with the other wildcard handler's return
+        /// value or your own.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void CallWildcardBeginA(Space space)
+        {
+            NativeMethods.cpArbiterCallWildcardBeginA(arbiter, space.Handle);
+        }
+
+        /// <summary>
+        /// If you want a custom callback to invoke the wildcard callback for the second collision
+        /// type, you must call this function explicitly. You must decide how to handle the
+        /// wildcard's return value since it may disagree with the other wildcard handler's return
+        /// value or your own.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void CallWildcardBeginB(Space space)
+        {
+            NativeMethods.cpArbiterCallWildcardBeginB(arbiter, space.Handle);
+        }
+
+        /// <summary>
+        /// If you want a custom callback to invoke the wildcard callback for the first collision
+        /// type, you must call this function explicitly. You must decide how to handle the
+        /// wildcard's return value since it may disagree with the other wildcard handler's return
+        /// value or your own.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool CallWildcardPreSolveA(Space space)
+        {
+            return NativeMethods.cpArbiterCallWildcardPreSolveA(arbiter, space.Handle) != 0;
+        }
+
+        /// <summary>
+        /// If you want a custom callback to invoke the wildcard callback for the second collision
+        /// type, you must call this function explicitly. You must decide how to handle the
+        /// wildcard's return value since it may disagree with the other wildcard handler's return
+        /// value or your own.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool CallWildcardPreSolveB(Space space)
+        {
+            return NativeMethods.cpArbiterCallWildcardPreSolveB(arbiter, space.Handle) != 0;
+        }
+
+        /// <summary>
+        /// If you want a custom callback to invoke the wildcard callback for the first collision
+        /// type, you must call this function explicitly.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void CallWildcardPostSolveA(Space space)
+        {
+            NativeMethods.cpArbiterCallWildcardPostSolveA(arbiter, space.Handle);
+        }
+
+        /// <summary>
+        /// If you want a custom callback to invoke the wildcard callback for the second collision
+        /// type, you must call this function explicitly.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void CallWildcardPostSolveB(Space space)
+        {
+            NativeMethods.cpArbiterCallWildcardPostSolveB(arbiter, space.Handle);
+        }
+
+        /// <summary>
+        /// If you want a custom callback to invoke the wildcard callback for the first collision
+        /// type, you must call this function explicitly.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void CallWildcardSeparateA(Space space)
+        {
+            NativeMethods.cpArbiterCallWildcardSeparateA(arbiter, space.Handle);
+        }
+
+        /// <summary>
+        /// If you want a custom callback to invoke the wildcard callback for the second collision
+        /// type, you must call this function explicitly.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void CallWildcardSeparateB(Space space)
+        {
+            NativeMethods.cpArbiterCallWildcardSeparateB(arbiter, space.Handle);
+        }
+
+        /// <summary>
+        /// Return true if an arbiter is equal to another.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Equals(Arbiter other)
+        {
+            return arbiter == other.arbiter;
+        }
+
+        /// <summary>
+        /// Check if an arbiter is equal to the given object.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override bool Equals(object obj)
+        {
+            var other = obj as Arbiter?;
+
+            if (other == null)
+                return false;
+
+            return Equals(other.Value);
+        }
+
+        /// <summary>
+        /// Return the arbiter's handle prefixed by 'Handle: '.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override string ToString()
+        {
+            return $"Handle: {arbiter}";
+        }
+
+        /// <summary>
+        /// Get the hash code.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override int GetHashCode()
+        {
+            return 932982278 + EqualityComparer<cpArbiter>.Default.GetHashCode(arbiter);
+        }
+
+        /// <summary>
+        /// Check if one arbiter is equal to another.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator ==(Arbiter left, Arbiter right)
+        {
+            return left.Equals(right);
+        }
+
+        /// <summary>
+        /// Check if one arbiter is inequal to another.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator !=(Arbiter left, Arbiter right)
+        {
+            return !(left == right);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/AutoGeometry.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/AutoGeometry.cs
new file mode 100644 (file)
index 0000000..2a8ba0b
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+using ObjCRuntime;
+#endif
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// This class contains functions for automatic generation of geometry.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    internal static class AutoGeometry
+    {
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(MarchSegmentFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void MarchSegmentFunctionCallback(Vect v0, Vect v1, IntPtr data)
+        {
+            var marchData = (MarchData)GCHandle.FromIntPtr(data).Target;
+            marchData.SegmentFunction(v0, v1, marchData.SegmentData);
+        }
+
+        private static MarchSegmentFunction segmentFunctionCallback = MarchSegmentFunctionCallback;
+
+#if (__IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__)
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(MarchSampleFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static double MarchSampleFunctionCallBack(Vect point, IntPtr data)
+        {
+            var marchData = (MarchData)GCHandle.FromIntPtr(data).Target;
+            return marchData.SampleFunction(point, marchData.SampleData);
+        }
+
+        private static MarchSampleFunction sampleFunctionCallBack = MarchSampleFunctionCallBack;
+
+        /// <summary>
+        /// Trace an aliased curve of an image along a particular threshold. The given number of
+        /// samples will be taken and spread across the bounding box area using the sampling
+        /// function and context. The segment function will be called for each segment detected that
+        /// lies along the density contour for the threshold. Only the SegmentData and SampleData are
+        /// optional.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void MarchHard(MarchData data)
+        {
+            var gcHandle = GCHandle.Alloc(data);
+            IntPtr handlePtr = GCHandle.ToIntPtr(gcHandle);
+
+            NativeMethods.cpMarchHard(
+                data.BoundingBox,
+                (uint)data.XSamples,
+                (uint)data.YSamples,
+                data.Threshold,
+                segmentFunctionCallback.ToFunctionPointer(),
+                handlePtr,
+                sampleFunctionCallBack.ToFunctionPointer(),
+                handlePtr);
+
+            gcHandle.Free();
+        }
+
+        /// <summary>
+        /// Trace an anti-aliased contour of an image along a particular threshold. The given number
+        /// of samples will be taken and spread across the bounding box area using the sampling
+        /// function and context. The segment function will be called for each segment detected that
+        /// lies along the density contour for the threshold.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void MarchSoft(MarchData data)
+        {
+            var gcHandle = GCHandle.Alloc(data);
+            IntPtr handlePtr = GCHandle.ToIntPtr(gcHandle);
+
+            NativeMethods.cpMarchSoft(
+                data.BoundingBox,
+                (uint)data.XSamples,
+                (uint)data.YSamples,
+                data.Threshold,
+                segmentFunctionCallback.ToFunctionPointer(),
+                handlePtr,
+                sampleFunctionCallBack.ToFunctionPointer(),
+                handlePtr);
+
+            gcHandle.Free();
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs
new file mode 100644 (file)
index 0000000..850b208
--- /dev/null
@@ -0,0 +1,767 @@
+/*
+ * 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;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+using ObjCRuntime;
+#endif
+
+using cpBody = System.IntPtr;
+using cpArbiter = System.IntPtr;
+using cpConstraint = System.IntPtr;
+using cpShape = System.IntPtr;
+using cpSpace = System.IntPtr;
+using cpDataPointer = System.IntPtr;
+using System.Diagnostics;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Mass and moment are ignored when <see cref="BodyType"/> is <see cref="BodyType.Kinematic"/>
+    /// or <see cref="BodyType.Static"/>. Guessing the mass for a body is usually fine, but guessing
+    /// a moment of inertia can lead to a very poor simulation. It’s recommended to use Chipmunk’s
+    /// moment-calculating functions to estimate the moment for you.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class Body : IDisposable
+    {
+#pragma warning disable IDE0032
+        private readonly cpBody body;
+#pragma warning restore IDE0032
+
+        /// <summary>
+        /// The native handle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public cpBody Handle => body;
+
+        /// <summary>
+        /// Create a Dynamic Body with no mass and no moment.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Body()
+            : this(BodyType.Dynamic)
+        {
+        }
+
+        internal Body(cpBody handle)
+        {
+            body = handle;
+            RegisterUserData();
+        }
+
+        /// <summary>
+        ///  Create a <see cref="Body"/> of the given <see cref="BodyType"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Body(BodyType type)
+        {
+            body = InitializeBody(type);
+            RegisterUserData();
+        }
+
+        /// <summary>
+        /// Creates a body with the given mass and moment.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Body(double mass, double moment) : this(mass, moment, BodyType.Dynamic)
+        {
+        }
+
+        /// <summary>
+        /// Creates a body with the given mass and moment, of the give <see cref="BodyType"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Body(double mass, double moment, BodyType type)
+        {
+            body = InitializeBody(type);
+            NativeMethods.cpBodySetMass(body, mass);
+            NativeMethods.cpBodySetMoment(body, moment);
+            RegisterUserData();
+        }
+
+        void RegisterUserData()
+        {
+            cpDataPointer pointer = NativeInterop.RegisterHandle(this);
+            NativeMethods.cpBodySetUserData(body, pointer);
+        }
+
+        void ReleaseUserData()
+        {
+            cpDataPointer pointer = NativeMethods.cpBodyGetUserData(body);
+            NativeInterop.ReleaseHandle(pointer);
+        }
+
+        /// <summary>
+        /// Get a <see cref="Body"/> object from a native cpBody handle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Body FromHandle(cpBody body)
+        {
+            cpDataPointer handle = NativeMethods.cpBodyGetUserData(body);
+            return NativeInterop.FromIntPtr<Body>(handle);
+        }
+
+        /// <summary>
+        /// Get the managed <see cref="Body"/> object from the native handle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Body FromHandleSafe(cpBody nativeBodyHandle)
+        {
+            if (nativeBodyHandle == IntPtr.Zero)
+            {
+                return null;
+            }
+
+            return FromHandle(nativeBodyHandle);
+        }
+
+        private static cpBody InitializeBody(BodyType type)
+        {
+            if (type == BodyType.Kinematic)
+            {
+                return NativeMethods.cpBodyNewKinematic();
+            }
+
+            if (type == BodyType.Static)
+            {
+                return NativeMethods.cpBodyNewStatic();
+            }
+
+            return NativeMethods.cpBodyNew(0.0, 0.0);
+        }
+
+        /// <summary>
+        /// Destroy and free the body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Free()
+        {
+            var space = Space;
+
+            if (space != null)
+                space.RemoveBody(this);
+
+            ReleaseUserData();
+            NativeMethods.cpBodyFree(body);
+        }
+
+        /// <summary>
+        /// Dispose the body.
+        /// </summary>
+        protected virtual void Dispose(bool dispose)
+        {
+            if (!dispose)
+            {
+                Debug.WriteLine("Disposing body {0} on finalizer... (consider Dispose explicitly)", body);
+            }
+
+            Free();
+        }
+
+        /// <summary>
+        /// Dispose the body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        // Properties
+
+        /// <summary>
+        /// Arbitrary user data.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object Data { get; set; }
+
+        /// <summary>
+        /// Rotation of the body in radians. When changing the rotation, you may also want to call
+        /// <see cref="Space.ReindexShapesForBody"/> to update the collision detection information
+        /// for the attached shapes if you plan to make any queries against the space. A body
+        /// rotates around its center of gravity, not its position.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Angle
+        {
+            get => NativeMethods.cpBodyGetAngle(body);
+            set => NativeMethods.cpBodySetAngle(body, value);
+        }
+
+        /// <summary>
+        /// Set body position and rotation angle (in radians)
+        /// </summary>
+        /// <param name="position"></param>
+        /// <param name="angle"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetTransform(Vect position, double angle)
+        {
+            NativeMethods.cpBodySetTransform(body, position, angle);
+        }
+
+        /// <summary>
+        /// Get body position and rotation angle (in radians)
+        /// </summary>
+        /// <param name="position"></param>
+        /// <param name="angle"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void GetTransform(out Vect position, out double angle)
+        {
+            NativeMethods.cpBodyGetTransform(body, out position, out angle);
+        }
+
+        /// <summary>
+        /// The way the body behaves in physics simulations.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public BodyType Type
+        {
+            get => (BodyType)NativeMethods.cpBodyGetType(body);
+            set => NativeMethods.cpBodySetType(body, (int)value);
+        }
+
+        /// <summary>
+        /// Mass of the rigid body. Mass does not have to be expressed in any particular units, but
+        /// relative masses should be consistent. 
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Mass
+        {
+            get => NativeMethods.cpBodyGetMass(body);
+            set => NativeMethods.cpBodySetMass(body, value);
+        }
+
+        /// <summary>
+        /// Moment of inertia of the body. The mass tells you how hard it is to push an object,
+        /// the MoI tells you how hard it is to spin the object. Don't try to guess the MoI, use the
+        /// MomentFor*() functions to estimate it, or the physics may behave strangely. 
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Moment
+        {
+            get => NativeMethods.cpBodyGetMoment(body);
+            set => NativeMethods.cpBodySetMoment(body, value);
+        }
+
+        /// <summary>
+        /// Get the space this body is associated with, or null if it is not currently associated.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Space Space
+        {
+            get
+            {
+                cpSpace space = NativeMethods.cpBodyGetSpace(body);
+                return Space.FromHandleSafe(space);
+            }
+        }
+
+        /// <summary>
+        /// Position of the body. When changing the position, you may also want to call
+        /// <see cref="Space.ReindexShapesForBody"/> to update the collision detection information
+        /// for the attached shapes if you plan to make any queries against the space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Position
+        {
+            get => NativeMethods.cpBodyGetPosition(body);
+            set => NativeMethods.cpBodySetPosition(body, value);
+        }
+
+        /// <summary>
+        /// Location of the center of gravity in body-local coordinates. The default value is
+        /// (0, 0), meaning the center of gravity is the same as the position of the body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect CenterOfGravity
+        {
+            get => NativeMethods.cpBodyGetCenterOfGravity(body);
+            set => NativeMethods.cpBodySetCenterOfGravity(body, value);
+        }
+
+        /// <summary>
+        /// Linear velocity of the center of gravity of the body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Velocity
+        {
+            get => NativeMethods.cpBodyGetVelocity(body);
+            set => NativeMethods.cpBodySetVelocity(body, value);
+        }
+
+        /// <summary>
+        /// Force applied to the center of gravity of the body. This value is reset for every time
+        /// step.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Force
+        {
+            get => NativeMethods.cpBodyGetForce(body);
+            set => NativeMethods.cpBodySetForce(body, value);
+        }
+
+        /// <summary>
+        /// The angular velocity of the body in radians per second.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double AngularVelocity
+        {
+            get => NativeMethods.cpBodyGetAngularVelocity(body);
+            set => NativeMethods.cpBodySetAngularVelocity(body, value);
+        }
+
+        /// <summary>
+        /// The torque applied to the body. This value is reset for every time step.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Torque
+        {
+            get => NativeMethods.cpBodyGetTorque(body);
+            set => NativeMethods.cpBodySetTorque(body, value);
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(BodyArbiterIteratorFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void AddEachArbiterToArray(cpBody body, cpArbiter arbiter, IntPtr data)
+        {
+            var list = (List<Arbiter>)GCHandle.FromIntPtr(data).Target;
+            var a = new Arbiter(arbiter);
+            list.Add(a);
+        }
+
+        private static BodyArbiterIteratorFunction eachArbiterFunc = AddEachArbiterToArray;
+
+        /// <summary>
+        /// The rotation vector for the body. Can be used with cpvrotate() or cpvunrotate() to perform fast rotations.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Rotation => NativeMethods.cpBodyGetRotation(body);
+
+        /// <summary>
+        /// Get the list of body Arbiters
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<Arbiter> Arbiters
+        {
+            get
+            {
+                var list = new List<Arbiter>();
+                var gcHandle = GCHandle.Alloc(list);
+                NativeMethods.cpBodyEachArbiter(body, eachArbiterFunc.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle));
+                gcHandle.Free();
+                return list;
+            }
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(BodyArbiterIteratorFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void AddEachConstraintToArray(cpBody body, cpConstraint constraint, IntPtr data)
+        {
+            var list = (List<Constraint>)GCHandle.FromIntPtr(data).Target;
+            var c = Constraint.FromHandle(constraint);
+            list.Add(c);
+        }
+
+        private static BodyConstraintIteratorFunction eachConstraintFunc = AddEachConstraintToArray;
+
+        /// <summary>
+        /// All constraints attached to the body
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<Constraint> Constraints
+        {
+            get
+            {
+                var list = new List<Constraint>();
+                var gcHandle = GCHandle.Alloc(list);
+                NativeMethods.cpBodyEachConstraint(body, eachConstraintFunc.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle));
+                gcHandle.Free();
+                return list.ToArray();
+            }
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(BodyShapeIteratorFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void AddEachShapeToArray(cpBody body, cpShape shape, IntPtr data)
+        {
+            var list = (List<Shape>)GCHandle.FromIntPtr(data).Target;
+            var s = Shape.FromHandle(shape);
+            list.Add(s);
+        }
+
+        private static BodyShapeIteratorFunction eachShapeFunc = AddEachShapeToArray;
+
+        /// <summary>
+        /// All shapes attached to the body
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<Shape> Shapes
+        {
+            get
+            {
+                var list = new List<Shape>();
+                var gcHandle = GCHandle.Alloc(list);
+                NativeMethods.cpBodyEachShape(body, eachShapeFunc.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle));
+                gcHandle.Free();
+                return list.ToArray();
+            }
+        }
+
+        /// <summary>
+        /// Returns true if body is sleeping.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsSleeping => NativeMethods.cpBodyIsSleeping(body) != 0;
+
+        // Actions
+
+        /// <summary>
+        ///     Reset the idle timer on a body.
+        ///     If it was sleeping, wake it and any other bodies it was touching.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Activate() => NativeMethods.cpBodyActivate(body);
+
+        /// <summary>
+        /// Similar in function to Activate(). Activates all bodies touching body. If filter is not NULL, then only bodies touching through filter will be awoken.
+        /// </summary>
+        /// <param name="filter"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ActivateStatic(Shape filter) => NativeMethods.cpBodyActivateStatic(body, filter.Handle);
+
+        /// <summary>
+        /// Add the local force force to body as if applied from the body local point.
+        /// </summary>
+        /// <param name="force"></param>
+        /// <param name="point"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ApplyForceAtLocalPoint(Vect force, Vect point)
+        {
+            NativeMethods.cpBodyApplyForceAtLocalPoint(body, force, point);
+        }
+
+        /// <summary>
+        /// Apply torque.
+        /// </summary>
+        /// <param name="torque"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ApplyTorque(double torque)
+        {
+            NativeMethods.cpBodyApplyTorque(body, torque);
+        }
+
+        /// <summary>
+        /// Apply angular impulse.
+        /// </summary>
+        /// <param name="impulse"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ApplyAngularImpulse(double impulse)
+        {
+            NativeMethods.cpBodyApplyAngularImpulse(body, impulse);
+        }
+
+        /// <summary>
+        ///     Add the force force to body as if applied from the world point.
+        ///     People are sometimes confused by the difference between a force and an impulse.
+        ///     An impulse is a very large force applied over a very short period of time.
+        ///     Some examples are a ball hitting a wall or cannon firing.
+        ///     Chipmunk treats impulses as if they occur instantaneously by adding directly to the velocity of an object.
+        ///     Both impulses and forces are affected the mass of an object.
+        ///     Doubling the mass of the object will halve the effect.
+        /// </summary>
+        /// <param name="force"></param>
+        /// <param name="point"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ApplyForceAtWorldPoint(Vect force, Vect point)
+        {
+            NativeMethods.cpBodyApplyForceAtWorldPoint(body, force, point);
+        }
+
+        /// <summary>
+        /// Apply an impulse to a body. Both the impulse and point are expressed in world coordinates.
+        /// </summary>
+        /// <param name="impulse"></param>
+        /// <param name="point"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ApplyImpulseAtWorldPoint(Vect impulse, Vect point)
+        {
+            NativeMethods.cpBodyApplyImpulseAtWorldPoint(body, impulse, point);
+        }
+
+        /// <summary>
+        /// Apply an impulse to a body. Both the impulse and point are expressed in body local coordinates.
+        /// </summary>
+        /// <param name="impulse"></param>
+        /// <param name="point"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ApplyImpulseAtLocalPoint(Vect impulse, Vect point)
+        {
+            NativeMethods.cpBodyApplyImpulseAtLocalPoint(body, impulse, point);
+        }
+
+        /// <summary>
+        /// Forces a body to fall asleep immediately even if it’s in midair. Cannot be called from a callback.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Sleep()
+        {
+            NativeMethods.cpBodySleep(body);
+        }
+
+        /// <summary>
+        /// When objects in Chipmunk sleep, they sleep as a group of all objects that are touching or jointed together.
+        /// When an object is woken up, all of the objects in its group are woken up.
+        /// SleepWithGroup() allows you group sleeping objects together. It acts identically to Sleep() if you pass null as
+        /// group by starting a new group.
+        /// If you pass a sleeping body for group, body will be awoken when group is awoken.
+        /// You can use this to initialize levels and start stacks of objects in a pre-sleeping state.
+        /// </summary>
+        /// <param name="group"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SleepWithGroup(Body group)
+        {
+            NativeMethods.cpBodySleepWithGroup(body, group != null ? group.Handle : IntPtr.Zero);
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(BodyVelocityFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void BodyVelocityFunctionCallback(cpBody bodyHandle, Vect gravity, double damping, double dt)
+        {
+            var body = FromHandle(bodyHandle);
+
+            body.velocityUpdateFunction(body, gravity, damping, dt);
+        }
+
+        private static BodyVelocityFunction BodyVelocityFunctionCallbackDelegate = BodyVelocityFunctionCallback;
+
+        private Action<Body, Vect, double, double> velocityUpdateFunction;
+        /// <summary>
+        /// Set the callback used to update a body's velocity.
+        /// Parameters: body, gravity, damping and deltaTime
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Action<Body, Vect, double, double> VelocityUpdateFunction
+        {
+            get => velocityUpdateFunction;
+            set
+            {
+                velocityUpdateFunction = value;
+
+                IntPtr callbackPointer;
+
+                if (value == null)
+                    callbackPointer = NativeMethods.cpBodyGetDefaultVelocityUpdateFunc();
+                else
+                    callbackPointer = BodyVelocityFunctionCallbackDelegate.ToFunctionPointer();
+
+                NativeMethods.cpBodySetVelocityUpdateFunc(body, callbackPointer);
+            }
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(BodyPositionFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void BodyPositionFunctionCallback(cpBody bodyHandle, double dt)
+        {
+            var body = FromHandle(bodyHandle);
+
+            body.positionUpdateFunction(body, dt);
+        }
+
+        private static BodyPositionFunction BodyUpdateFunctionCallbackDelegate = BodyPositionFunctionCallback;
+
+        private Action<Body, double> positionUpdateFunction;
+
+        /// <summary>
+        /// Set the callback used to update a body's position.
+        /// Parameters: body, deltaTime
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Action<Body, double> PositionUpdateFunction
+        {
+            get => positionUpdateFunction;
+            set
+            {
+                positionUpdateFunction = value;
+
+                IntPtr callbackPointer;
+
+                if (value == null)
+                    callbackPointer = NativeMethods.cpBodyGetDefaultPositionUpdateFunc();
+                else
+                    callbackPointer = BodyUpdateFunctionCallbackDelegate.ToFunctionPointer();
+
+                NativeMethods.cpBodySetPositionUpdateFunc(body, callbackPointer);
+            }
+        }
+
+        /// <summary>
+        /// Default velocity integration function..
+        /// </summary>
+        /// <param name="gravity"></param>
+        /// <param name="damping"></param>
+        /// <param name="dt"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void UpdateVelocity(Vect gravity, double damping, double dt)
+        {
+            NativeMethods.cpBodyUpdateVelocity(body, gravity, damping, dt);
+        }
+
+        /// <summary>
+        /// Default position integration function.
+        /// </summary>
+        /// <param name="dt"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void UpdatePosition(double dt)
+        {
+            NativeMethods.cpBodyUpdatePosition(body, dt);
+        }
+
+        /// <summary>
+        /// Convert body relative/local coordinates to absolute/world coordinates.
+        /// </summary>
+        /// <param name="point"></param>
+        /// <returns></returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect LocalToWorld(Vect point)
+        {
+            return NativeMethods.cpBodyLocalToWorld(body, point);
+        }
+
+        /// <summary>
+        /// Convert body absolute/world coordinates to  relative/local coordinates.
+        /// </summary>
+        /// <param name="point"></param>
+        /// <returns></returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect WorldToLocal(Vect point)
+        {
+            return NativeMethods.cpBodyWorldToLocal(body, point);
+        }
+
+        /// <summary>
+        /// Get the velocity on a body (in world units) at a point on the body in world coordinates.
+        /// </summary>
+        /// <param name="point"></param>
+        /// <returns></returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect GetVelocityAtWorldPoint(Vect point)
+        {
+            return NativeMethods.cpBodyGetVelocityAtWorldPoint(body, point);
+        }
+
+        /// <summary>
+        /// Get the velocity on a body (in world units) at a point on the body in local coordinates.
+        /// </summary>
+        /// <param name="point"></param>
+        /// <returns></returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect GetVelocityAtLocalPoint(Vect point)
+        {
+            return NativeMethods.cpBodyGetVelocityAtLocalPoint(body, point);
+        }
+
+        /// <summary>
+        /// Get the kinetic energy of a body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double KineticEnergy => NativeMethods.cpBodyKineticEnergy(body);
+
+        /// <summary>
+        /// Calculate the moment of inertia for a solid box centered on the body.
+        /// </summary>
+        /// <param name="mass"></param>
+        /// <param name="width"></param>
+        /// <param name="height"></param>
+        /// <returns></returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static double MomentForBox(double mass, double width, double height)
+        {
+            return NativeMethods.cpMomentForBox(mass, width, height);
+        }
+
+        /// <summary>
+        /// Get the list of all bodies in contact with this one
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<Body> AllContactedBodies
+        {
+            get
+            {
+                int count = NativeMethods.cpBodyGetContactedBodiesCount(body);
+
+                if (count == 0)
+                    return Array.Empty<Body>();
+
+                IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count);
+                NativeMethods.cpBodyGetUserDataContactedBodies(body, ptrBodies);
+
+                IntPtr[] userDataArray = new IntPtr[count];
+
+                Marshal.Copy(ptrBodies, userDataArray, 0, count);
+
+                Marshal.FreeHGlobal(ptrBodies);
+
+                Body[] bodies = new Body[count];
+
+                for (int i = 0; i < count; i++)
+                {
+                    Body b = NativeInterop.FromIntPtr<Body>(userDataArray[i]);
+                    bodies[i] = b;
+                }
+
+                return bodies;
+            }
+        }
+
+        /// <summary>
+        /// Check if a Body is in contact with another
+        /// </summary>
+        /// <param name="other"></param>
+        /// <returns></returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool ContactWith(Body other)
+        {
+            return NativeMethods.cpBodyContactWith(body, other.body) != 0;
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/BodyType.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/BodyType.cs
new file mode 100644 (file)
index 0000000..ebf2a93
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Chipmunk supports three different types of bodies with unique behavioral and performance
+    /// characteristics.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum BodyType
+    {
+        /// <summary>
+        /// Dynamic bodies are the default body type. They react to collisions, are affected by
+        /// forces and gravity, and have a finite amount of mass. These are the type of bodies that
+        /// you want the physics engine to simulate for you. Dynamic bodies interact with all types
+        /// of bodies and can generate collision callbacks.
+        /// </summary>
+        Dynamic,
+
+        /// <summary>
+        /// Kinematic bodies are bodies that are controlled from your code instead of from the
+        /// physics engine. They aren't affected by gravity and they have an infinite amount of
+        /// mass, so they don’t react to collisions or forces with other bodies. Kinematic bodies
+        /// are controlled by setting their velocity, which will cause them to move. Good examples
+        /// of kinematic bodies might include things like moving platforms. Objects that are
+        /// touching or jointed to a kinematic body are never allowed to fall asleep.
+        /// </summary>
+        Kinematic,
+
+        /// <summary>
+        /// Static bodies are bodies that never (or rarely) move. Using static bodies for things
+        /// like terrain offers a big performance boost over other body types -- Chipmunk doesn't
+        /// need to check for collisions between static objects and it never needs to update their
+        /// collision information. Additionally, because static bodies don’t move, Chipmunk knows
+        /// it’s safe to let objects that are touching or jointed to them fall asleep. Generally,
+        /// all of your level geometry will be attached to a static body, except for things like
+        /// moving platforms or doors. Every space provides a built-in static body for your
+        /// convenience. Static bodies can be moved, but there is a performance penalty as the
+        /// collision information is recalculated. There is no penalty for having multiple static
+        /// bodies, and it can be useful in simplifying your code to allow different parts of your
+        /// static geometry to be initialized or moved separately.
+        /// </summary>
+        Static
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/BoundingBox.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/BoundingBox.cs
new file mode 100644 (file)
index 0000000..535bf4e
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 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;
+using System.Runtime.InteropServices;
+
+#pragma warning disable IDE1006
+#pragma warning disable IDE0032
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Chipmunk's axis-aligned 2D bounding box type.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    [StructLayout(LayoutKind.Sequential)]
+    public struct BoundingBox : IEquatable<BoundingBox>
+    {
+        private double left;
+        private double bottom;
+        private double right;
+        private double top;
+
+        /// <summary>
+        /// Create a bounding box with the given coordinates.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public BoundingBox(double left, double bottom, double right, double top)
+        {
+            this.left = left;
+            this.bottom = bottom;
+            this.right = right;
+            this.top = top;
+        }
+
+        /// <summary>
+        /// Left value of bounding box.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Left { get => left; set => left = value; }
+
+        /// <summary>
+        /// Bottom value of bouding box.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Bottom { get => bottom; set => bottom = value; }
+
+        /// <summary>
+        /// Right value of bouding box.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Right { get => right; set => right = value; }
+
+        /// <summary>
+        /// Top value of bouding box.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Top { get => top; set => top = value; }
+
+        /// <summary>
+        /// Return true if the dimensions of both bounding boxes are equal to another (within
+        /// <see cref="float.Epsilon"/> distance of each other.)
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Equals(BoundingBox other)
+        {
+            return Math.Abs(left - other.left) < float.Epsilon &&
+                   Math.Abs(bottom - other.bottom) < float.Epsilon &&
+                   Math.Abs(right - other.right) < float.Epsilon &&
+                   Math.Abs(top - other.top) < float.Epsilon;
+        }
+
+        /// <summary>
+        /// Return true if the given object is reference-equal.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override bool Equals(object obj)
+        {
+            var bb = obj as BoundingBox?;
+            if (bb == null)
+            {
+                return false;
+            }
+
+            return this == bb.Value;
+        }
+
+        /// <summary>
+        /// Get the bounding box hash code.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override int GetHashCode()
+        {
+            var hashCode = -1064806749;
+
+#pragma warning disable RECS0025 // Non-readonly field referenced in 'GetHashCode()'
+            hashCode = hashCode * -1521134295 + left.GetHashCode();
+            hashCode = hashCode * -1521134295 + bottom.GetHashCode();
+            hashCode = hashCode * -1521134295 + right.GetHashCode();
+            hashCode = hashCode * -1521134295 + top.GetHashCode();
+#pragma warning restore RECS0025 // Non-readonly field referenced in 'GetHashCode()'
+
+            return hashCode;
+        }
+
+        /// <summary>
+        /// Return a string displaying coordinates formatted like (left, bottom, right, top).
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override string ToString()
+        {
+            return $"({left},{bottom},{right},{top})";
+        }
+
+        /// <summary>
+        /// Return true if the dimensions of both bounding boxes are within
+        /// <see cref="float.Epsilon"/> of each other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator ==(BoundingBox left, BoundingBox right)
+        {
+            return left.Equals(right);
+        }
+
+        /// <summary>
+        ///  Return true if the dimensions of both bounding boxes are not within
+        ///  <see cref="float.Epsilon"/> of each other.
+        /// </summary>
+        /// <param name="left"></param>
+        /// <param name="right"></param>
+        /// <returns></returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator !=(BoundingBox left, BoundingBox right)
+        {
+            return !(left == right);
+        }
+    }
+}
+
+#pragma warning restore IDE1006
+#pragma warning restore IDE0032
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/CollisionHandler.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/CollisionHandler.cs
new file mode 100644 (file)
index 0000000..c325a6a
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * 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;
+using System.Diagnostics;
+using cpArbiter = System.IntPtr;
+using cpBool = System.Byte;
+using cpCollisionHandlerPointer = System.IntPtr;
+using cpSpace = System.IntPtr;
+using voidptr_t = System.IntPtr;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+using ObjCRuntime;
+#endif
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// A collision handler is a set of 4 function callbacks for the different collision events that
+    /// Chipmunk recognizes. Collision callbacks are closely associated with <see cref="Arbiter"/>
+    /// objects. You should familiarize yourself with those as well. Note #1: Shapes tagged as
+    /// sensors (<see cref="Shape.Sensor"/> == true) never generate collisions that get processed,
+    /// so collisions between sensor shapes and other shapes will never call the post_solve()
+    /// callback. They still generate begin() and separate() callbacks, and the pre_solve() callback
+    /// is also called every frame even though there is no collision response. Note #2: pre_solve()
+    /// callbacks are called before the sleeping algorithm runs. If an object falls asleep, its
+    /// post_solve() callback won’t be called until it’s re-awoken.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public sealed class CollisionHandler
+    {
+        private readonly cpCollisionHandlerPointer handle;
+
+        private static CollisionBeginFunction beginCallback = CollisionBeginFunctionCallback;
+        private static CollisionPreSolveFunction preSolveCallback = CollisionPreSolveFunctionCallback;
+        private static CollisionPostSolveFunction postSolveCallback = CollisionPostSolveFunctionCallback;
+        private static CollisionSeparateFunction separeteCallback = CollisionSeparateFunctionCallback;
+
+        private static IntPtr DefaultBeginFunction;
+        private static IntPtr DefaultPreSolveFunction;
+        private static IntPtr DefaultPostSolveFunction;
+        private static IntPtr DefaultSeparateFunction;
+
+        private CollisionHandler(cpCollisionHandlerPointer collisionHandle, ref cpCollisionHandler handler)
+        {
+            handle = collisionHandle;
+
+            IntPtr data = NativeInterop.RegisterHandle(this);
+
+            handler.userData = data;
+
+            long typeA = (long)handler.typeA.ToUInt64();
+            long typeB = (long)handler.typeB.ToUInt64();
+
+            TypeA = unchecked((int)typeA);
+            TypeB = unchecked((int)typeB);
+
+            cpCollisionHandler.ToPointer(handler, handle);
+        }
+
+        internal static CollisionHandler GetOrCreate(cpCollisionHandlerPointer collisionHandle)
+        {
+            Debug.Assert(collisionHandle != IntPtr.Zero, "CollisionHandle cannot be zero");
+
+            var handler = cpCollisionHandler.FromHandle(collisionHandle);
+
+            if (handler.userData != IntPtr.Zero)
+            {
+                return NativeInterop.FromIntPtr<CollisionHandler>(handler.userData);
+            }
+
+            EnsureDefaultCallbackValues(handler);
+
+            return new CollisionHandler(collisionHandle, ref handler);
+        }
+
+        private static void EnsureDefaultCallbackValues(cpCollisionHandler handler)
+        {
+            if (DefaultBeginFunction != IntPtr.Zero)
+                return;
+
+            DefaultBeginFunction = handler.beginFunction;
+            DefaultPreSolveFunction = handler.preSolveFunction;
+            DefaultPostSolveFunction = handler.postSolveFunction;
+            DefaultSeparateFunction = handler.separateFunction;
+        }
+
+        private Action<Arbiter, Space, object> begin;
+
+        /// <summary>
+        /// This function is called when two shapes with types that match this collision handler begin colliding
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Action<Arbiter, Space, object> Begin
+        {
+            set
+            {
+                begin = value;
+
+                var handler = cpCollisionHandler.FromHandle(handle);
+
+                IntPtr callbackPointer;
+
+                if (value == null)
+                {
+                    callbackPointer = DefaultBeginFunction;
+                }
+                else
+                {
+                    callbackPointer = beginCallback.ToFunctionPointer();
+                }
+
+                handler.beginFunction = callbackPointer;
+
+                cpCollisionHandler.ToPointer(handler, handle);
+            }
+            get => begin;
+        }
+
+        private Func<Arbiter, Space, object, bool> preSolve;
+
+        /// <summary>
+        /// This function is called each step when two shapes with types that match this collision
+        /// handler are colliding. It's called before the collision solver runs so that you can
+        /// affect a collision's outcome.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Func<Arbiter, Space, object, bool> PreSolve
+        {
+            set
+            {
+                preSolve = value;
+                var handler = cpCollisionHandler.FromHandle(handle);
+                IntPtr callbackPointer;
+
+                if (value == null)
+                {
+                    callbackPointer = DefaultPreSolveFunction;
+                }
+                else
+                {
+                    callbackPointer = preSolveCallback.ToFunctionPointer();
+                }
+
+                handler.preSolveFunction = callbackPointer;
+                cpCollisionHandler.ToPointer(handler, handle);
+            }
+            get => preSolve;
+        }
+
+        private Action<Arbiter, Space, object> postSolve;
+
+        /// <summary>
+        /// This function is called each step when two shapes with types that match this collision
+        /// handler are colliding. It's called after the collision solver runs so that you can read
+        /// back information about the collision to trigger events in your game.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Action<Arbiter, Space, object> PostSolve
+        {
+            set
+            {
+                postSolve = value;
+                var handler = cpCollisionHandler.FromHandle(handle);
+                IntPtr callbackPointer;
+
+                if (value == null)
+                {
+                    callbackPointer = DefaultPostSolveFunction;
+                }
+                else
+                {
+                    callbackPointer = postSolveCallback.ToFunctionPointer();
+                }
+
+                handler.postSolveFunction = callbackPointer;
+                cpCollisionHandler.ToPointer(handler, handle);
+            }
+            get => postSolve;
+        }
+
+        private Action<Arbiter, Space, object> separate;
+
+        /// <summary>
+        /// This function is called when two shapes with types that match this collision handler
+        /// stop colliding.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Action<Arbiter, Space, object> Separate
+        {
+            set
+            {
+                separate = value;
+                var handler = cpCollisionHandler.FromHandle(handle);
+                IntPtr callbackPointer;
+
+                if (value == null)
+                {
+                    callbackPointer = DefaultSeparateFunction;
+                }
+                else
+                {
+                    callbackPointer = separeteCallback.ToFunctionPointer();
+                }
+
+                handler.separateFunction = callbackPointer;
+                cpCollisionHandler.ToPointer(handler, handle);
+            }
+            get => separate;
+        }
+
+        /// <summary>
+        /// User definable context pointer that is passed to all of the collision handler functions.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object Data { get; set; }
+
+        /// <summary>
+        /// In the collision handler callback, the shape with this type will be the first argument.
+        /// Read only.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int TypeA { get; }
+
+        /// <summary>
+        /// In the collision handler callback, the shape with this type will be the second argument.
+        /// Read only.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int TypeB { get; }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(CollisionBeginFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void CollisionBeginFunctionCallback(cpArbiter arbiterHandle, cpSpace spaceHandle, voidptr_t userData)
+        {
+            var arbiter = new Arbiter(arbiterHandle);
+            var space = Space.FromHandle(spaceHandle);
+
+            var handler = NativeInterop.FromIntPtr<CollisionHandler>(userData);
+            var begin = handler.Begin;
+
+            if (begin == null)
+            {
+                return;
+            }
+
+            begin(arbiter, space, handler.Data);
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(CollisionPreSolveFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static cpBool CollisionPreSolveFunctionCallback(cpArbiter arbiterHandle, cpSpace spaceHandle, voidptr_t userData)
+        {
+            var arbiter = new Arbiter(arbiterHandle);
+            var space = Space.FromHandle(spaceHandle);
+
+            var handler = NativeInterop.FromIntPtr<CollisionHandler>(userData);
+            var preSolve = handler.PreSolve;
+
+            if (preSolve == null)
+            {
+                return 1;
+            }
+
+            if (preSolve(arbiter, space, handler.Data))
+            {
+                return 1;
+            }
+
+            return 0;
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(CollisionPostSolveFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void CollisionPostSolveFunctionCallback(cpArbiter arbiterHandle, cpSpace spaceHandle, voidptr_t userData)
+        {
+            var arbiter = new Arbiter(arbiterHandle);
+            var space = Space.FromHandle(spaceHandle);
+
+            var handler = NativeInterop.FromIntPtr<CollisionHandler>(userData);
+            var postSolve = handler.PostSolve;
+
+            if (postSolve == null)
+            {
+                return;
+            }
+
+            postSolve(arbiter, space, handler.Data);
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(CollisionSeparateFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void CollisionSeparateFunctionCallback(cpArbiter arbiterHandle, cpSpace spaceHandle, voidptr_t userData)
+        {
+            var arbiter = new Arbiter(arbiterHandle);
+            var space = Space.FromHandle(spaceHandle);
+
+            var handler = NativeInterop.FromIntPtr<CollisionHandler>(userData);
+            var separate = handler.Separate;
+
+            if (separate == null)
+            {
+                return;
+            }
+
+            separate(arbiter, space, handler.Data);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/Constraint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/Constraint.cs
new file mode 100644 (file)
index 0000000..bf57b7a
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * 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.Diagnostics;
+using System.ComponentModel;
+using cpBody = System.IntPtr;
+using cpConstraint = System.IntPtr;
+using cpDataPointer = System.IntPtr;
+using cpSpace = System.IntPtr;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+using ObjCRuntime;
+#endif
+
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Base class of all constraints.
+    /// You usually don’t want to create instances of this class directly, but instead use one of
+    /// the specific constraints such as the <see cref="PinJoint"/>.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public abstract class Constraint : IDisposable
+    {
+#pragma warning disable IDE0032
+        cpConstraint constraint;
+#pragma warning restore IDE0032
+
+        /// <summary>
+        /// Construct a constraint with the given native handle.
+        /// </summary>
+        /// <param name="handle"></param>
+        internal protected Constraint(cpConstraint handle)
+        {
+            constraint = handle;
+            RegisterUserData();
+        }
+
+        /// <summary>
+        /// Native handle to constraint.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public cpConstraint Handle => constraint;
+
+        /// <summary>
+        /// Register managed object to native user data.
+        /// </summary>
+        private void RegisterUserData()
+        {
+            cpDataPointer pointer = NativeInterop.RegisterHandle(this);
+            NativeMethods.cpConstraintSetUserData(constraint, pointer);
+        }
+
+        void ReleaseUserData()
+        {
+            cpDataPointer pointer = NativeMethods.cpConstraintGetUserData(constraint);
+            NativeInterop.ReleaseHandle(pointer);
+        }
+
+        /// <summary>
+        /// Get a Constraint object from a native handle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Constraint FromHandle(cpConstraint constraint)
+        {
+            cpDataPointer handle = NativeMethods.cpConstraintGetUserData(constraint);
+            return NativeInterop.FromIntPtr<Constraint>(handle);
+        }
+
+        /// <summary>
+        /// Dispose the constraint.
+        /// </summary>
+        protected virtual void Dispose(bool dispose)
+        {
+            if (!dispose)
+            {
+                Debug.WriteLine("Disposing constraint {0} on finalizer... (consider Dispose explicitly)", constraint);
+            }
+
+            Free();
+        }
+
+        /// <summary>
+        /// Destroy and free the constraint.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Free()
+        {
+            ReleaseUserData();
+            NativeMethods.cpConstraintFree(constraint);
+        }
+
+        /// <summary>
+        /// Destroy the constraint
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        /// Get the cpSpace this constraint is added to.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Space Space
+        {
+            get
+            {
+                cpSpace space = NativeMethods.cpConstraintGetSpace(constraint);
+                return Space.FromHandleSafe(space);
+            }
+        }
+
+        /// <summary>
+        /// Get the first body the constraint is attached to.
+        /// </summary>
+        public Body BodyA
+        {
+            get
+            {
+                cpBody body = NativeMethods.cpConstraintGetBodyA(constraint);
+                return Body.FromHandleSafe(body);
+            }
+        }
+
+        /// <summary>
+        /// Get the second body the constraint is attached to.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Body BodyB
+        {
+            get
+            {
+                cpBody body = NativeMethods.cpConstraintGetBodyB(constraint);
+                return Body.FromHandleSafe(body);
+            }
+        }
+
+        /// <summary>;
+        /// The maximum force that this constraint is allowed to use.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double MaxForce
+        {
+            get => NativeMethods.cpConstraintGetMaxForce(constraint);
+            set => NativeMethods.cpConstraintSetMaxForce(constraint, value);
+        }
+
+        /// <summary>
+        /// Rate at which joint error is corrected.
+        /// Defaults to pow(1.0 - 0.1, 60.0) meaning that it will
+        /// correct 10% of the error every 1/60th of a second.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double ErrorBias
+        {
+            get => NativeMethods.cpConstraintGetErrorBias(constraint);
+            set => NativeMethods.cpConstraintSetErrorBias(constraint, value);
+        }
+
+
+        /// <summary>
+        /// The maximum rate at which joint error is corrected.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double MaxBias
+        {
+            get => NativeMethods.cpConstraintGetMaxBias(constraint);
+            set => NativeMethods.cpConstraintSetMaxBias(constraint, value);
+        }
+
+        /// <summary>
+        /// Whether the two bodies connected by the constraint are allowed to collide or not.
+        /// 
+        /// When two bodies collide, Chipmunk ignores the collisions if this property is set to
+        /// False on any constraint that connects the two bodies. Defaults to True. This can be
+        /// used to create a chain that self-collides, but adjacent links in the chain do not collide.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool CollideBodies
+        {
+            get => NativeMethods.cpConstraintGetCollideBodies(constraint) != 0;
+            set => NativeMethods.cpConstraintSetCollideBodies(constraint, value ? (byte)1 : (byte)0);
+        }
+
+        private static ConstraintSolveFunction preSolveFunctionCallback = ConstraintPreSolveFunctionCallback;
+        private static ConstraintSolveFunction postSolveFunctionCallback = ConstraintPostSolveFunctionCallback;
+
+        private Action<Constraint, Space> preSolve;
+        private Action<Constraint, Space> postSolve;
+
+        /// <summary>
+        /// Pre-solve function that is called before the solver runs.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Action<Constraint, Space> PreSolve
+        {
+            get => preSolve;
+            set
+            {
+                preSolve = value;
+
+                IntPtr callbackPointer;
+
+                if (value == null)
+                    callbackPointer = IntPtr.Zero;
+                else
+                    callbackPointer = preSolveFunctionCallback.ToFunctionPointer();
+
+                NativeMethods.cpConstraintSetPreSolveFunc(constraint, callbackPointer);
+            }
+        }
+
+        /// <summary>
+        /// Post-solve function that is called after the solver runs.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Action<Constraint, Space> PostSolve
+        {
+            get => postSolve;
+            set
+            {
+                postSolve = value;
+
+                IntPtr callbackPointer;
+
+                if (value == null)
+                    callbackPointer = IntPtr.Zero;
+                else
+                    callbackPointer = postSolveFunctionCallback.ToFunctionPointer();
+
+                NativeMethods.cpConstraintSetPostSolveFunc(constraint, callbackPointer);
+            }
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(ConstraintSolveFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void ConstraintPreSolveFunctionCallback(cpConstraint constraintHandle, cpSpace spaceHandle)
+        {
+            var constraint = Constraint.FromHandle(constraintHandle);
+            var space = Space.FromHandle(spaceHandle);
+
+            Action<Constraint, Space> preSolve = constraint.PreSolve;
+
+            preSolve(constraint, space);
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(ConstraintSolveFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void ConstraintPostSolveFunctionCallback(cpConstraint constraintHandle, cpSpace spaceHandle)
+        {
+            var constraint = Constraint.FromHandle(constraintHandle);
+            var space = Space.FromHandle(spaceHandle);
+
+            Action<Constraint, Space> postSolve = constraint.PostSolve;
+
+            postSolve(constraint, space);
+        }
+
+        /// <summary>
+        /// The user-definable data pointer for this constraint.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object Data { get; set; }
+
+        /// <summary>
+        /// Get the last impulse applied by this constraint.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Impulse => NativeMethods.cpConstraintGetImpulse(constraint);
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedRotarySpring.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedRotarySpring.cs
new file mode 100644 (file)
index 0000000..44ad728
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 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;
+
+using cpConstraint = System.IntPtr;
+
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+using ObjCRuntime;
+#endif
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// DampedRotarySpring works like <see cref="DampedSpring"/>, but in an angular fashion.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class DampedRotarySpring : Constraint
+    {
+        /// <summary>
+        /// Check if a constraint is a <see cref="DampedRotarySpring"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsDampedRotarySpring(Constraint constraint) => NativeMethods.cpConstraintIsDampedRotarySpring(constraint.Handle) != 0;
+
+        /// <summary>
+        /// Create a damped rotary spring.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DampedRotarySpring(
+            Body bodyA,
+            Body bodyB,
+            double restAngle,
+            double stiffness,
+            double damping)
+            : base(
+                NativeMethods.cpDampedRotarySpringNew(
+                    bodyA.Handle,
+                    bodyB.Handle,
+                    restAngle,
+                    stiffness,
+                    damping))
+        {
+            originalTorqueCallbackPointer = NativeMethods.cpDampedRotarySpringGetSpringTorqueFunc(Handle);
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(DampedRotarySpringTorqueFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static double DampedRotarySpringTorqueCallback(cpConstraint springHandle, double relativeAngle)
+        {
+            var constraint = (DampedRotarySpring)FromHandle(springHandle);
+
+            Func<DampedRotarySpring, double, double> dampedRotarySpringTorqueFunction = constraint.TorqueFunction;
+
+            return dampedRotarySpringTorqueFunction(constraint, relativeAngle);
+        }
+
+        private static DampedRotarySpringTorqueFunction DampedRotarySpringForceCallback = DampedRotarySpringTorqueCallback;
+
+        /// <summary>
+        /// The rest angle of the spring.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double RestAngle
+        {
+            get => NativeMethods.cpDampedRotarySpringGetRestAngle(Handle);
+            set => NativeMethods.cpDampedRotarySpringSetRestAngle(Handle, value);
+        }
+
+        /// <summary>
+        /// The stiffness of the spring in force/distance.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Stiffness
+        {
+            get => NativeMethods.cpDampedRotarySpringGetStiffness(Handle);
+            set => NativeMethods.cpDampedRotarySpringSetStiffness(Handle, value);
+        }
+
+        /// <summary>
+        /// The damping of the spring.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Damping
+        {
+            get => NativeMethods.cpDampedRotarySpringGetDamping(Handle);
+            set => NativeMethods.cpDampedRotarySpringSetDamping(Handle, value);
+        }
+
+        private Func<DampedRotarySpring, double, double> torqueFunction;
+        private IntPtr originalTorqueCallbackPointer;
+
+        /// <summary>
+        /// Damped rotary spring torque custom function callback.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Func<DampedRotarySpring, double, double> TorqueFunction
+        {
+            get => torqueFunction;
+            set
+            {
+                torqueFunction = value;
+
+                IntPtr callbackPointer;
+
+                if (value == null)
+                {
+                    callbackPointer = originalTorqueCallbackPointer;
+                }
+                else
+                {
+                    callbackPointer = DampedRotarySpringForceCallback.ToFunctionPointer();
+                }
+
+                NativeMethods.cpDampedRotarySpringSetSpringTorqueFunc(Handle, callbackPointer);
+            }
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedSpring.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedSpring.cs
new file mode 100644 (file)
index 0000000..9ffa323
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * 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;
+
+using cpConstraint = System.IntPtr;
+
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+using ObjCRuntime;
+#endif
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// <see cref="DampedSpring"/> is a damped spring.
+    /// The spring allows you to define the rest length, stiffness and damping.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class DampedSpring : Constraint
+    {
+        /// <summary>
+        /// Check if a constraint is a <see cref="DampedSpring"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsDampedSpring(Constraint constraint) => NativeMethods.cpConstraintIsDampedSpring(constraint.Handle) != 0;
+
+        /// <summary>
+        /// Defined much like a slide joint.
+        /// </summary>
+        /// <param name="bodyA">The first connected body.</param>
+        /// <param name="bodyB">The second connected body.</param>
+        /// <param name="anchorA">Anchor point a, relative to body a.</param>
+        /// <param name="anchorB"> Anchor point b, relative to body b.</param>
+        /// <param name="restLength">The distance the spring wants to be.</param>
+        /// <param name="stiffness">The spring constant (Young’s modulus).</param>
+        /// <param name="damping">How soft to make the damping of the spring.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DampedSpring(
+            Body bodyA,
+            Body bodyB,
+            Vect anchorA,
+            Vect anchorB,
+            double restLength,
+            double stiffness,
+            double damping)
+            : base(NativeMethods.cpDampedSpringNew(
+                bodyA.Handle,
+                bodyB.Handle,
+                anchorA,
+                anchorB,
+                restLength,
+                stiffness,
+                damping))
+        {
+            originalForceCallbackPointer = NativeMethods.cpDampedSpringGetSpringForceFunc(Handle);
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(DampedSpringForceFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static double DampedSpringForceCallback(cpConstraint springHandle, double distance)
+        {
+            var constraint = (DampedSpring)Constraint.FromHandle(springHandle);
+
+            Func<DampedSpring, double, double> dampedSpringForceFunction = constraint.forceFunction;
+
+            return dampedSpringForceFunction(constraint, distance);
+        }
+
+        private static DampedSpringForceFunction dampedSpringForceCallback = DampedSpringForceCallback;
+
+        /// <summary>
+        /// The location of the first anchor relative to the first body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect AnchorA
+        {
+            get => NativeMethods.cpDampedSpringGetAnchorA(Handle);
+            set => NativeMethods.cpDampedSpringSetAnchorA(Handle, value);
+        }
+
+        /// <summary>
+        /// The location of the second anchor relative to the second body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect AnchorB
+        {
+            get => NativeMethods.cpDampedSpringGetAnchorB(Handle);
+            set => NativeMethods.cpDampedSpringSetAnchorB(Handle, value);
+        }
+
+        /// <summary>
+        /// The rest length of the spring.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double RestLength
+        {
+            get => NativeMethods.cpDampedSpringGetRestLength(Handle);
+            set => NativeMethods.cpDampedSpringSetRestLength(Handle, value);
+        }
+
+        /// <summary>
+        /// The stiffness of the spring in force/distance.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Stiffness
+        {
+            get => NativeMethods.cpDampedSpringGetStiffness(Handle);
+            set => NativeMethods.cpDampedSpringSetStiffness(Handle, value);
+        }
+
+        /// <summary>
+        /// The damping of the spring.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Damping
+        {
+            get => NativeMethods.cpDampedSpringGetDamping(Handle);
+            set => NativeMethods.cpDampedSpringSetDamping(Handle, value);
+        }
+
+        private Func<DampedSpring, double, double> forceFunction;
+
+        private IntPtr originalForceCallbackPointer;
+
+        /// <summary>
+        /// Damped spring force custom function callback.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Func<DampedSpring, double, double> ForceFunction
+        {
+            get => forceFunction;
+            set
+            {
+                forceFunction = value;
+
+                IntPtr callbackPointer;
+
+                if (value == null)
+                {
+                    callbackPointer = originalForceCallbackPointer;
+                }
+                else
+                {
+                    callbackPointer = dampedSpringForceCallback.ToFunctionPointer();
+                }
+
+                NativeMethods.cpDampedSpringSetSpringForceFunc(Handle, callbackPointer);
+            }
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GearJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GearJoint.cs
new file mode 100644 (file)
index 0000000..601342e
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// <see cref="GearJoint"/> keeps the angular velocity ratio of a pair of bodies constant.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class GearJoint : Constraint
+    {
+        /// <summary>
+        /// Check if a constraint is a <see cref="GearJoint"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsGearJoint(Constraint constraint) => NativeMethods.cpConstraintIsGearJoint(constraint.Handle) != 0;
+
+        /// <summary>
+        /// Keeps the angular velocity ratio of a pair of bodies constant.
+        /// </summary>
+        /// <param name="bodyA">The first connected body.</param>
+        /// <param name="bodyB">The second connected body.</param>
+        /// <param name="phase">The seconded connected body.</param>
+        /// <param name="ratio">
+        /// Measured in absolute terms. It is currently not possible to set
+        /// the ratio in relation to a third body’s angular velocity.
+        /// </param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public GearJoint(Body bodyA, Body bodyB, double phase, double ratio) :
+            base(NativeMethods.cpGearJointNew(bodyA.Handle, bodyB.Handle, phase, ratio))
+        {
+        }
+
+        /// <summary>
+        /// The phase offset of the gears.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Phase
+        {
+            get => NativeMethods.cpGearJointGetPhase(Handle);
+            set => NativeMethods.cpGearJointSetPhase(Handle, value);
+        }
+
+        /// <summary>
+        /// The ratio of a gear joint.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Ratio
+        {
+            get => NativeMethods.cpGearJointGetRatio(Handle);
+            set => NativeMethods.cpGearJointSetRatio(Handle, value);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GrooveJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GrooveJoint.cs
new file mode 100644 (file)
index 0000000..e295b31
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// <see cref="GrooveJoint"/> is similar to a <see cref="PivotJoint"/>, but with a linear slide.
+    /// One of the anchor points is a line segment that the pivot can slide on instead of being fixed.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class GrooveJoint : Constraint
+    {
+        /// <summary>
+        /// Check if a constraint is a <see cref="GrooveJoint"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsGrooveJoint(Constraint constraint) => NativeMethods.cpConstraintIsGrooveJoint(constraint.Handle) != 0;
+
+        /// <summary>
+        /// Create an anchor where <paramref name="bodyB"/> can rotate similar to a
+        /// <see cref="PivotJoint"/>, except it's anchored at <paramref name="anchorB"/>, which is a
+        /// point that can slide between <paramref name="grooveA"/> and <paramref name="grooveB"/>.
+        /// </summary>
+        /// <param name="bodyA">The first connected body.</param>
+        /// <param name="bodyB">The second connected body.</param>
+        /// <param name="grooveA">
+        /// The start of the groove on <paramref name="bodyA"/>. Coordinates are local to the body.
+        /// </param>
+        /// <param name="grooveB">
+        /// The end of the groove on <paramref name="bodyA"/>. Coordinates are local to the body.
+        /// </param>
+        /// <param name="anchorB">
+        /// The location of the pivot on <paramref name="bodyB"/>. Coordinates are local to the
+        /// body.
+        /// </param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public GrooveJoint(Body bodyA, Body bodyB, Vect grooveA, Vect grooveB, Vect anchorB)
+            : base(NativeMethods.cpGrooveJointNew(bodyA.Handle, bodyB.Handle, grooveA, grooveB, anchorB))
+        {
+        }
+
+        /// <summary>
+        /// The first endpoint of the groove relative to the first body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect GrooveA
+        {
+            get => NativeMethods.cpGrooveJointGetGrooveA(Handle);
+            set => NativeMethods.cpGrooveJointSetGrooveA(Handle, value);
+        }
+
+        /// <summary>
+        /// The second endpoint of the groove relative to the first body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect GrooveB
+        {
+            get => NativeMethods.cpGrooveJointGetGrooveB(Handle);
+            set => NativeMethods.cpGrooveJointSetGrooveB(Handle, value);
+        }
+
+        /// <summary>
+        ///  The location of the second anchor relative to the second body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect AnchorB
+        {
+            get => NativeMethods.cpGrooveJointGetAnchorB(Handle);
+            set => NativeMethods.cpGrooveJointSetAnchorB(Handle, value);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PinJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PinJoint.cs
new file mode 100644 (file)
index 0000000..f0f9e94
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// <see cref="PinJoint"/> links shapes with a solid bar or pin. Keeps the anchor points at a
+    /// set distance from one another.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class PinJoint : Constraint
+    {
+        /// <summary>
+        /// Check if a constraint is a <see cref="PinJoint"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsPinJoint(Constraint constraint) => NativeMethods.cpConstraintIsPinJoint(constraint.Handle) != 0;
+
+        /// <summary>
+        /// The distance between the two anchor points is measured when the joint is created. If you
+        /// want to set a specific distance, use the setter function to override it.
+        /// </summary>
+        /// <param name="bodyA">One of the two bodies to connect.</param>
+        /// <param name="bodyB">One of the two bodies to connect.</param>
+        /// <param name="anchorA">The anchor point for <paramref name="bodyA"/>.</param>
+        /// <param name="anchorB">The anchor point for <paramref name="bodyB"/>.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public PinJoint(Body bodyA, Body bodyB, Vect anchorA, Vect anchorB)
+            : base(NativeMethods.cpPinJointNew(bodyA.Handle, bodyB.Handle, anchorA, anchorB))
+        {
+        }
+
+        /// <summary>
+        /// The location of the first anchor relative to the first body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect AnchorA
+        {
+            get => NativeMethods.cpPinJointGetAnchorA(Handle);
+            set => NativeMethods.cpPinJointSetAnchorA(Handle, value);
+        }
+
+        /// <summary>
+        /// The location of the second anchor relative to the second body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect AnchorB
+        {
+            get => NativeMethods.cpPinJointGetAnchorB(Handle);
+            set => NativeMethods.cpPinJointSetAnchorB(Handle, value);
+        }
+
+        /// <summary>
+        /// The distance the joint will maintain between the two anchors.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Distance
+        {
+            get => NativeMethods.cpPinJointGetDist(Handle);
+            set => NativeMethods.cpPinJointSetDist(Handle, value);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PivotJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PivotJoint.cs
new file mode 100644 (file)
index 0000000..de7a9bd
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// <see cref="PivotJoint"/> acts like a swivel, allowing two objects to pivot about a single
+    /// point.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class PivotJoint : Constraint
+    {
+        /// <summary>
+        /// Check if a constraint is a <see cref="PinJoint"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsPivotJoint(Constraint constraint) => NativeMethods.cpConstraintIsPivotJoint(constraint.Handle) != 0;
+
+        /// <summary>
+        /// Initialize a pivot joint with two anchors. Since the anchors are provided in world
+        /// coordinates, the bodies must already be correctly positioned. The joint is fixed as soon
+        /// as the containing space is simulated.
+        /// </summary>
+        /// <param name="bodyA">One of the two bodies to connect.</param>
+        /// <param name="bodyB">One of the two bodies to connect.</param>
+        /// <param name="anchorA">
+        /// The location of one of the anchors, specified in world coordinates.
+        /// </param>
+        /// <param name="anchorB">
+        /// The location of one of the anchors, specified in world coordinates.
+        /// </param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public PivotJoint(Body bodyA, Body bodyB, Vect anchorA, Vect anchorB)
+            : base(NativeMethods.cpPivotJointNew2(bodyA.Handle, bodyB.Handle, anchorA, anchorB))
+        {
+        }
+
+        /// <summary>
+        /// Initialize a pivot joint with one anchor. Since the pivot is provided in world
+        /// coordinates, the bodies must already be correctly positioned.
+        /// </summary>
+        /// <param name="bodyA">One of the two bodies to connect.</param>
+        /// <param name="bodyB">One of the two bodies to connect.</param>
+        /// <param name="anchor">The location of the pivot, specified in world coordinates.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public PivotJoint(Body bodyA, Body bodyB, Vect anchor) :
+        base(NativeMethods.cpPivotJointNew(bodyA.Handle, bodyB.Handle, anchor))
+        {
+
+        }
+
+        /// <summary>
+        /// The location of the first anchor relative to the first body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect AnchorA
+        {
+            get => NativeMethods.cpPivotJointGetAnchorA(Handle);
+            set => NativeMethods.cpPivotJointSetAnchorA(Handle, value);
+        }
+
+        /// <summary>
+        /// The location of the second anchor relative to the second body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect AnchorB
+        {
+            get => NativeMethods.cpPivotJointGetAnchorB(Handle);
+            set => NativeMethods.cpPivotJointSetAnchorB(Handle, value);
+        }
+
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RatchetJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RatchetJoint.cs
new file mode 100644 (file)
index 0000000..4c368ac
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// <see cref="RatchetJoint"/> is a rotary ratchet, which works like a socket wrench.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class RatchetJoint : Constraint
+    {
+        /// <summary>
+        /// Check if a constraint is a <see cref="RatchetJoint"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsRatchetJoint(Constraint constraint) => NativeMethods.cpConstraintIsRatchetJoint(constraint.Handle) != 0;
+
+        /// <summary>
+        /// Works like a socket wrench.
+        /// </summary>
+        /// <param name="bodyA">One of the two bodies to connect.</param>
+        /// <param name="bodyB">One of the two bodies to connect.</param>
+        /// <param name="phase">
+        /// The initial offset to use when deciding where the ratchet angles are.
+        /// </param>
+        /// <param name="ratchet">
+        /// The distance between "clicks" (following the socket wrench analogy).
+        /// </param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public RatchetJoint(Body bodyA, Body bodyB, double phase, double ratchet)
+            : base(NativeMethods.cpRatchetJointNew(bodyA.Handle, bodyB.Handle, phase, ratchet))
+        {
+        }
+
+        /// <summary>
+        /// The angle of the current ratchet tooth.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Angle
+        {
+            get => NativeMethods.cpRatchetJointGetAngle(Handle);
+            set => NativeMethods.cpRatchetJointSetAngle(Handle, value);
+        }
+
+        /// <summary>
+        /// The phase offset of the ratchet.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Phase
+        {
+            get => NativeMethods.cpRatchetJointGetPhase(Handle);
+            set => NativeMethods.cpRatchetJointSetPhase(Handle, value);
+        }
+
+        /// <summary>
+        /// The angular distance of each ratchet.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Rachet
+        {
+            get => NativeMethods.cpRatchetJointGetRatchet(Handle);
+            set => NativeMethods.cpRatchetJointSetRatchet(Handle, value);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RotaryLimitJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RotaryLimitJoint.cs
new file mode 100644 (file)
index 0000000..16b6fa1
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// <see cref="RotaryLimitJoint"/> constrains the relative rotations of two bodies.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class RotaryLimitJoint : Constraint
+    {
+        /// <summary>
+        /// Check if a constraint is a <see cref="RotaryLimitJoint"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsRotaryLimitJoint(Constraint constraint) => NativeMethods.cpConstraintIsRotaryLimitJoint(constraint.Handle) != 0;
+
+        /// <summary>
+        /// Constrains the relative rotations of two bodies.
+        /// </summary>
+        /// <param name="bodyA"></param>
+        /// <param name="bodyB"></param>
+        /// <param name="mininum">
+        /// The minimum angular limit in radians. May be greater than 1 backwards revolution.
+        /// </param>
+        /// <param name="maximum">
+        /// The maximum angular limit in radians. May be greater than 1 revolution.
+        /// </param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public RotaryLimitJoint(Body bodyA, Body bodyB, double mininum, double maximum)
+            : base(NativeMethods.cpRotaryLimitJointNew(bodyA.Handle, bodyB.Handle, mininum, maximum))
+        {
+        }
+
+        /// <summary>
+        /// The minimum distance the joint will maintain between the two anchors.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Minimum
+        {
+            get => NativeMethods.cpRotaryLimitJointGetMin(Handle);
+            set => NativeMethods.cpRotaryLimitJointSetMin(Handle, value);
+        }
+
+        /// <summary>
+        /// The maximum distance the joint will maintain between the two anchors.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Maximum
+        {
+            get => NativeMethods.cpRotaryLimitJointGetMax(Handle);
+            set => NativeMethods.cpRotaryLimitJointSetMax(Handle, value);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SimpleMotor.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SimpleMotor.cs
new file mode 100644 (file)
index 0000000..a8c2d80
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// <see cref="SimpleMotor"/> keeps the relative angular velocity constant.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class SimpleMotor : Constraint
+    {
+        /// <summary>
+        /// Check if constraint is a <see cref="SimpleMotor"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsSimpleMotor(Constraint constraint) => NativeMethods.cpConstraintIsSimpleMotor(constraint.Handle) != 0;
+
+        /// <summary>
+        /// Rotate with a constant relative angular velocity constant between two bodies.
+        /// </summary>
+        /// <param name="bodyA">One of the two bodies.</param>
+        /// <param name="bodyB">One of the two bodies.</param>
+        /// <param name="rate">The rate of rotation.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public SimpleMotor(Body bodyA, Body bodyB, double rate)
+            : base(NativeMethods.cpSimpleMotorNew(bodyA.Handle, bodyB.Handle, rate))
+        {
+        }
+
+        /// <summary>
+        /// The rate of the motor.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Rate
+        {
+            get => NativeMethods.cpSimpleMotorGetRate(Handle);
+            set => NativeMethods.cpSimpleMotorSetRate(Handle, value);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SlideJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SlideJoint.cs
new file mode 100644 (file)
index 0000000..9b4681f
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// <see cref="SlideJoint"/> is like a <see cref="PinJoint"/>, but with a minimum and maximum
+    /// distance. A chain could be modeled using this joint. It keeps the anchor points from getting
+    /// too far apart, but will allow them to get closer together.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class SlideJoint : Constraint
+    {
+        /// <summary>
+        /// Check if a constraint is a <see cref="SlideJoint"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsSlideJoint(Constraint constraint) => NativeMethods.cpConstraintIsSlideJoint(constraint.Handle) != 0;
+
+        /// <summary>
+        /// Create a slide constraint between two bodies.
+        /// </summary>
+        /// <param name="bodyA">One of the two bodies to connect.</param>
+        /// <param name="bodyB">One of the two bodies to connect.</param>
+        /// <param name="anchorA">The anchor point for <paramref name="bodyA"/>.</param>
+        /// <param name="anchorB">The anchor point for <paramref name="bodyB"/>.</param>
+        /// <param name="min">The minimum distance the anchor points can get to each other.</param>
+        /// <param name="max">The maximum distance the anchor points can be apart.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public SlideJoint(Body bodyA, Body bodyB, Vect anchorA, Vect anchorB, double min, double max)
+            : base(NativeMethods.cpSlideJointNew(bodyA.Handle, bodyB.Handle, anchorA, anchorB, min, max))
+        {
+        }
+
+        /// <summary>
+        /// The location of the first anchor relative to the first body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect AnchorA
+        {
+            get => NativeMethods.cpSlideJointGetAnchorA(Handle);
+            set => NativeMethods.cpSlideJointSetAnchorA(Handle, value);
+        }
+
+        /// <summary>
+        /// The location of the second anchor relative to the second body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect AnchorB
+        {
+            get => NativeMethods.cpSlideJointGetAnchorB(Handle);
+            set => NativeMethods.cpSlideJointSetAnchorB(Handle, value);
+        }
+
+        /// <summary>
+        /// The minimum distance the joint will maintain between the two anchors
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Minimum
+        {
+            get => NativeMethods.cpSlideJointGetMin(Handle);
+            set => NativeMethods.cpSlideJointSetMin(Handle, value);
+        }
+
+        /// <summary>
+        /// The maximum distance the joint will maintain between the two anchors.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Maximum
+        {
+            get => NativeMethods.cpSlideJointGetMax(Handle);
+            set => NativeMethods.cpSlideJointSetMax(Handle, value);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPoint.cs
new file mode 100644 (file)
index 0000000..d1233d3
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * 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
+{
+    /// <summary>
+    ///  Contains information about a contact point. <see cref="PointA"/> and <see cref="PointB"/>
+    ///  are the contact positions on the surface of each shape. <see cref="Distance"/> 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
+    ///  <see cref="Arbiter.ContactPointSet"/>.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public sealed class ContactPoint : IEquatable<ContactPoint>
+    {
+#pragma warning disable IDE0032
+        private readonly Vect pointA;
+        private readonly Vect pointB;
+        private readonly double distance;
+#pragma warning restore IDE0032
+
+        /// <summary>
+        /// Point A in the contact point.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect PointA => pointA;
+
+        /// <summary>
+        ///  Point B in the contact point.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect PointB => pointB;
+
+        /// <summary>
+        /// 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
+        /// <see cref="Arbiter.ContactPointSet"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Distance => distance;
+
+        private ContactPoint(Vect pointA, Vect pointB, double distance)
+        {
+            this.pointA = pointA;
+            this.pointB = pointB;
+            this.distance = distance;
+        }
+
+        /// <summary>
+        /// Returns true if neither <see cref="ContactPoint"/> is null and the points are within
+        /// <see cref="float.Epsilon"/> distance of each other.
+        /// </summary>
+        [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;
+        }
+
+
+        /// <summary>
+        /// Check if this <see cref="ContactPoint"/> is equal to an object.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override bool Equals(object obj)
+        {
+            var other = obj as ContactPoint;
+
+            if (other == null)
+            {
+                return false;
+            }
+
+            return Equals(other);
+        }
+
+        /// <summary>
+        /// Get the <see cref="ContactPoint"/> hash set.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override int GetHashCode()
+        {
+            var hashCode = -1285340573;
+
+            hashCode = hashCode * -1521134295 + pointA.GetHashCode();
+            hashCode = hashCode * -1521134295 + pointB.GetHashCode();
+            hashCode = hashCode * -1521134295 + distance.GetHashCode();
+
+            return hashCode;
+        }
+
+        /// <summary>
+        /// Returns a string in the format of "a: {pointA}, b: {pointB}, distance: {distance}".
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override string ToString()
+        {
+            return $"a: {pointA}, b: {pointB}, distance: {distance}";
+        }
+
+        /// <summary>
+        /// Returns true if both <see cref="ContactPoint"/>s are the same object or the dimensions
+        /// are within <see cref="float.Epsilon"/> distance of each other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator ==(ContactPoint left, ContactPoint right)
+        {
+            if (ReferenceEquals(left, null))
+            {
+                return ReferenceEquals(right, null);
+            }
+
+            return left.Equals(right);
+        }
+
+        /// <summary>
+        /// Returns false if both <see cref="ContactPoint"/>s are the same object or the dimensions
+        /// are within <see cref="float.Epsilon"/> distance of each other.
+        /// </summary>
+        [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
+            };
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPointSet.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPointSet.cs
new file mode 100644 (file)
index 0000000..8a623f0
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * 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.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Contact point sets make getting contact information simpler. There can be at most 2 contact
+    /// points.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public sealed class ContactPointSet : IEquatable<ContactPointSet>
+    {
+#pragma warning disable IDE0032
+        private readonly int count;
+        private readonly Vect normal;
+        private readonly ContactPoint[] points;
+#pragma warning restore IDE0032
+
+        private ContactPointSet(int count, Vect normal, ContactPoint[] points)
+        {
+            this.count = count;
+            this.normal = normal;
+            this.points = points;
+        }
+
+        /// <summary>
+        /// Get the number of contact points in the contact set (maximum of two).
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int Count => count;
+
+        /// <summary>
+        /// Get the normal of the collision.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Normal => normal;
+
+        /// <summary>
+        /// List of points in the contact point set
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<ContactPoint> Points => points;
+
+        /// <summary>
+        /// Return true if the contact point set is sequence-equal to another.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Equals(ContactPointSet other)
+        {
+            if (ReferenceEquals(other, null)
+                || count != other.count
+                || normal != other.normal
+                || points.Length != other.points.Length)
+            {
+                return false;
+            }
+
+            return points.SequenceEqual(other.points);
+        }
+
+        /// <summary>
+        /// Get the hash code.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override int GetHashCode()
+        {
+            var hashCode = -475635172;
+
+            hashCode = hashCode * -1521134295 + count.GetHashCode();
+            hashCode = hashCode * -1521134295 + normal.GetHashCode();
+            hashCode = hashCode * -1521134295 + EqualityComparer<ContactPoint[]>.Default.GetHashCode(points);
+
+            return hashCode;
+        }
+
+        /// <summary>
+        /// Return true if the <see cref="ContactPointSet"/> is sequence-equal to another.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override bool Equals(object obj)
+        {
+            var other = obj as ContactPointSet;
+
+            if (other == null)
+            {
+                return false;
+            }
+
+            return Equals(other);
+        }
+
+        /// <summary>
+        /// Return true if the contact point sets are sequence-equal.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator ==(ContactPointSet left, ContactPointSet right)
+        {
+            if (ReferenceEquals(left, null))
+            {
+                return ReferenceEquals(right, null);
+            }
+
+            return left.Equals(right);
+        }
+
+        /// <summary>
+        /// Return true if the contact point sets are sequence-inequal.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator !=(ContactPointSet left, ContactPointSet right)
+        {
+            return !(left == right);
+        }
+
+        internal static ContactPointSet FromContactPointSet(cpContactPointSet contactPointSet)
+        {
+            var points = new ContactPoint[2];
+
+            if (contactPointSet.count > 0)
+            {
+                points[0] = ContactPoint.FromCollidePoint(contactPointSet.points0);
+            }
+            else
+            {
+                points[0] = ContactPoint.Empty;
+            }
+
+            if (contactPointSet.count > 1)
+            {
+                points[1] = ContactPoint.FromCollidePoint(contactPointSet.points1);
+            }
+            else
+            {
+                points[1] = ContactPoint.Empty;
+            }
+
+            return new ContactPointSet(
+                contactPointSet.count,
+                contactPointSet.normal,
+                points);
+        }
+
+        internal cpContactPointSet ToContactPointSet()
+        {
+            return new cpContactPointSet
+            {
+                normal = normal,
+                points0 = points[0].ToContactPoint(),
+                points1 = points[1].ToContactPoint(),
+                count = count
+            };
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugColor.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugColor.cs
new file mode 100644 (file)
index 0000000..223e869
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * 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;
+using System.Runtime.InteropServices;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// RGBA channels as floats used to represent the color for debug drawing.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    [StructLayout(LayoutKind.Sequential)]
+    public struct DebugColor : IEquatable<DebugColor>
+    {
+#pragma warning disable IDE0032
+        private readonly float red;
+        private readonly float green;
+        private readonly float blue;
+        private readonly float alpha;
+#pragma warning restore IDE0032
+
+        /// <summary>
+        /// Red component in the RGBA color space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float Red => red;
+
+        /// <summary>
+        /// Green component in the RGBA color space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float Green => green;
+
+        /// <summary>
+        /// Blue component in the RGBA color space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float Blue => blue;
+
+        /// <summary>
+        /// Alpha component in the RGBA color space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float Alpha => alpha;
+
+        /// <summary>
+        /// Create a <see cref="DebugColor"/> with the given color channel values.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DebugColor(float red, float green, float blue)
+            : this(red, green, blue, 1.0f)
+        {
+        }
+
+        /// <summary>
+        /// Create a <see cref="DebugColor"/> with the given color channel values.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DebugColor(float red, float green, float blue, float alpha)
+        {
+            this.red = red;
+            this.green = green;
+            this.blue = blue;
+            this.alpha = alpha;
+        }
+
+        /// <summary>
+        /// Check if a <see cref="DebugColor"/> is equal to another object.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override bool Equals(object obj)
+        {
+            var other = obj as DebugColor?;
+
+            if (other == null)
+                return false;
+
+            return Equals(other.Value);
+        }
+
+        /// <summary>
+        /// Check if a <see cref="DebugColor"/> is reference-equal to the other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Equals(DebugColor color)
+        {
+            return this == color;
+        }
+
+        /// <summary>
+        /// Get the hash code.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override int GetHashCode()
+        {
+            var hashCode = -1813971818;
+
+            hashCode = hashCode * -1521134295 + red.GetHashCode();
+            hashCode = hashCode * -1521134295 + green.GetHashCode();
+            hashCode = hashCode * -1521134295 + blue.GetHashCode();
+            hashCode = hashCode * -1521134295 + alpha.GetHashCode();
+
+            return hashCode;
+        }
+
+        /// <summary>
+        /// Return a string formatted as "(R, G, B, A)".
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override string ToString()
+        {
+            return $"({red},{green},{blue},{alpha})";
+        }
+
+        /// <summary>
+        /// Return true if two <see cref="DebugColor"/> are reference-equal.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator ==(DebugColor a, DebugColor b)
+        {
+#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
+            return a.red == b.red &&
+                a.green == b.green &&
+                a.blue == b.blue &&
+                a.alpha == b.alpha;
+#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
+        }
+
+
+        /// <summary>
+        /// Return true if two <see cref="DebugColor"/> are not reference-equal.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator !=(DebugColor a, DebugColor b)
+        {
+            return !(a == b);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawColors.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawColors.cs
new file mode 100644 (file)
index 0000000..a64e7ea
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Default DebugColors for ShapeOutline, Constraint and CollisionPoint
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class DebugDrawColors
+    {
+#pragma warning disable IDE0032
+        static readonly DebugDrawColors defaultColors = new DebugDrawColors()
+        {
+            ShapeOutline = new DebugColor(1, 1, 1),
+            Constraint = new DebugColor(0, 1, 0),
+            CollisionPoint = new DebugColor(1, 0, 1)
+        };
+#pragma warning restore IDE0032
+
+        /// <summary>
+        /// Shape outline color.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DebugColor ShapeOutline { get; set; }
+
+        /// <summary>
+        /// Constraint color.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DebugColor Constraint { get; set; }
+
+        /// <summary>
+        /// Collision point color.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DebugColor CollisionPoint { get; set; }
+
+        /// <summary>
+        /// The Default DebugDrawColors.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static DebugDrawColors Default => defaultColors;
+
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawFlags.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawFlags.cs
new file mode 100644 (file)
index 0000000..31e13c9
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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
+{
+    /// <summary>
+    /// Flags to enable or disable DebugDrawing.
+    /// </summary>
+    [Flags]
+        [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum DebugDrawFlags
+    {
+        /// <summary>
+        /// Draw nothing.
+        /// </summary>
+        None = 0,
+
+        /// <summary>
+        /// Draw Shapes.
+        /// </summary>
+        Shapes = 1 << 0,
+
+        /// <summary>
+        /// Draw Constraints.
+        /// </summary>
+        Constraints = 1 << 1,
+
+        /// <summary>
+        ///  Draw Collision Points.
+        /// </summary>
+        CollisionPoints = 1 << 2,
+
+        /// <summary>
+        /// Draw All.
+        /// </summary>
+        All = Shapes | Constraints | CollisionPoints
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/HastySpace.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/HastySpace.cs
new file mode 100644 (file)
index 0000000..5c0e1ce
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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
+{
+    /// <summary>
+    /// Similar to <see cref="Space"/>, but with ARM NEON optimizations in the solver.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public sealed class HastySpace : Space
+    {
+        /// <summary>
+        /// On ARM platforms that support NEON, this will enable the vectorized solver.
+        /// <see cref="HastySpace"/> also supports multiple threads, but runs single threaded by
+        /// default for determinism.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public HastySpace()
+            : base(NativeMethods.cpHastySpaceNew())
+        {
+        }
+
+        /// <summary>
+        /// The number of threads to use for the solver. Currently Chipmunk is limited to 2 threads
+        /// as using more generally provides very minimal performance gains. Passing 0 as the thread
+        /// count on iOS or OS X will cause Chipmunk to automatically detect the number of threads
+        /// it should use. On other platforms passing 0 for the thread count will set 1 thread.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int Threads
+        {
+            get => (int)NativeMethods.cpHastySpaceGetThreads(Handle);
+            set => NativeMethods.cpHastySpaceSetThreads(Handle, (uint)value);
+        }
+
+        /// <summary>
+        /// Step in the hasty space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public sealed override void Step(double dt)
+        {
+            NativeMethods.cpHastySpaceStep(Handle, dt);
+        }
+
+        /// <summary>
+        /// Destroy and free the hasty space.
+        /// </summary>
+        protected override void FreeSpace(IntPtr handle)
+        {
+            NativeMethods.cpHastySpaceFree(handle);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/IDebugDraw.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/IDebugDraw.cs
new file mode 100644 (file)
index 0000000..2ea82a5
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Interface to draw debug primitives (circle, point, segment).
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public interface IDebugDraw
+    {
+        /// <summary>
+        /// Draw stroked circle.
+        /// </summary>
+        void DrawCircle(Vect pos, double angle, double radius, DebugColor outlineColor, DebugColor fillColor);
+
+        /// <summary>
+        /// Draws a line segment.
+        /// </summary>
+        void DrawSegment(Vect a, Vect b, DebugColor color);
+
+        /// <summary>
+        /// Draws a thick line segment.
+        /// </summary>
+        void DrawFatSegment(Vect a, Vect b, double radius, DebugColor outlineColor, DebugColor fillColor);
+
+        /// <summary>
+        /// Draws a convex polygon.
+        /// </summary>
+        void DrawPolygon(Vect[] vectors, double radius, DebugColor outlineColor, DebugColor fillColor);
+
+        /// <summary>
+        /// Draws a dot.
+        /// </summary>
+        void DrawDot(double size, Vect pos, DebugColor color);
+
+        /// <summary>
+        /// Returns a color for a given shape. This gives you an opportunity to color shapes based
+        /// on how they are used in your engine.
+        /// </summary>
+        DebugColor ColorForShape(Shape shape);
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/MarchData.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/MarchData.cs
new file mode 100644 (file)
index 0000000..c5e5d76
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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
+{
+    /// <summary>
+    /// March data used for <see cref="AutoGeometry"/>.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class MarchData
+    {
+        /// <summary>
+        /// The bounding box.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public BoundingBox BoundingBox { get; set; }
+
+        /// <summary>
+        /// The number of horizontal samples.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int XSamples { get; set; }
+
+        /// <summary>
+        /// The number of vertical samples.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int YSamples { get; set; }
+
+        /// <summary>
+        /// The threshold.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Threshold { get; set; }
+
+        /// <summary>
+        /// Callback for sampling/
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Func<Vect, object, double> SampleFunction { get; set; }
+
+        /// <summary>
+        /// Callback for segmentation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Action<Vect, Vect, object> SegmentFunction { get; set; }
+
+        /// <summary>
+        /// User sample data.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object SampleData { get; set; }
+
+        /// <summary>
+        /// User segmentation data.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object SegmentData { get; set; }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/PointQueryInfo.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/PointQueryInfo.cs
new file mode 100644 (file)
index 0000000..aead09b
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * 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
+{
+    /// <summary>
+    /// <see cref="PointQueryInfo"/> holds the result of a point query made on a <see cref="Shape"/>
+    /// or <see cref="Space"/>.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public sealed class PointQueryInfo : IEquatable<PointQueryInfo>
+    {
+#pragma warning disable IDE0032
+        private readonly Shape shape;
+        private readonly Vect point;
+        private readonly double distance;
+        private readonly Vect gradient;
+#pragma warning restore IDE0032
+
+        /// <summary>
+        /// The nearest shape, None if no shape was within range.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Shape Shape => shape;
+
+        /// <summary>
+        /// The closest point on the shape’s surface (in world space coordinates).
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Point => point;
+
+        /// <summary>
+        /// The distance to the point. The distance is negative if the point is inside the shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Distance => distance;
+
+        /// <summary>
+        /// The gradient of the signed distance function.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Gradient => gradient;
+
+        /// <summary>
+        /// Create a <see cref="PointQueryInfo"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public PointQueryInfo(Shape s, Vect p, double d, Vect g)
+        {
+            shape = s;
+            point = p;
+            distance = d;
+            gradient = g;
+        }
+
+        /// <summary>
+        /// Return true if this <see cref="PointQueryInfo"/> object is reference-equal to the given
+        /// object.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override bool Equals(object obj)
+        {
+            var other = obj as PointQueryInfo;
+
+            if (other == null)
+            {
+                return false;
+            }
+
+            return this == other;
+        }
+
+        /// <summary>
+        /// Get the hash code.
+        /// </summary>
+        /// <returns></returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override int GetHashCode()
+        {
+            return shape.Handle.ToInt32() ^
+                point.GetHashCode() ^
+                distance.GetHashCode() ^
+                (gradient.GetHashCode() << 4);
+        }
+
+        /// <summary>
+        /// Return true if this <see cref="PointQueryInfo"/> object is reference-equal to the given
+        /// object.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator ==(PointQueryInfo left, PointQueryInfo right)
+        {
+            if (ReferenceEquals(left, null))
+            {
+                return ReferenceEquals(right, null);
+            }
+
+            return left.Equals(right);
+        }
+
+        /// <summary>
+        /// Return true if this <see cref="PointQueryInfo"/> object is not reference-equal to the
+        /// given object.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator !=(PointQueryInfo a, PointQueryInfo b)
+        {
+            return !(a == b);
+        }
+
+        internal static PointQueryInfo FromQueryInfo(cpPointQueryInfo queryInfo)
+        {
+            var shape = Shape.FromHandle(queryInfo.shape);
+
+            return new PointQueryInfo(
+                shape,
+                queryInfo.point,
+                queryInfo.distance,
+                queryInfo.gradient);
+        }
+
+        /// <summary>
+        /// Return true if this <see cref="PointQueryInfo"/> object's distance is within
+        /// <see cref="Single.Epsilon"/> of the other and all other fields are equivalent.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Equals(PointQueryInfo other)
+        {
+            if (ReferenceEquals(other, null) ||
+                shape.Handle != other.shape.Handle ||
+                point != other.point ||
+                gradient != other.gradient)
+            {
+                return false;
+            }
+
+            return Math.Abs(distance - other.distance) < float.Epsilon;
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/SegmentQueryInfo.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/SegmentQueryInfo.cs
new file mode 100644 (file)
index 0000000..2a97790
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * 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
+{
+    /// <summary>
+    /// Segment queries return where a shape was hit and its surface normal at the point of contact.
+    /// Use <see cref="SegmentQueryInfo.Shape"/> == null to test if a shape was hit. Segment queries
+    /// are like ray casting, but because not all spatial indexes allow processing infinitely long
+    /// ray queries, it's limited to segments. In practice, this is still very fast and you don’t
+    /// need to worry too much about the performance as long as you aren’t using extremely long
+    /// segments for your queries.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public sealed class SegmentQueryInfo : IEquatable<SegmentQueryInfo>
+    {
+#pragma warning disable IDE0032
+        private readonly Shape shape;
+        private readonly Vect point;
+        private readonly Vect normal;
+        private readonly double alpha;
+#pragma warning restore IDE0032
+
+        /// <summary>
+        /// Shape that was hit, or None if no collision occured.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Shape Shape => shape;
+
+        /// <summary>
+        /// The point of impact.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Point => point;
+
+        /// <summary>
+        /// The normal of the surface that was hit.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Normal => normal;
+
+        /// <summary>
+        /// The normalized distance along the query segment in the range [0, 1]
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Alpha => alpha;
+
+        /// <summary>
+        /// Construct a Segment query info.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public SegmentQueryInfo(Shape s, Vect p, Vect n, double a)
+        {
+            shape = s;
+            point = p;
+            normal = n;
+            alpha = a;
+        }
+
+        /// <summary>
+        /// Return true if the given object is reference-equal to this one.
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override bool Equals(object obj)
+        {
+            var other = obj as SegmentQueryInfo;
+
+            if (other == null)
+            {
+                return false;
+            }
+
+            return this == other;
+        }
+
+        /// <summary>
+        /// Return true if both objects are reference-equal to each other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator ==(SegmentQueryInfo left, SegmentQueryInfo right)
+        {
+            if (ReferenceEquals(left, null))
+            {
+                return ReferenceEquals(right, null);
+            }
+
+            return left.Equals(right);
+        }
+
+        /// <summary>
+        /// Return true if both objects are not reference-equal to each other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator !=(SegmentQueryInfo a, SegmentQueryInfo b)
+        {
+            return !(a == b);
+        }
+
+        /// <summary>
+        /// Create a SegmentQuery from a native struct cpSegmentQueryInfo.
+        /// </summary>
+        internal static SegmentQueryInfo FromQueryInfo(cpSegmentQueryInfo queryInfo)
+        {
+            Shape shape;
+
+            if (queryInfo.shape == IntPtr.Zero)
+            {
+                shape = null;
+            }
+            else
+            {
+                shape = Shape.FromHandle(queryInfo.shape);
+            }
+
+            return new SegmentQueryInfo(
+                shape,
+                queryInfo.point,
+                queryInfo.normal,
+                queryInfo.alpha);
+        }
+
+        /// <summary>
+        /// Return true if the fields in both objects are equivalent and the <see cref="alpha"/>
+        /// field is within <see cref="Single.Epsilon"/> of the other's.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Equals(SegmentQueryInfo other)
+        {
+            if (ReferenceEquals(other, null) ||
+                shape?.Handle != other.shape?.Handle ||
+                point != other.point ||
+                normal != other.normal)
+            {
+                return false;
+            }
+
+            return Math.Abs(alpha - other.alpha) < float.Epsilon;
+        }
+
+        /// <summary>
+        /// Get the hash code.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override int GetHashCode()
+        {
+            var hashCode = -1275187100;
+            hashCode = hashCode * -1521134295 + shape.GetHashCode();
+            hashCode = hashCode * -1521134295 + point.GetHashCode();
+            hashCode = hashCode * -1521134295 + normal.GetHashCode();
+            hashCode = hashCode * -1521134295 + alpha.GetHashCode();
+            return hashCode;
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/ShapeFilter.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ShapeFilter.cs
new file mode 100755 (executable)
index 0000000..45cb76b
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright(c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Fast collision filtering type that is used to determine if two objects collide before calling collision or query callbacks.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    [StructLayout(LayoutKind.Sequential)]
+    public struct ShapeFilter
+    {
+        private static readonly UIntPtr no_group = (UIntPtr)0;
+        private static readonly uint all_categories = (~(uint)0);
+        
+        private static readonly ShapeFilter filter_all = new ShapeFilter(no_group, all_categories, all_categories);
+        private static readonly ShapeFilter filter_none = new ShapeFilter(no_group, ~all_categories, ~all_categories);
+
+        private UIntPtr group;
+        private uint categories;
+        private uint mask;
+        /// <summary>
+        /// Group value 
+        /// Two objects with the same non-zero group value do not collide.
+        /// This is generally used to group objects in a composite object together to disable self collisions. 
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public UIntPtr Group
+        {
+            get => group;
+            set => group = value;
+        }
+
+        /// <summary>
+        /// Categories value
+        /// A bitmask of user definable categories that this object belongs to.
+        /// The category/mask combinations of both objects in a collision must agree for a collision to occur.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public uint Categories
+        {
+            get => categories;
+            set => categories = value;
+        }
+
+        /// <summary>
+        /// Mask value
+        /// A bitmask of user definable category types that this object object collides with.
+        /// The category/mask combinations of both objects in a collision must agree for a collision to occur.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public uint Mask
+        {
+            get => mask;
+            set => mask = value;
+        }
+
+        /// <summary>
+        /// Create a shape filter.
+        /// </summary>
+        /// <param name="group"></param>
+        /// <param name="categories"></param>
+        /// <param name="mask"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public ShapeFilter(UIntPtr group, uint categories, uint mask)
+        {
+            this.group = group;
+            this.categories = categories;
+            this.mask = mask;
+        }
+
+        /// <summary>
+        /// Value for signifying that a shape is in no group.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static UIntPtr NO_GROUP => no_group;
+
+        /// <summary>
+        /// Value for signifying that a shape is in every layer.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static uint ALL_CATEGORIES => all_categories;
+
+        /// <summary>
+        /// Collision filter value for a shape that will collide with anything except FILTER_NONE.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static ShapeFilter FILTER_ALL => filter_all;
+
+        /// <summary>
+        /// Collision filter value for a shape that does not collide with anything.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static ShapeFilter FILTER_NONE => filter_none;
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Box.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Box.cs
new file mode 100644 (file)
index 0000000..1ffd9a1
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// A retangular shape shape 
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class Box : Shape
+    {
+        /// <summary>
+        /// Create and initialize a box polygon shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Box(Body body, double width, double height, double radius)
+            : base(NativeMethods.cpBoxShapeNew(body.Handle, width, height, radius))
+        {
+
+        }
+
+        /// <summary>
+        /// Create and initialize an offset box polygon shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Box(Body body, BoundingBox box, double radius)
+            : base(NativeMethods.cpBoxShapeNew2(body.Handle, box, radius))
+        {
+
+        }
+
+        /// <summary>
+        /// Calculate the moment of inertia for a solid box.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static double MomentForBox(double mass, double width, double height)
+        {
+            return NativeMethods.cpMomentForBox(mass, width, height);
+        }
+
+        /// <summary>
+        /// Calculate the moment of inertia for a solid box.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static double MomentForBox(double mass, BoundingBox boundingBox)
+        {
+            return NativeMethods.cpMomentForBox2(mass, boundingBox);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Circle.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Circle.cs
new file mode 100644 (file)
index 0000000..252cf67
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// A circle shape defined by a radius
+    /// This is the fastest and simplest collision shape
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class Circle : Shape
+    {
+        /// <summary>
+        /// Create and initialize a circle polygon shape.
+        /// </summary>
+        /// <param name="body">The body to attach the circle to.</param>
+        /// <param name="radius">The radius of the circle.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Circle(Body body, double radius)
+            : this(body, radius, Vect.Zero)
+        {
+        }
+
+        /// <summary>
+        /// Create and initialize an offset circle polygon shape.
+        /// </summary>
+        /// <param name="body">The body to attach the circle to.</param>
+        /// <param name="radius">The radius of the circle.</param>
+        /// <param name="offset">
+        /// The offset from the body's center of gravity in coordinates local to the body.
+        /// </param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Circle(Body body, double radius, Vect offset)
+            : base(NativeMethods.cpCircleShapeNew(body.Handle, radius, offset))
+        {
+        }
+
+        /// <summary>
+        /// Get the offset of the circle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Offset => NativeMethods.cpCircleShapeGetOffset(Handle);
+
+        /// <summary>
+        ///  Get the radius of the circle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Radius => NativeMethods.cpCircleShapeGetRadius(Handle);
+
+        /// <summary>
+        /// Get the calculated area of the circle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public new double Area => AreaForCircle(0.0, Radius);
+
+        /// <summary>
+        /// Calculate the moment of the circle for the given mass.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double MomentForMass(double mass)
+        {
+            return MomentForCircle(mass, Radius, Offset);
+        }
+
+        /// <summary>
+        /// Calculate the moment of inertia for the circle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static double MomentForCircle(double mass, double innerRadius, double radius, Vect offset)
+        {
+            return NativeMethods.cpMomentForCircle(mass, innerRadius, radius, offset);
+        }
+
+        /// <summary>
+        /// Calculate the moment of inertia for the circle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static double MomentForCircle(double mass, double radius, Vect offset)
+        {
+            return NativeMethods.cpMomentForCircle(mass, 0.0, radius, offset);
+        }
+
+        /// <summary>
+        /// Calculate the area of a circle or donut.
+        /// </summary>
+        /// <param name="innerRadius">
+        /// The radius of the 'donut hole', which defines the area missing.
+        /// </param>
+        /// <param name="radius">
+        /// The outer radius of the donut. This should be greater than the
+        /// <paramref name="innerRadius"/>.
+        /// </param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static double AreaForCircle(double innerRadius, double radius)
+        {
+            return NativeMethods.cpAreaForCircle(innerRadius, radius);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Polygon.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Polygon.cs
new file mode 100644 (file)
index 0000000..986f70f
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * 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.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// A polygon shape composed of connected vertices.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class Polygon : Shape
+    {
+        /// <summary>
+        /// A convex polygon shape. It's the slowest, but most flexible collision shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Polygon(Body body, IReadOnlyList<Vect> verts, Transform transform, double radius)
+            : base(CreatePolygonShape(body, verts, transform, radius))
+        {
+        }
+
+        /// <summary>
+        /// Allocate and initialize a polygon shape with rounded corners.
+        /// The vertexes must be convex with a counter-clockwise winding.
+        /// </summary>
+        /// <param name="body"></param>
+        /// <param name="verts"></param>
+        /// <param name="radius"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Polygon(Body body, Vect[] verts, double radius)
+            : base(CreatePolygonShape(body, verts, radius))
+        {
+
+        }
+
+        private static IntPtr CreatePolygonShape(Body body, IReadOnlyList<Vect> verts, Transform transform, double radius)
+        {
+            Debug.Assert(verts.Count > 2);
+
+            IntPtr ptrVectors = NativeInterop.StructureArrayToPtr(verts);
+
+            IntPtr handle = NativeMethods.cpPolyShapeNew(body.Handle, verts.Count, ptrVectors, transform, radius);
+
+            NativeInterop.FreeStructure(ptrVectors);
+
+            return handle;
+        }
+
+        private static IntPtr CreatePolygonShape(Body body, Vect[] verts, double radius)
+        {
+            Debug.Assert(verts.Length > 2);
+
+            IntPtr ptrVectors = NativeInterop.StructureArrayToPtr(verts);
+
+            IntPtr handle = NativeMethods.cpPolyShapeNewRaw(body.Handle, verts.Length, ptrVectors, radius);
+
+            NativeInterop.FreeStructure(ptrVectors);
+
+            return handle;
+        }
+
+        /// <summary>
+        /// Get the number of vertices in a polygon shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int Count => NativeMethods.cpPolyShapeGetCount(Handle);
+
+        /// <summary>
+        /// Get the <paramref name="i"/>th vertex of a polygon shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect GetVertex(int i)
+        {
+            return NativeMethods.cpPolyShapeGetVert(Handle, i);
+        }
+
+        /// <summary>
+        /// Get the vertices of the polygon.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<Vect> Vertices
+        {
+            get
+            {
+                int count = Count;
+                if (count == 0)
+                    return Array.Empty<Vect>();
+
+                Vect[] vertices = new Vect[count];
+
+                for (int i = 0; i < count; i++)
+                {
+                    vertices[i] = GetVertex(i);
+                }
+
+                return vertices;
+            }
+        }
+
+        /// <summary>
+        /// Get the radius of the polygon.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Radius => NativeMethods.cpPolyShapeGetRadius(Handle);
+
+        /// <summary>
+        ///  Get and calculate the signed area of this polygon. Vertices specified such that they connect in
+        ///  a clockwise fashion (called winding) give a positive area measurement. This is probably
+        ///  backwards to what you might expect.
+        /// </summary>
+
+        /// <summary>
+        /// Get and calculate the signed area of the polygon.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public new double Area => AreaForPoly(Vertices, Radius);
+
+        /// <summary>
+        /// Get and calculate the centroid of the polygon.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Centroid => CentroidForPoly(Vertices);
+
+        /// <summary>
+        /// Calculate the moment of inertia for a solid polygon shape assuming its center of gravity
+        /// is at its centroid. The offset is added to each vertex.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static double MomentForPolygon(double mass, IReadOnlyList<Vect> vertices, Vect offset, double radius)
+        {
+            IntPtr verticesPtr = NativeInterop.StructureArrayToPtr(vertices);
+            double moment = NativeMethods.cpMomentForPoly(mass, vertices.Count, verticesPtr, offset, radius);
+
+            NativeInterop.FreeStructure(verticesPtr);
+
+            return moment;
+        }
+
+        /// <summary>
+        /// Calculate the signed area of this polygon. Vertices specified such that they connect in
+        ///  a clockwise fashion (called winding) give a positive area measurement. This is probably
+        ///  backwards to what you might expect.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static double AreaForPoly(IReadOnlyList<Vect> vertices, double radius)
+        {
+            IntPtr verticesPtr = NativeInterop.StructureArrayToPtr(vertices);
+
+            double area = NativeMethods.cpAreaForPoly(vertices.Count, verticesPtr, radius);
+
+            NativeInterop.FreeStructure(verticesPtr);
+
+            return area;
+        }
+
+        /// <summary>
+        /// Calculate the natural centroid of a polygon.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Vect CentroidForPoly(IReadOnlyList<Vect> vertices)
+        {
+            IntPtr verticesPtr = NativeInterop.StructureArrayToPtr(vertices);
+
+            Vect centroid = NativeMethods.cpCentroidForPoly(vertices.Count, verticesPtr);
+
+            NativeInterop.FreeStructure(verticesPtr);
+
+            return centroid;
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Segment.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Segment.cs
new file mode 100644 (file)
index 0000000..66e8a4b
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// A line segment shape between two points, which is mainly useful when it behaves statically,
+    /// though it can be beveled to give it thickness.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class Segment : Shape
+    {
+        /// <summary>
+        /// Create a line segment.
+        /// </summary>
+        /// <param name="body">The body to attach the segment to.</param>
+        /// <param name="a">The first endpoint of the segment.</param>
+        /// <param name="b">The second endpoint of the segment.</param>
+        /// <param name="radius">The thickness of the segment.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Segment(Body body, Vect a, Vect b, double radius)
+            : base(NativeMethods.cpSegmentShapeNew(body.Handle, a, b, radius))
+        {
+        }
+
+        /// <summary>
+        /// Let Chipmunk know about the geometry of adjacent segments to avoid colliding with endcaps.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetNeighbors(Vect prev, Vect next)
+        {
+            NativeMethods.cpSegmentShapeSetNeighbors(Handle, prev, next);
+        }
+
+        /// <summary>
+        /// Get the first endpoint of the segment shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect A => NativeMethods.cpSegmentShapeGetA(Handle);
+
+        /// <summary>
+        /// Get the second endpoint of the segment shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect B => NativeMethods.cpSegmentShapeGetB(Handle);
+
+        /// <summary>
+        /// Get the normal of the segment shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Normal => NativeMethods.cpSegmentShapeGetNormal(Handle);
+
+        /// <summary>
+        /// Get the segment radius.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Radius => NativeMethods.cpSegmentShapeGetRadius(Handle);
+
+        /// <summary>
+        /// Calculate the area of the segment, assuming a thickness has been provided. The area is
+        /// calculated assuming the endpoints would be rounded, like a capsule.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public new double Area => AreaForSegment(A, B, Radius);
+
+        /// <summary>
+        /// Calculate the moment of inertia of the segment.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double MomentForMass(double mass)
+        {
+            return MomentForSegment(mass, A, B, Radius);
+        }
+
+        /// <summary>
+        /// Calculate the moment of inertia for the line segment.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static double MomentForSegment(double mass, Vect a, Vect b, double radius)
+        {
+            return NativeMethods.cpMomentForSegment(mass, a, b, radius);
+        }
+
+        /// <summary>
+        /// Calculate the area of a segment, assuming a thickness has been provided. The area is
+        /// calculated assuming the endpoints would be rounded, like a capsule.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static double AreaForSegment(Vect a, Vect b, double radius)
+        {
+            return NativeMethods.cpAreaForSegment(a, b, radius);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Shape.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Shape.cs
new file mode 100644 (file)
index 0000000..19259a0
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * 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;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using cpBody = System.IntPtr;
+using cpDataPointer = System.IntPtr;
+using cpShape = System.IntPtr;
+using cpSpace = System.IntPtr;
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Abstract Chipmunk Shape
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public abstract class Shape : IDisposable
+    {
+#pragma warning disable IDE0032
+        private readonly cpShape shape;
+#pragma warning restore IDE0032
+
+        /// <summary>
+        /// Create a Shape with the given <paramref name="shapeHandle"/>.
+        /// </summary>
+        /// <param name="shapeHandle">The native shape handle.</param>
+        internal protected Shape(cpShape shapeHandle)
+        {
+            shape = shapeHandle;
+            RegisterUserData();
+        }
+
+        /// <summary>
+        /// The native handle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public cpShape Handle => shape;
+
+        /// <summary>
+        /// Register managed object in the native user data.
+        /// </summary>
+        private void RegisterUserData()
+        {
+            cpDataPointer pointer = NativeInterop.RegisterHandle(this);
+            NativeMethods.cpShapeSetUserData(shape, pointer);
+        }
+
+        void ReleaseUserData()
+        {
+            cpDataPointer pointer = NativeMethods.cpShapeGetUserData(shape);
+            NativeInterop.ReleaseHandle(pointer);
+        }
+
+        /// <summary>
+        /// Get a managed Shape from a native handle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Shape FromHandle(cpShape shape)
+        {
+            cpDataPointer handle = NativeMethods.cpShapeGetUserData(shape);
+
+            return NativeInterop.FromIntPtr<Shape>(handle);
+        }
+
+        /// <summary>
+        /// Dispose the shape.
+        /// </summary>
+        protected virtual void Dispose(bool dispose)
+        {
+            if (!dispose)
+            {
+                Debug.WriteLine("Disposing shape {0} on finalizer... (consider Dispose explicitly)", shape);
+            }
+
+            Free();
+        }
+
+        /// <summary>
+        /// Destroy and free the shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Free()
+        {
+            ReleaseUserData();
+            NativeMethods.cpShapeFree(shape);
+        }
+
+        /// <summary>
+        /// Destroy and free the shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        // Shape properties
+
+        /// <summary>
+        /// Arbitrary user data.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object Data { get; set; }
+
+        /// <summary>
+        /// Gets the space that this shape is registered within.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Space Space
+        {
+            get
+            {
+                cpSpace space = NativeMethods.cpShapeGetSpace(shape);
+                return Space.FromHandleSafe(space);
+            }
+        }
+
+        /// <summary>
+        /// The body that this shape is associated with.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Body Body
+        {
+            get
+            {
+                cpBody body = NativeMethods.cpShapeGetBody(shape);
+                return Body.FromHandleSafe(body);
+            }
+            set
+            {
+                Debug.Assert(value != null && Space == null,
+                    "Body can't be null and you can only change body if the shape wasn't added to space");
+
+                NativeMethods.cpShapeSetBody(shape, value.Handle);
+            }
+        }
+
+        /// <summary>
+        /// Mass of the shape to have Chipmunk calculate mass properties for you.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Mass
+        {
+            get => NativeMethods.cpShapeGetMass(shape);
+            set => NativeMethods.cpShapeSetMass(shape, value);
+        }
+
+        /// <summary>
+        /// Density of the shape if you are having Chipmunk calculate mass properties for you.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Density
+        {
+            get => NativeMethods.cpShapeGetDensity(shape);
+            set => NativeMethods.cpShapeSetDensity(shape, value);
+        }
+
+        /// <summary>
+        /// Get the calculated moment of inertia for the shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Moment => NativeMethods.cpShapeGetMoment(shape);
+
+        /// <summary>
+        /// Get the calculated area of the shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Area => NativeMethods.cpShapeGetArea(shape);
+
+        /// <summary>
+        /// Get the center of gravity of the shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect CenterOfGravity => NativeMethods.cpShapeGetCenterOfGravity(shape);
+
+        /// <summary>
+        /// Get the bounding box that contains the shape, given it's current position and angle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public BoundingBox BoundingBox => NativeMethods.cpShapeGetBB(shape);
+
+        /// <summary>
+        /// Whether the shape is a sensor.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Sensor
+        {
+            get => NativeMethods.cpShapeGetSensor(shape) != 0;
+            set => NativeMethods.cpShapeSetSensor(shape, value ? (byte)1 : (byte)0);
+        }
+
+        /// <summary>
+        /// The elasticity of the shape. A value of 0.0 is perfectly inelastic (no bounce). A
+        /// value of 1.0 is perfectly elastic. Due to simulation inaccuracy, values of 1.0 or
+        /// greater are not recommended.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Elasticity
+        {
+            get => NativeMethods.cpShapeGetElasticity(shape);
+            set => NativeMethods.cpShapeSetElasticity(shape, value);
+        }
+
+        /// <summary>
+        /// The friction coefficient, following the Coulomb friction model. A value of 0.0 is
+        /// frictionless. https://en.wikipedia.org/wiki/Friction#Coefficient_of_friction
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Friction
+        {
+            get => NativeMethods.cpShapeGetFriction(shape);
+            set => NativeMethods.cpShapeSetFriction(shape, value);
+        }
+
+        /// <summary>
+        ///  The surface velocity of the object. Useful for creating conveyor belts or players that
+        ///  move around. This value is only used when calculating friction, not resolving the
+        ///  collision.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect SurfaceVelocity
+        {
+            get => NativeMethods.cpShapeGetSurfaceVelocity(shape);
+            set => NativeMethods.cpShapeSetSurfaceVelocity(shape, value);
+        }
+
+        /// <summary>
+        /// An arbitrary value representing the collision type of this shape. Only shapes with like
+        /// collision types will collide.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int CollisionType
+        {
+            get => (int)(uint)NativeMethods.cpShapeGetCollisionType(shape);
+            set => NativeMethods.cpShapeSetCollisionType(shape, (UIntPtr)(uint)value);
+        }
+
+        /// <summary>
+        /// An arbitrary value representing the collision type of this shape. Only shapes with like
+        /// collision types will collide.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ShapeFilter Filter
+        {
+            get => (ShapeFilter)NativeMethods.cpShapeGetFilter(shape);
+            set => NativeMethods.cpShapeSetFilter(shape, (ShapeFilter)value);
+        }
+
+        /// <summary>
+        /// Update, cache and return the bounding box of a shape based on the body it's attached to.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public BoundingBox CacheBB()
+        {
+            return NativeMethods.cpShapeCacheBB(shape);
+        }
+
+        /// <summary>
+        /// Update, cache and return the bounding box of a shape with an explicit transformation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public BoundingBox Update(Transform transform)
+        {
+            return NativeMethods.cpShapeUpdate(shape, transform);
+        }
+
+        /// <summary>
+        /// Finds the point on the surface of the shape which is closest to the given point.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public PointQueryInfo PointQuery(Vect point)
+        {
+            var output = new cpPointQueryInfo();
+            NativeMethods.cpShapePointQuery(shape, point, ref output);
+
+            return PointQueryInfo.FromQueryInfo(output);
+        }
+
+        /// <summary>
+        /// Perform a segment query against a shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public SegmentQueryInfo SegmentQuery(Vect a, Vect b, double radius)
+        {
+            var queryInfo = new cpSegmentQueryInfo();
+            NativeMethods.cpShapeSegmentQuery(shape, a, b, radius, ref queryInfo);
+
+            return SegmentQueryInfo.FromQueryInfo(queryInfo);
+        }
+
+        /// <summary>
+        /// Get the contact information between two shapes.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ContactPointSet Collide(Shape other)
+        {
+            Debug.Assert(Marshal.SizeOf(typeof(cpContactPointSet)) == 104,
+                "check Chipmunk sizeof(cpContactPointSet)");
+
+            cpContactPointSet contactPointSet = NativeMethods.cpShapesCollide(shape, other.Handle);
+
+            return ContactPointSet.FromContactPointSet(contactPointSet);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs
new file mode 100755 (executable)
index 0000000..df8c661
--- /dev/null
@@ -0,0 +1,851 @@
+/*
+ * 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.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using cpBody = System.IntPtr;
+using cpCollisionHandlerPointer = System.IntPtr;
+using cpCollisionType = System.UIntPtr;
+using cpConstraint = System.IntPtr;
+using cpDataPointer = System.IntPtr;
+using cpShape = System.IntPtr;
+using cpSpace = System.IntPtr;
+using voidptr_t = System.IntPtr;
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+using ObjCRuntime;
+#endif
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Spaces in Chipmunk are the basic unit of simulation. You add rigid bodies, shapes, and
+    /// constraints to the space and then step them all forward through time together.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class Space : IDisposable
+    {
+#pragma warning disable IDE0032
+        private readonly cpSpace space;
+#pragma warning restore IDE0032
+
+        /// <summary>
+        /// Native handle cpSpace.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public cpSpace Handle => space;
+
+        /// <summary>
+        /// Create a new Space object.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Space()
+        {
+            space = NativeMethods.cpSpaceNew();
+            RegisterUserData();
+        }
+
+        /// <summary>
+        /// Create a space from a native Handle (used by derived classes).
+        /// </summary>
+        /// <param name="handle"></param>
+        protected internal Space(cpSpace handle)
+        {
+            space = handle;
+            RegisterUserData();
+        }
+
+        /// <summary>
+        /// Destroys and frees.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Free()
+        {
+            ReleaseUserData();
+            FreeSpace(space);
+        }
+
+        /// <summary>
+        /// Destroy and free space.
+        /// </summary>
+        /// <param name="handle"></param>
+        protected virtual void FreeSpace(cpSpace handle)
+        {
+            NativeMethods.cpSpaceFree(handle);
+        }
+
+        /// <summary>
+        /// Destroy and free space.
+        /// </summary>
+        protected virtual void Dispose(bool disposing)
+        {
+            Free();
+        }
+        /// <summary>
+        /// Disposes the Space object.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        void RegisterUserData()
+        {
+            cpDataPointer pointer = NativeInterop.RegisterHandle(this);
+            NativeMethods.cpSpaceSetUserData(space, pointer);
+        }
+
+        void ReleaseUserData()
+        {
+            cpDataPointer pointer = NativeMethods.cpSpaceGetUserData(space);
+            NativeInterop.ReleaseHandle(pointer);
+        }
+
+        /// <summary>
+        /// Get a Space object from native cpSpace handle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Space FromHandle(cpSpace space)
+        {
+            cpDataPointer handle = NativeMethods.cpSpaceGetUserData(space);
+            return NativeInterop.FromIntPtr<Space>(handle);
+        }
+
+        /// <summary>
+        /// Get a Space object from native cpSpace handle, but return null if the handle is 0.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Space FromHandleSafe(cpSpace space)
+        {
+            if (space == IntPtr.Zero)
+            {
+                return null;
+            }
+
+            return FromHandle(space);
+        }
+
+        // Properties
+
+        /// <summary>
+        /// Arbitrary user data.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object Data { get; set; }
+
+        /// <summary>
+        /// Number of iterations to use in the impulse solver to solve contacts and other
+        /// constraints.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int Iterations
+        {
+            get => NativeMethods.cpSpaceGetIterations(space);
+            set => NativeMethods.cpSpaceSetIterations(space, value);
+        }
+
+        /// <summary>
+        /// Gravity to pass to rigid bodies when integrating velocity. 
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Gravity
+        {
+            get => NativeMethods.cpSpaceGetGravity(space);
+            set => NativeMethods.cpSpaceSetGravity(space, value);
+        }
+
+        /// <summary>
+        /// Damping rate expressed as the fraction of velocity that bodies retain each second. A
+        /// value of 0.9 would mean that each body's velocity will drop 10% per second. The default
+        /// value is 1.0, meaning no damping is applied. Note: This damping value is different than
+        /// those of <see cref="DampedSpring"/> and <see cref="DampedRotarySpring"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Damping
+        {
+            get => NativeMethods.cpSpaceGetDamping(space);
+            set => NativeMethods.cpSpaceSetDamping(space, value);
+        }
+
+        /// <summary>
+        /// Speed threshold for a body to be considered idle. The default value of 0 means to let
+        /// the space guess a good threshold based on gravity. 
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double IdleSpeedThreshold
+        {
+            get => NativeMethods.cpSpaceGetIdleSpeedThreshold(space);
+            set => NativeMethods.cpSpaceSetIdleSpeedThreshold(space, value);
+        }
+
+        /// <summary>
+        /// Time a group of bodies must remain idle in order to fall asleep. Enabling sleeping also
+        /// implicitly enables the the contact graph. The default value of infinity disables the
+        /// sleeping algorithm. 
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double SleepTimeThreshold
+        {
+            get => NativeMethods.cpSpaceGetSleepTimeThreshold(space);
+            set => NativeMethods.cpSpaceSetSleepTimeThreshold(space, value);
+        }
+
+        /// <summary>
+        /// Amount of encouraged penetration between colliding shapes. This is used to reduce
+        /// oscillating contacts and keep the collision cache warm. Defaults to 0.1. If you have
+        /// poor simulation quality, increase this number as much as possible without allowing
+        /// visible amounts of overlap. 
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double CollisionSlop
+        {
+            get => NativeMethods.cpSpaceGetCollisionSlop(space);
+            set => NativeMethods.cpSpaceSetCollisionSlop(space, value);
+        }
+
+        /// <summary>
+        /// Determines how fast overlapping shapes are pushed apart.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double CollisionBias
+        {
+            get => NativeMethods.cpSpaceGetCollisionBias(space);
+            set => NativeMethods.cpSpaceSetCollisionBias(space, value);
+        }
+
+        /// <summary>
+        /// Number of frames that contact information should persist. Defaults to 3. There is
+        /// probably never a reason to change this value.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int CollisionPersistence
+        {
+            get => (int)NativeMethods.cpSpaceGetCollisionPersistence(space);
+            set => NativeMethods.cpSpaceSetCollisionPersistence(space, (uint)value);
+        }
+
+        /// <summary>
+        /// The Space provided static body for a given <see cref="Space"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Body StaticBody
+        {
+            get
+            {
+                cpBody bodyHandle = NativeMethods.cpSpaceGetStaticBody(space);
+                cpDataPointer gcHandle = NativeMethods.cpBodyGetUserData(bodyHandle);
+
+                if (gcHandle != IntPtr.Zero)
+                {
+                    return NativeInterop.FromIntPtr<Body>(gcHandle);
+                }
+
+                return new Body(bodyHandle);
+            }
+        }
+
+        /// <summary>
+        /// Returns the current (or most recent) time step used with the given space.
+        /// Useful from callbacks if your time step is not a compile-time global.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double CurrentTimeStep => NativeMethods.cpSpaceGetCurrentTimeStep(space);
+
+        /// <summary>
+        /// Returns true from inside a callback when objects cannot be added/removed.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsLocked => NativeMethods.cpSpaceIsLocked(space) != 0;
+
+
+        // Collision Handlers
+
+        /// <summary>
+        /// Create or return the existing collision handler that is called for all collisions that are
+        /// not handled by a more specific collision handler.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CollisionHandler GetOrCreateDefaultCollisionHandler()
+        {
+            cpCollisionHandlerPointer collisionHandle = NativeMethods.cpSpaceAddDefaultCollisionHandler(space);
+            return CollisionHandler.GetOrCreate(collisionHandle);
+        }
+
+
+        /// <summary>
+        /// Create or return the existing collision handler for the specified pair of collision
+        /// types. If wildcard handlers are used with either of the collision types, it's the
+        /// responsibility of the custom handler to invoke the wildcard handlers.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CollisionHandler GetOrCreateCollisionHandler(int typeA, int typeB)
+        {
+            uint utypeA = unchecked((uint)typeA);
+            uint utypeB = unchecked((uint)typeB);
+
+            cpCollisionType collisionTypeA = new cpCollisionType(utypeA);
+            cpCollisionType collisionTypeB = new cpCollisionType(utypeB);
+
+            cpCollisionHandlerPointer collisionHandle = NativeMethods.cpSpaceAddCollisionHandler(space, collisionTypeA, collisionTypeB);
+            return CollisionHandler.GetOrCreate(collisionHandle);
+        }
+
+
+        /// <summary>
+        /// Create or return the existing wildcard collision handler for the specified type.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CollisionHandler GetOrCreateWildcardHandler(int type)
+        {
+            cpCollisionHandlerPointer collisionHandle = NativeMethods.cpSpaceAddWildcardHandler(space, (cpCollisionType)type);
+            return CollisionHandler.GetOrCreate(collisionHandle);
+        }
+
+        /// <summary>
+        /// Add a collision shape to the simulation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void AddShape(Shape shape)
+        {
+            NativeMethods.cpSpaceAddShape(space, shape.Handle);
+        }
+
+        /// <summary>
+        /// Add a rigid body to the simulation. 
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void AddBody(Body body)
+        {
+            NativeMethods.cpSpaceAddBody(space, body.Handle);
+        }
+
+        /// <summary>
+        /// Add a constraint to the simulation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void AddConstraint(Constraint constraint)
+        {
+            NativeMethods.cpSpaceAddConstraint(space, constraint.Handle);
+        }
+
+        /// <summary>
+        /// Remove a collision shape from the simulation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void RemoveShape(Shape shape)
+        {
+            NativeMethods.cpSpaceRemoveShape(space, shape.Handle);
+        }
+
+        /// <summary>
+        /// Remove a rigid body from the simulation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void RemoveBody(Body body)
+        {
+            NativeMethods.cpSpaceRemoveBody(space, body.Handle);
+        }
+
+        /// <summary>
+        /// Remove a constraint from the simulation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void RemoveConstraint(Constraint constraint)
+        {
+            NativeMethods.cpSpaceRemoveConstraint(space, constraint.Handle);
+        }
+
+        /// <summary>
+        /// Test if a collision shape has been added to the space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Contains(Shape shape)
+        {
+            return NativeMethods.cpSpaceContainsShape(space, shape.Handle) != 0;
+        }
+
+        /// <summary>
+        /// Test if a rigid body has been added to the space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Contains(Body body)
+        {
+            return NativeMethods.cpSpaceContainsBody(space, body.Handle) != 0;
+        }
+
+        /// <summary>
+        /// Test if a constraint has been added to the space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Contains(Constraint constraint)
+        {
+            return NativeMethods.cpSpaceContainsConstraint(space, constraint.Handle) != 0;
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(PostStepFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void PostStepCallBack(cpSpace handleSpace, voidptr_t handleKey, voidptr_t handleData)
+        {
+            var space = FromHandle(handleSpace);
+            var key = NativeInterop.FromIntPtr<object>(handleKey);
+            var data = NativeInterop.FromIntPtr<PostStepCallbackInfo>(handleData);
+
+            Action<Space, object, object> callback = data.Callback;
+
+            callback(space, key, data.Data);
+
+            NativeInterop.ReleaseHandle(handleKey);
+            NativeInterop.ReleaseHandle(handleData);
+        }
+
+        private static PostStepFunction postStepCallBack = PostStepCallBack;
+
+        /// <summary>
+        /// Schedule a post-step callback to be called when <see cref="Step"/> finishes. You can
+        /// only register one callback per unique value for <paramref name="key"/>. Returns true
+        /// only if <paramref name="key"/> has never been scheduled before. It's possible to pass
+        /// null for <paramref name="callback"/> if you only want to mark <paramref name="key"/> as
+        /// being used.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool AddPostStepCallback(Action<Space, object, object> callback, object key, object data)
+        {
+            var info = new PostStepCallbackInfo(callback, data);
+
+            IntPtr dataHandle = NativeInterop.RegisterHandle(info);
+            IntPtr keyHandle = NativeInterop.RegisterHandle(key);
+
+            return NativeMethods.cpSpaceAddPostStepCallback(space, postStepCallBack.ToFunctionPointer(), keyHandle, dataHandle) != 0;
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpacePointQueryFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void EachPointQuery(cpShape shapeHandle, Vect point, double distance, Vect gradient, voidptr_t data)
+        {
+            var list = (List<PointQueryInfo>)GCHandle.FromIntPtr(data).Target;
+
+            var shape = Shape.FromHandle(shapeHandle);
+            var pointQuery = new PointQueryInfo(shape, point, distance, gradient);
+
+            list.Add(pointQuery);
+        }
+
+        private static SpacePointQueryFunction eachPointQuery = EachPointQuery;
+
+        /// <summary>
+        /// Get the shapes within a radius of the point location that are part of this space. The
+        /// filter is applied to the query and follows the same rules as the collision detection.
+        /// If a maxDistance of 0.0 is used, the point must lie inside a shape. Negative
+        /// <paramref name="maxDistance"/> is also allowed meaning that the point must be a under a
+        /// certain depth within a shape to be considered a match.
+        /// </summary>
+        /// <param name="point">Where to check for shapes in the space.</param>
+        /// <param name="maxDistance">Match only within this distance.</param>
+        /// <param name="filter">Only pick shapes matching the filter.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<PointQueryInfo> PointQuery(Vect point, double maxDistance, ShapeFilter filter)
+        {
+            var list = new List<PointQueryInfo>();
+            var gcHandle = GCHandle.Alloc(list);
+
+            NativeMethods.cpSpacePointQuery(space, point, maxDistance, filter, eachPointQuery.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle));
+
+            gcHandle.Free();
+            return list;
+        }
+
+        /// <summary>
+        /// Get the nearest shape within a radius of a point that is part of this space. The filter
+        /// is applied to the query and follows the same rules as the collision detection. If a
+        /// <paramref name="maxDistance"/> of 0.0 is used, the point must lie inside a shape.
+        /// Negative <paramref name="maxDistance"/> is also allowed, meaning that the point must be
+        /// under a certain depth within a shape to be considered a match.
+        /// </summary>
+        /// <param name="point">Where to check for collision in the space.</param>
+        /// <param name="maxDistance">Match only within this distance.</param>
+        /// <param name="filter">Only pick shapes matching the filter.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public PointQueryInfo PointQueryNearest(Vect point, double maxDistance, ShapeFilter filter)
+        {
+            var queryInfo = new cpPointQueryInfo();
+
+            cpShape shape = NativeMethods.cpSpacePointQueryNearest(space, point, maxDistance, filter, ref queryInfo);
+            if (shape == IntPtr.Zero)
+                return null;
+
+            return PointQueryInfo.FromQueryInfo(queryInfo);
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpaceSegmentQueryFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void EachSegmentQuery(cpShape shapeHandle, Vect point, Vect normal, double alpha, voidptr_t data)
+        {
+            var list = (List<SegmentQueryInfo>)GCHandle.FromIntPtr(data).Target;
+
+            var shape = Shape.FromHandle(shapeHandle);
+            var pointQuery = new SegmentQueryInfo(shape, point, normal, alpha);
+
+            list.Add(pointQuery);
+        }
+
+        private static SpaceSegmentQueryFunction eachSegmentQuery = EachSegmentQuery;
+
+        /// <summary>
+        /// Get the shapes within a capsule-shaped radius of a line segment that is part of this
+        /// space. The filter is applied to the query and follows the same rules as the collision
+        /// detection.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<SegmentQueryInfo> SegmentQuery(Vect start, Vect end, double radius, ShapeFilter filter)
+        {
+            var list = new List<SegmentQueryInfo>();
+            var gcHandle = GCHandle.Alloc(list);
+
+            NativeMethods.cpSpaceSegmentQuery(space, start, end, radius, filter, eachSegmentQuery.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle));
+
+            gcHandle.Free();
+            return list;
+        }
+
+        /// <summary>
+        /// Get the first shape within a capsule-shaped radius of a line segment that is part of
+        /// this space. The filter is applied to the query and follows the same rules as the
+        /// collision detection.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public SegmentQueryInfo SegmentQueryFirst(Vect start, Vect end, double radius, ShapeFilter filter)
+        {
+            var queryInfo = new cpSegmentQueryInfo();
+
+            cpShape shape = NativeMethods.cpSpaceSegmentQueryFirst(space, start, end, radius, filter, ref queryInfo);
+            if (shape == IntPtr.Zero)
+                return null;
+
+            return SegmentQueryInfo.FromQueryInfo(queryInfo);
+        }
+
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpaceBBQueryFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void EachBBQuery(cpShape shapeHandle, voidptr_t data)
+        {
+            var list = (List<Shape>)GCHandle.FromIntPtr(data).Target;
+
+            var shape = Shape.FromHandle(shapeHandle);
+
+            list.Add(shape);
+        }
+
+        private static SpaceBBQueryFunction eachBBQuery = EachBBQuery;
+
+
+        /// <summary>
+        /// Get all shapes within the axis-aligned bounding box that are part of this shape. The
+        /// filter is applied to the query and follows the same rules as the collision detection.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<Shape> BoundBoxQuery(BoundingBox bb, ShapeFilter filter)
+        {
+            var list = new List<Shape>();
+
+            var gcHandle = GCHandle.Alloc(list);
+
+            NativeMethods.cpSpaceBBQuery(space, bb, filter, eachBBQuery.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle));
+
+            gcHandle.Free();
+            return list;
+        }
+
+        /// <summary>
+        /// Get all bodies in the space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<Body> Bodies
+        {
+            get
+            {
+                int count = NativeMethods.cpSpaceGetBodyCount(space);
+
+                if (count == 0)
+                    return Array.Empty<Body>();
+
+                IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count);
+                NativeMethods.cpSpaceGetBodiesUserDataArray(space, ptrBodies);
+
+                IntPtr[] userDataArray = new IntPtr[count];
+
+                Marshal.Copy(ptrBodies, userDataArray, 0, count);
+
+                Marshal.FreeHGlobal(ptrBodies);
+
+                Body[] bodies = new Body[count];
+
+                for (int i = 0; i < count; i++)
+                {
+                    Body b = NativeInterop.FromIntPtr<Body>(userDataArray[i]);
+                    bodies[i] = b;
+                }
+
+                return bodies;
+            }
+        }
+
+        /// <summary>
+        /// Get dynamic bodies in the space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<Body> DynamicBodies
+        {
+            get
+            {
+                int count = NativeMethods.cpSpaceGetDynamicBodyCount(space);
+
+                if (count == 0)
+                    return Array.Empty<Body>();
+
+                IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count);
+                NativeMethods.cpSpaceGetDynamicBodiesUserDataArray(space, ptrBodies);
+
+                IntPtr[] userDataArray = new IntPtr[count];
+
+                Marshal.Copy(ptrBodies, userDataArray, 0, count);
+
+                Marshal.FreeHGlobal(ptrBodies);
+
+                Body[] bodies = new Body[count];
+
+                for (int i = 0; i < count; i++)
+                {
+                    Body b = NativeInterop.FromIntPtr<Body>(userDataArray[i]);
+                    bodies[i] = b;
+                }
+
+                return bodies;
+            }
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpaceObjectIteratorFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void EachShape(cpShape shapeHandle, voidptr_t data)
+        {
+            var list = (List<Shape>)GCHandle.FromIntPtr(data).Target;
+
+            var shape = Shape.FromHandle(shapeHandle);
+
+            list.Add(shape);
+        }
+
+        private static SpaceObjectIteratorFunction eachShape = EachShape;
+
+        /// <summary>
+        /// Get all shapes in the space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<Shape> Shapes
+        {
+            get
+            {
+                var list = new List<Shape>();
+
+                var gcHandle = GCHandle.Alloc(list);
+
+                NativeMethods.cpSpaceEachShape(space, eachShape.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle));
+
+                gcHandle.Free();
+
+                return list;
+            }
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpaceShapeQueryFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void ShapeQueryCallback(cpShape shape, IntPtr pointsPointer, voidptr_t data)
+        {
+            var list = (List<ContactPointSet>)GCHandle.FromIntPtr(data).Target;
+
+            var pointSet = NativeInterop.PtrToStructure<cpContactPointSet>(pointsPointer);
+
+            list.Add(ContactPointSet.FromContactPointSet(pointSet));
+        }
+
+        private static SpaceShapeQueryFunction shapeQueryCallback = ShapeQueryCallback;
+
+        /// <summary>
+        /// Get all shapes in the space that are overlapping the given shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<ContactPointSet> ShapeQuery(Shape shape)
+        {
+            var list = new List<ContactPointSet>();
+            var gcHandle = GCHandle.Alloc(list);
+
+            NativeMethods.cpSpaceShapeQuery(space, shape.Handle, shapeQueryCallback.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle));
+
+            gcHandle.Free();
+            return list;
+        }
+
+#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__
+#pragma warning disable CA1416 // Validate platform compatibility
+        [MonoPInvokeCallback(typeof(SpaceObjectIteratorFunction))]
+#pragma warning restore CA1416 // Validate platform compatibility
+#endif
+        private static void EachConstraint(cpConstraint constraintHandle, voidptr_t data)
+        {
+            var list = (List<Constraint>)GCHandle.FromIntPtr(data).Target;
+
+            var constraint = Constraint.FromHandle(constraintHandle);
+
+            list.Add(constraint);
+        }
+
+        private static SpaceObjectIteratorFunction eachConstraint = EachConstraint;
+
+
+        /// <summary>
+        /// Get all constraints in the space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<Constraint> Constraints
+        {
+            get
+            {
+                var list = new List<Constraint>();
+
+                var gcHandle = GCHandle.Alloc(list);
+
+                NativeMethods.cpSpaceEachConstraint(space, eachConstraint.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle));
+
+                gcHandle.Free();
+
+                return list;
+            }
+        }
+
+        /// <summary>
+        /// Update the collision detection info for the static shapes in the space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ReindexStatic()
+        {
+            NativeMethods.cpSpaceReindexStatic(space);
+        }
+
+        /// <summary>
+        /// Update the collision detection data for a specific shape in the space.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ReindexShape(Shape shape)
+        {
+            NativeMethods.cpSpaceReindexShape(space, shape.Handle);
+        }
+
+        /// <summary>
+        /// Update the collision detection data for all shapes attached to a body.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ReindexShapesForBody(Body body)
+        {
+            NativeMethods.cpSpaceReindexShapesForBody(space, body.Handle);
+        }
+
+        /// <summary>
+        /// Switch the space to use a spatial hash as its spatial index.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void UseSpatialHash(double dim, int count)
+        {
+            NativeMethods.cpSpaceUseSpatialHash(space, dim, count);
+        }
+
+        /// <summary>
+        /// Update the space for the given time step. Using a fixed time step is highly recommended.
+        /// Doing so will increase the efficiency of the contact persistence, requiring an order of
+        /// magnitude fewer iterations to resolve the collisions in the usual case. It is not the
+        /// same to call step 10 times with a dt of 0.1, or 100 times with a dt of 0.01 even if the
+        /// end result is that the simulation moved forward 100 units. Performing multiple calls
+        /// with a smaller dt creates a more stable and accurate simulation. Therefore, it sometimes
+        /// makes sense to have a little for loop around the step call.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void Step(double dt)
+        {
+            NativeMethods.cpSpaceStep(space, dt);
+        }
+
+        /// <summary>
+        /// Draw all objects in the space for debugging purposes.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void DebugDraw(IDebugDraw debugDraw)
+        {
+            DebugDraw(debugDraw, DebugDrawFlags.All, DebugDrawColors.Default);
+        }
+
+        /// <summary>
+        /// Draw all objects in the space for debugging purposes using flags.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void DebugDraw(IDebugDraw debugDraw, DebugDrawFlags flags)
+        {
+            DebugDraw(debugDraw, flags, DebugDrawColors.Default);
+        }
+
+        /// <summary>
+        /// Draw all objects in the space for debugging purposes using flags and colors.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void DebugDraw(IDebugDraw debugDraw, DebugDrawFlags flags, DebugDrawColors colors)
+        {
+            var debugDrawOptions = new cpSpaceDebugDrawOptions();
+            IntPtr debugDrawOptionsPointer = debugDrawOptions.AcquireDebugDrawOptions(debugDraw, flags, colors);
+
+            NativeMethods.cpSpaceDebugDraw(space, debugDrawOptionsPointer);
+
+            debugDrawOptions.ReleaseDebugDrawOptions(debugDrawOptionsPointer);
+        }
+
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Transform.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Transform.cs
new file mode 100644 (file)
index 0000000..b5f92a3
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * 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;
+using System.Runtime.InteropServices;
+
+#pragma warning disable IDE1006
+#pragma warning disable IDE0032
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// Type used for 2x3 affine transforms. See wikipedia for details:
+    /// http://en.wikipedia.org/wiki/Affine_transformation. The properties map to the matrix in this
+    /// way: [[a  c   tx], [b  d   ty]]. We can't use System.Numerics.Matrix32 since it does't use
+    /// doubles.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    [StructLayout(LayoutKind.Sequential)]
+    public struct Transform : IEquatable<Transform>
+    {
+        private static readonly Transform identity = new Transform(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
+
+        private double a;
+        private double b;
+        private double c;
+        private double d;
+        private double tx;
+        private double ty;
+
+        /// <summary>
+        /// Create a matrix transformation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Transform(double a, double b, double c, double d, double tx, double ty) : this()
+        {
+            this.a = a;
+            this.b = b;
+            this.c = c;
+            this.d = d;
+            this.tx = tx;
+            this.ty = ty;
+        }
+
+        /// <summary>
+        /// Create a transpose matrix.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Transform CreateTranspose(double a, double c, double tx, double b, double d, double ty)
+        {
+            return new Transform(a, b, c, d, tx, ty);
+        }
+
+        /// <summary>
+        /// Create a translation matrix.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Transform CreateTranslation(Vect translate)
+        {
+            return CreateTranspose(1.0, 0.0, translate.X, 0.0, 1.0, translate.Y);
+        }
+
+        /// <summary>
+        /// Create an identity matrix.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Transform Identity => identity;
+
+        /// <summary>
+        /// A
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double A { get => a; set => a = value; }
+
+        /// <summary>
+        /// B
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double B { get => b; set => b = value; }
+        
+        /// <summary>
+        /// C
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double C { get => c; set => c = value; }
+        
+        /// <summary>
+        /// D
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double D { get => d; set => d = value; }
+
+        /// <summary>
+        /// Tx
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Tx { get => tx; set => tx = value; }
+
+        /// <summary>
+        /// Ty
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Ty { get => ty; set => ty = value; }
+
+        /// <summary>
+        /// Return true if all matrix values are within <see cref="Single.Epsilon"/> of each other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override bool Equals(object obj)
+        {
+            Transform? transform = obj as Transform?;
+
+            if (transform == null)
+                return false;
+
+            return Equals(transform.Value);
+        }
+
+        /// <summary>
+        /// Return true if all matrix values are within <see cref="Single.Epsilon"/> of each other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Equals(Transform other)
+        {
+            return Math.Abs(a - other.a) < double.Epsilon &&
+                   Math.Abs(b - other.b) < double.Epsilon &&
+                   Math.Abs(c - other.c) < double.Epsilon &&
+                   Math.Abs(d - other.d) < double.Epsilon &&
+                   Math.Abs(tx - other.tx) < double.Epsilon &&
+                   Math.Abs(ty - other.ty) < double.Epsilon;
+        }
+
+        /// <summary>
+        /// Get the hash code.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override int GetHashCode()
+        {
+            var hashCode = -884009331;
+#pragma warning disable RECS0025 // Non-readonly field referenced in 'GetHashCode()'
+            hashCode = hashCode * -1521134295 + a.GetHashCode();
+            hashCode = hashCode * -1521134295 + b.GetHashCode();
+            hashCode = hashCode * -1521134295 + c.GetHashCode();
+            hashCode = hashCode * -1521134295 + d.GetHashCode();
+            hashCode = hashCode * -1521134295 + tx.GetHashCode();
+            hashCode = hashCode * -1521134295 + ty.GetHashCode();
+#pragma warning restore RECS0025 // Non-readonly field referenced in 'GetHashCode()'
+            return hashCode;
+        }
+
+        /// <summary>
+        /// Return a string formatted like "(a,b|c,d|tx,ty)".
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override string ToString()
+        {
+            return $"({a},{b}|{c},{d}|{tx},{ty})";
+        }
+
+        /// <summary>
+        /// Return true if all matrix values are within <see cref="Single.Epsilon"/> of each other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator ==(Transform transform1, Transform transform2)
+        {
+            return transform1.Equals(transform2);
+        }
+
+        /// <summary>
+        /// Return true if all matrix values are not within <see cref="Single.Epsilon"/> of each
+        /// other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator !=(Transform transform1, Transform transform2)
+        {
+            return !(transform1 == transform2);
+        }
+    }
+}
+
+#pragma warning restore IDE1006
+#pragma warning restore IDE0032
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/CircleExtensions.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/CircleExtensions.cs
new file mode 100644 (file)
index 0000000..ec8f251
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk.Unsafe
+{
+    /// <summary>
+    /// Unsafe extension methods for the <see cref="Circle"/> shape.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public static class CircleExtensions
+    {
+        /// <summary>
+        /// Change the radius of the circle shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void SetRadius(this Circle circle, double radius)
+        {
+            NativeMethods.cpCircleShapeSetRadius(circle.Handle, radius);
+        }
+
+        /// <summary>
+        /// Change the offset of the circle shape.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void SetOffset(this Circle circle, Vect offset)
+        {
+            NativeMethods.cpCircleShapeSetOffset(circle.Handle, offset);
+        }
+
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/PolygonExtensions.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/PolygonExtensions.cs
new file mode 100644 (file)
index 0000000..61d737d
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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.Unsafe
+{
+    /// <summary>
+    /// Unsafe extension methods for the <see cref="Polygon"/> shape.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public static class PolygonExtensions
+    {
+        /// <summary>
+        /// Set the vertexes of the polygon.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void SetVertexes(this Polygon polygon, Vect[] vertexes, Transform transform)
+        {
+            IntPtr ptrVectors = NativeInterop.StructureArrayToPtr(vertexes);
+            NativeMethods.cpPolyShapeSetVerts(polygon.Handle, vertexes.Length, ptrVectors, transform);
+            NativeInterop.FreeStructure(ptrVectors);
+        }
+
+        /// <summary>
+        /// Set the vertexes of the polygon.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void SetVertexes(this Polygon polygon, Vect[] vertexes)
+        {
+            IntPtr ptrVectors = NativeInterop.StructureArrayToPtr(vertexes);
+            NativeMethods.cpPolyShapeSetVertsRaw(polygon.Handle, vertexes.Length, ptrVectors);
+            NativeInterop.FreeStructure(ptrVectors);
+        }
+
+        /// <summary>
+        /// Set the radius of a poly shape 
+        /// </summary>
+        /// <param name="polygon"></param>
+        /// <param name="radius"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void SetRadius(this Polygon polygon, double radius)
+        {
+            NativeMethods.cpPolyShapeSetRadius(polygon.Handle, radius);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/SegmentExtensions.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/SegmentExtensions.cs
new file mode 100644 (file)
index 0000000..8035726
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Physics2D.Chipmunk.Unsafe
+{
+    /// <summary>
+    /// Unsafe extensions methods for the <see cref="Segment"/> shape.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public static class SegmentExtensions
+    {
+        /// <summary>
+        /// Set the endpoints of a segment shape. This mutates collision shapes. Chipmunk can't get
+        /// velocity information on changing shapes, so the results will be unrealistic.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void SetEndpoints(this Segment segment, Vect a, Vect b)
+        {
+            NativeMethods.cpSegmentShapeSetEndpoints(segment.Handle, a, b);
+        }
+
+        /// <summary>
+        /// Set the radius of a segment shape. This mutates collision shapes. Chipmunk can't get
+        /// velocity information on changing shapes, so the results will be unrealistic.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void SetRadius(this Segment segment, double radius)
+        {
+            NativeMethods.cpSegmentShapeSetRadius(segment.Handle, radius);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Vect.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Vect.cs
new file mode 100644 (file)
index 0000000..41049dd
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+ * 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;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+#pragma warning disable IDE1006
+#pragma warning disable IDE0032
+
+// Chipmunk has it own Vector class, 
+// We can't use System.Numerics.Vector2 since is not blitable with the native Vect from Chipmunk
+
+namespace Tizen.NUI.Physics2D.Chipmunk
+{
+    /// <summary>
+    /// 2D Vector struct
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    [StructLayout(LayoutKind.Sequential)]
+    public struct Vect : IEquatable<Vect>
+    {
+        private static readonly Vect zero = new Vect(0, 0);
+
+        private double x;
+        private double y;
+
+        /// <summary>
+        /// X value
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double X
+        {
+            get => x;
+            set => x = value;
+        }
+
+        /// <summary>
+        /// Y value
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Y
+        {
+            get => y;
+            set => y = value;
+        }
+
+        /// <summary>
+        /// Create a vector.
+        /// </summary>
+        /// <param name="x"></param>
+        /// <param name="y"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public Vect(double x, double y)
+        {
+            this.x = x;
+            this.y = y;
+        }
+
+        /// <summary>
+        /// Return true if both objects are within <see cref="Single.Epsilon"/> of each other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override bool Equals(object obj)
+        {
+            Vect? vect = obj as Vect?;
+
+            if (vect == null)
+                return false;
+
+            return this == vect.Value;
+        }
+
+        /// <summary>
+        /// Get the hash code.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override int GetHashCode()
+        {
+#pragma warning disable RECS0025 // Non-readonly field referenced in 'GetHashCode()'
+            return (x.GetHashCode() << 16) ^ y.GetHashCode();
+#pragma warning restore RECS0025 // Non-readonly field referenced in 'GetHashCode()'
+        }
+
+        /// <summary>
+        /// Return true if both objects are within <see cref="Single.Epsilon"/> of each other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Equals(Vect other)
+        {
+            return this == other;
+        }
+
+        /// <summary>
+        /// Return a string formatted like "(x,y)".
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override string ToString()
+        {
+            return $"({x},{y})";
+        }
+
+        /// <summary>
+        /// Return true if both objects are within <see cref="Single.Epsilon"/> of each other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator ==(Vect a, Vect b)
+        {
+            return Math.Abs(b.x - a.x) <= double.Epsilon &&
+                   Math.Abs(b.y - a.y) <= double.Epsilon;
+        }
+
+        /// <summary>
+        /// Return true if both objects are not within <see cref="Single.Epsilon"/> of each other.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool operator !=(Vect a, Vect b)
+        {
+            return !(a == b);
+        }
+
+        /// <summary>
+        /// Add two vectors.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static Vect operator +(Vect a, Vect b)
+        {
+            return new Vect(a.x + b.x, a.y + b.y);
+        }
+
+        /// <summary>
+        /// Subtract two vectors.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static Vect operator -(Vect a, Vect b)
+        {
+            return new Vect(a.x - b.x, a.y - b.y);
+        }
+
+        /// <summary>
+        /// Negate a vector.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static Vect operator -(Vect a)
+        {
+            return new Vect(-a.x, -a.y);
+        }
+
+        /// <summary>
+        /// Scalar multiplication.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static Vect operator *(Vect a, double s)
+        {
+            return new Vect(a.x * s, a.y * s);
+        }
+
+        /// <summary>
+        /// Scalar division.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static Vect operator /(Vect a, double s)
+        {
+            return new Vect(a.x / s, a.y / s);
+        }
+
+        /// <summary>
+        /// Scalar multiplication.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static Vect operator *(double s, Vect a)
+        {
+            return new Vect(a.x * s, a.y * s);
+        }
+
+        /// <summary>
+        /// Scalar division.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static Vect operator /(double s, Vect a)
+        {
+            return new Vect(a.x / s, a.y / s);
+        }
+
+        /// <summary>
+        /// Vector dot product.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public double Dot(Vect v2)
+        {
+            return x * v2.x + y * v2.y;
+        }
+
+        /// <summary>
+        /// 2D vector cross product analog. The cross product of 2D vectors results in a 3D vector
+        /// with only a z component. This function returns the magnitude of the z value.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public double Cross(Vect v2)
+        {
+            return x * v2.y - y * v2.x;
+        }
+
+        /// <summary>
+        /// Returns a perpendicular vector (-90 degree rotation).
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Perpendicurlar => new Vect(-y, x);
+
+        /// <summary>
+        /// Returns the vector projection of v1 onto v2.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public Vect Project(Vect v2)
+        {
+            return v2 * Dot(v2) / v2.Dot(v2);
+        }
+
+        /// <summary>
+        /// Returns the unit length vector for the given angle (in radians).
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static Vect ForAngle(double angle)
+        {
+            return new Vect(Math.Cos(angle), Math.Sin(angle));
+        }
+
+        /// <summary>
+        /// Returns the angular direction v is pointing in (in radians).
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public double ToAngle()
+        {
+            return Math.Atan2(y, x);
+        }
+
+        /// <summary>
+        /// Uses complex number multiplication to rotate v1 by v2. Scaling will occur if v1 is not a
+        /// unit vector.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public Vect Rotate(Vect v2)
+        {
+            return new Vect(x * v2.x - y * v2.y, x * v2.y + y * v2.x);
+        }
+
+        /// <summary>
+        /// Inverse of Rotate().
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public Vect Unrotate(Vect v2)
+        {
+            return new Vect(x * v2.x + y * v2.y, y * v2.x - x * v2.y);
+        }
+
+        /// <summary>
+        /// Returns the squared length of v. Faster than <see cref="Length"/> when you only need to
+        /// compare lengths.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public double LengthSquared() => Dot(this);
+
+        /// <summary>
+        /// Returns the length of v.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public double Length()
+        {
+            return Math.Sqrt(Dot(this));
+        }
+
+        /// <summary>
+        /// Linearly interpolate between this and <paramref name="v2"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public Vect Lerp(Vect v2, double t)
+        {
+            return this * (1.0 - t) + v2 * t;
+        }
+
+        /// <summary>
+        /// Returns a normalized copy.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public Vect Normalize()
+        {
+            return this * (1.0 / (Length() + double.Epsilon));
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        static double Clamp(double value, double min, double max)
+        {
+            if (value < min)
+            {
+                return min;
+            }
+            if (value > max)
+            {
+                return max;
+            }
+
+            return value;
+        }
+
+        /// <summary>
+        /// Spherical linear interpolation between current position and <paramref name="v2"/> based
+        /// on <paramref name="t"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect SLerp(Vect v2, double t)
+        {
+            double dot = Normalize().Dot(v2.Normalize());
+            double omega = Math.Acos(Clamp(dot, -1.0f, 1.0f));
+
+            if (omega < 1e-3)
+            {
+                // If the angle between two vectors is very small, lerp instead to avoid precision issues.
+                return Lerp(v2, t);
+            }
+
+            double denom = 1.0 / Math.Sin(omega);
+            return (this * Math.Sin((1.0f - t) * omega) * denom) + v2 * Math.Sin(t * omega) * denom;
+        }
+
+        /// <summary>
+        /// Spherical linear interpolation between current position towards <paramref name="v2"/> by
+        /// no more than angle <paramref name="a"/> radians.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect SLerpConst(Vect v2, double a)
+        {
+            double dot = Normalize().Dot(v2.Normalize());
+            double omega = Math.Acos(Clamp(dot, -1.0f, 1.0f));
+
+            return SLerp(v2, Math.Min(a, omega) / omega);
+        }
+
+        /// <summary>
+        /// Clamp the magnitude to the given length.
+        /// </summary>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect Clamp(double length)
+        {
+            return Dot(this) > length * length ? Normalize() * length : this;
+        }
+
+        /// <summary>
+        /// Linearly interpolate between the current position towards <paramref name="v2"/> by
+        /// distance <paramref name="d"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Vect LerpConst(Vect v2, double d)
+        {
+            return this + (v2 - this).Clamp(d);
+        }
+
+        /// <summary>
+        /// Return the distance between this and <paramref name="v2"/>.
+        /// </summary>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double Distance(Vect v2)
+        {
+            return (this - v2).Length();
+        }
+
+        /// <summary>
+        /// Return the squared distance between current position and <paramref name="v2"/>. Faster
+        /// than <see cref="Distance"/> when you only need to compare distances.
+        /// </summary>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public double DistanceSquare(Vect v2)
+        {
+            return (this - v2).LengthSquared();
+        }
+
+        /// <summary>
+        /// Return true if the distance between current position and <paramref name="v2"/> is less
+        /// than <paramref name="distance"/>.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool Near(Vect v2, double distance)
+        {
+            return DistanceSquare(v2) < distance * distance;
+        }
+
+        /// <summary>
+        /// (0, 0) Vector.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Vect Zero => zero;
+    }
+}
+
+#pragma warning restore IDE1006
+#pragma warning restore IDE0032
diff --git a/test/Tizen.NUI.Physics2D.Sample/Physics2DSample.cs b/test/Tizen.NUI.Physics2D.Sample/Physics2DSample.cs
new file mode 100644 (file)
index 0000000..e790dec
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+* Copyright (c) 2023 Samsung Electronics Co., Ltd.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Linq;
+using Tizen.NUI.Physics2D.Chipmunk;
+
+// Tests the basic functionality of the Chipmunk2D physics engine without the need of any rendering.
+// It sets up a 2D physics simulation with a dynamic circle dropping to the top of two static segments
+// representing the ground and bouncing back. The simulation is run for a fixed number of time steps,
+// and the position of the circle body is printed at each step to verify the correctness of the physics
+// simulation.
+
+class Physics2DSample
+{
+    public Physics2DSample()
+    {
+        // Create a space for physics simulation
+        var space = new Space();
+    
+        // Set up gravity along the Y-axis (negative value for downward)
+        var gravity = new Vect(0, -100);
+        space.Gravity = gravity;
+        
+        // Create two static bodies (static bodies do not move) with shapes (segments) to form the ground
+        var groundBody1 = new Body(BodyType.Static);
+        var groundBody2 = new Body(BodyType.Static);
+                    
+        // Add the body to the space
+        space.AddBody(groundBody1);
+        space.AddBody(groundBody2);
+
+        var groundStart = new Vect(-1000, 0); // Start point of the ground
+        var groundEnd = new Vect(1000, 0); // End point of the ground
+    
+        var groundShape1 = new Segment(groundBody1, groundStart, groundEnd, 0);
+        var groundShape2 = new Segment(groundBody2, groundStart, groundEnd, 0);
+        
+        groundShape1.CollisionType = 0;
+        groundShape2.CollisionType = 1;
+        
+        groundShape1.Elasticity = 0.85f;
+        groundShape2.Elasticity = 0.85f;
+    
+        // Add the shapes to the space
+        space.AddShape(groundShape1);
+        space.AddShape(groundShape2);
+    
+        // Create a dynamic body with a circle shape
+        var radius = 20.0;
+        var mass = 1.0;
+        var moment = Circle.MomentForCircle(mass, 0, radius, Vect.Zero);
+        
+        // Set initial position for the circle
+        var circleBody = new Body(mass, moment);
+        circleBody.Position = new Vect(0, 50);
+    
+        // Add the body to the space
+        space.AddBody(circleBody);
+    
+        // Create a circle shape
+        var circleShape = new Circle(circleBody, radius, Vect.Zero);
+        circleShape.CollisionType = 2;
+        circleShape.Elasticity = 0.85f;
+    
+        // Add the circle shape to the space
+        space.AddShape(circleShape);
+
+        // Detect the collision between the circle and the ground        
+        CollisionHandler handler = space.GetOrCreateCollisionHandler(0, 2);
+        handler.Data = new StringBuilder();
+        
+        handler.Begin = (arbiterHandle, spaceHandle, userData) =>
+        {
+            StringBuilder builder = (StringBuilder)userData;
+            _ = builder.Append("Begin -> ");
+            
+            Console.WriteLine("CollisionHandler::" + handler.Data.ToString());
+        };
+    
+        handler.PreSolve = (arbiterHandle, spaceHandle, userData) =>
+        {
+            StringBuilder builder = (StringBuilder)userData;
+            _ = builder.Append("PreSolve -> ");
+            
+            Console.WriteLine("CollisionHandler::" + handler.Data.ToString());
+    
+            return true;
+        };
+    
+        handler.PostSolve = (arbiterHandle, spaceHandle, userData) =>
+        {
+            StringBuilder builder = (StringBuilder)userData;
+            _ = builder.Append("PostSolve -> ");
+            
+            Console.WriteLine("CollisionHandler::" + handler.Data.ToString());
+        };
+    
+        handler.Separate = (arbiterHandle, spaceHandle, userData) =>
+        {
+            StringBuilder builder = (StringBuilder)userData;
+            _ = builder.Append("Separate -> ");
+            
+            Console.WriteLine("CollisionHandler::" + handler.Data.ToString());
+        };
+        
+    
+        // Simulate the physics for some time steps
+        var numSteps = 60; // Number of simulation steps
+        var timeStep = 1.0 / 60.0; // Time step for each simulation step (60 FPS)
+        
+        // Set the velocity of the circle body to make it move to the right
+        circleBody.Velocity = new Vect(100, 0); // Velocity of (100, 0) along the X-axis
+        
+        for (int i = 0; i < numSteps; ++i)
+        {
+            space.Step(timeStep);
+    
+            // Print the position of the circle body during simulation
+            var position = circleBody.Position;
+            Console.WriteLine("Step " + i + " - Circle Position: (" + position.X + ", " + position.Y + ")");
+        }
+
+        // Make a point query on a shape
+        {
+            circleShape.Filter = new ShapeFilter((UIntPtr)10, 1, 5);
+            ShapeFilter filter = circleShape.Filter;
+            Console.WriteLine("ShapeFilter: " + filter.Group + ", " + filter.Categories + ", " + filter.Mask);
+        
+            var body = new Body(1, 1.66);
+            var shape = new Box(body, 2, 2, 0);
+    
+            PointQueryInfo point = shape.PointQuery(new Vect(3, 4));
+            Console.WriteLine("Shape PointQuery: Distance: " + point.Distance + ", Point: " + point.Point + ", Gradient.X: " + point.Gradient.X + ", Gradient.Y: " + point.Gradient.Y);            
+    
+            shape.Dispose();
+            body.Dispose();
+        }
+    
+        // Make a point query on a space
+        {
+            var mySpace = new Space();
+            var body = new Body(1, 1.66);
+            var shape = new Box(body, 100, 100, 0);
+    
+            body.Position = new Vect(0, 0);
+    
+            PointQueryInfo[] infos = mySpace.PointQuery(body.Position, 10.0, ShapeFilter.FILTER_ALL).ToArray();
+            Console.WriteLine("Space PointQuery: infos.Length: " + infos.Length);
+    
+            mySpace.AddBody(body);
+            mySpace.AddShape(shape);
+    
+            infos = mySpace.PointQuery(body.Position, 10.0, ShapeFilter.FILTER_ALL).ToArray();
+            Console.WriteLine("Space PointQuery: infos.Length: " + infos.Length);
+    
+            if (infos.Length > 0 && shape == infos[0].Shape)
+            {
+                Console.WriteLine("Space PointQuery: The shape matches");
+            }
+    
+            PointQueryInfo info = space.PointQueryNearest(new Vect(0, 0), 100.0, ShapeFilter.FILTER_ALL);
+            
+            if (info == null || info.Shape == null)
+            {
+                Console.WriteLine("Space PointQueryNearest: No shape is found");
+            }
+            else
+            {
+                Console.WriteLine("Shape PointQueryNearest: Distance: " + info.Distance + ", Point: " + info.Point + ", Gradient.X: "  + info.Gradient.X + ", Gradient.Y: " + info.Gradient.Y + ", Body position: " + info.Shape.Body.Position);
+            }
+    
+            shape.Dispose();
+            body.Dispose();
+            mySpace.Dispose();
+        }
+        
+        // Clean up
+        groundShape1.Dispose();
+        groundShape2.Dispose();
+        circleShape.Dispose();
+    
+        groundBody1.Dispose();
+        groundBody2.Dispose();
+        circleBody.Dispose();
+    
+        space.Dispose();
+    }
+    
+    /// <summary>
+    /// The main entry point for the application.
+    /// </summary>
+    [STAThread] // Forces app to use one thread to access NUI
+    static void Main(string[] args)
+    {
+        Physics2DSample example = new Physics2DSample();
+    }
+}
+
diff --git a/test/Tizen.NUI.Physics2D.Sample/Tizen.NUI.Physics2D.Sample.csproj b/test/Tizen.NUI.Physics2D.Sample/Tizen.NUI.Physics2D.Sample.csproj
new file mode 100644 (file)
index 0000000..b3cedf0
--- /dev/null
@@ -0,0 +1,22 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net6.0</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <AssemblyName>Physics2DSample</AssemblyName>
+  </PropertyGroup>
+    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+      <DebugType>portable</DebugType>
+    </PropertyGroup>
+    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+      <DebugType>None</DebugType>
+    </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="Tizen.NET.Sdk" Version="1.0.9" />
+    <ProjectReference Include="../../src/Tizen/Tizen.csproj" />
+    <ProjectReference Include="../../src/Tizen.NUI/Tizen.NUI.csproj" />
+    <ProjectReference Include="../../src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj" />
+  </ItemGroup>
+  <PropertyGroup>
+    <NeedInjection>True</NeedInjection>
+  </PropertyGroup>
+</Project>
diff --git a/test/Tizen.NUI.Physics2D.Sample/tizen-manifest.xml b/test/Tizen.NUI.Physics2D.Sample/tizen-manifest.xml
new file mode 100644 (file)
index 0000000..ce556b8
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest package="org.tizen.example.Tizen.NUI.Physics2D.Sample" version="1.0.0" api-version="6" xmlns="http://tizen.org/ns/packages">
+    <profile name="common" />
+    <ui-application appid="org.tizen.example.Tizen.NUI.Physics2D.Sample" exec="Physics2DSample.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet-nui" launch_mode="single">
+        <label>Tizen.NUI.Physics2D.Sample</label>
+        <icon>NUI.png</icon>
+        <metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
+        <splash-screens />
+    </ui-application>
+    <shortcut-list />
+    <dependencies />
+    <provides-appdefined-privileges />
+</manifest>