--- /dev/null
+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")]
--- /dev/null
+<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>
--- /dev/null
+
+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
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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
+
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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();
+ }
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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
+ };
+ }
+ }
+}
--- /dev/null
+/*
+ * 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
+ };
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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;
+
+ }
+}
--- /dev/null
+/*
+ * 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
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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; }
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+ }
+
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+* 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();
+ }
+}
+
--- /dev/null
+<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>
--- /dev/null
+<?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>