├── .clang-format ├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ └── build.yml ├── .gitignore ├── Directory.Build.props ├── Directory.Build.targets ├── Directory.Packages.props ├── JoltPhysicsSharp.Native.targets ├── JoltPhysicsSharp.sln ├── LICENSE ├── NuGet.config ├── README.md ├── global.json ├── native ├── android-arm │ └── libjoltc.so ├── android-arm64 │ └── libjoltc.so ├── android-x64 │ └── libjoltc.so ├── linux-arm64 │ └── libjoltc.so ├── linux-x64 │ └── libjoltc.so ├── osx │ └── libjoltc.dylib ├── win-arm64 │ ├── joltc.dll │ └── joltc_double.dll └── win-x64 │ ├── joltc.dll │ └── joltc_double.dll ├── samples ├── 01-HelloWorld │ ├── 01-HelloWorld.csproj │ └── Program.cs ├── Alimer.SampleFramework │ ├── Alimer.SampleFramework.csproj │ ├── Application.cs │ └── DisposableObject.cs └── HelloWorld │ ├── HelloWorld.csproj │ ├── Program.cs │ ├── Sample.cs │ └── Samples │ ├── AlternativeCollissionFilteringSample.cs │ └── HelloWorld.cs ├── src └── JoltPhysicsSharp │ ├── Activation.cs │ ├── ActiveEdgeMode.cs │ ├── AllowedDOFs.cs │ ├── BackFaceMode.cs │ ├── Body.cs │ ├── BodyCreationSettings.cs │ ├── BodyDrawFilter.cs │ ├── BodyFilter.cs │ ├── BodyID.cs │ ├── BodyInterface.cs │ ├── BodyLockInterface.cs │ ├── BodyLockMultiRead.cs │ ├── BodyLockMultiWrite.cs │ ├── BodyLockRead.cs │ ├── BodyLockWrite.cs │ ├── BodyType.cs │ ├── Bool8.cs │ ├── BoundingBox.cs │ ├── BoundingSphere.cs │ ├── BroadPhaseCastResult.cs │ ├── BroadPhaseLayer.cs │ ├── BroadPhaseLayerFilter.cs │ ├── BroadPhaseLayerInterface.cs │ ├── BroadPhaseLayerInterfaceMask.cs │ ├── BroadPhaseLayerInterfaceTable.cs │ ├── BroadPhaseQuery.cs │ ├── Character │ ├── Character.cs │ ├── CharacterBase.cs │ ├── CharacterBaseSettings.cs │ ├── CharacterSettings.cs │ ├── CharacterVirtual.cs │ ├── CharacterVirtualSettings.cs │ ├── CharacterVsCharacterCollision.cs │ ├── ExtendedUpdateSettings.cs │ └── GroundState.cs │ ├── CharacterID.cs │ ├── CollectFacesMode.cs │ ├── CollidePointResult.cs │ ├── CollideShapeResult.cs │ ├── CollideShapeSettings.cs │ ├── CollisionCollectorType.cs │ ├── CollisionEstimationResult.cs │ ├── CollisionGroup.cs │ ├── CollisionGroupID.cs │ ├── CollisionSubGroupID.cs │ ├── ConstraintSpace.cs │ ├── ConstraintSubType.cs │ ├── ConstraintType.cs │ ├── Constraints │ ├── ConeConstraint.cs │ ├── Constraint.cs │ ├── DistanceConstraint.cs │ ├── FixedConstraint.cs │ ├── GearConstraint.cs │ ├── HingeConstraint.cs │ ├── PointConstraint.cs │ ├── SixDOFConstraint.cs │ ├── SliderConstraint.cs │ ├── SwingTwistConstraint.cs │ └── TwoBodyConstraint.cs │ ├── ContactManifold.cs │ ├── ContactSettings.cs │ ├── DebugRenderer.cs │ ├── DelegateProxies.cs │ ├── Double3.cs │ ├── DrawSettings.cs │ ├── Foundation.cs │ ├── GroupFilter.cs │ ├── GroupFilterTable.cs │ ├── HandleDictionary.cs │ ├── IndexedTriangle.cs │ ├── IndexedTriangleNoMaterial.cs │ ├── JobSystem.cs │ ├── JobSystemThreadPool.cs │ ├── Jolt.cs │ ├── JoltApi.cs │ ├── JoltColor.cs │ ├── JoltPhysicsSharp.csproj │ ├── MassProperties.cs │ ├── MathUtil.cs │ ├── Matrix4x4Extensions.cs │ ├── MotionProperties.cs │ ├── MotionQuality.cs │ ├── MotionType.cs │ ├── MotorSettings.cs │ ├── MotorState.cs │ ├── NarrowPhaseQuery.cs │ ├── NativeObject.cs │ ├── ObjectLayer.cs │ ├── ObjectLayerFilter.cs │ ├── ObjectLayerPairFilter.cs │ ├── ObjectLayerPairFilterMask.cs │ ├── ObjectLayerPairFilterTable.cs │ ├── ObjectVsBroadPhaseLayerFilter.cs │ ├── ObjectVsBroadPhaseLayerFilterMask.cs │ ├── ObjectVsBroadPhaseLayerFilterTable.cs │ ├── OverrideMassProperties.cs │ ├── PhysicsMaterial.cs │ ├── PhysicsSettings.cs │ ├── PhysicsSystem.cs │ ├── PhysicsUpdateError.cs │ ├── PlatformLock.cs │ ├── RMatrix4x4.cs │ ├── Ragdoll.cs │ ├── Ray.cs │ ├── RayCastResult.cs │ ├── RayCastSettings.cs │ ├── Shape │ ├── BoxShape.cs │ ├── CapsuleShape.cs │ ├── CompoundShape.cs │ ├── ConvexHullShape.cs │ ├── ConvexShape.cs │ ├── CylinderShape.cs │ ├── DecoratedShape.cs │ ├── EmptyShape.cs │ ├── HeightFieldShape.cs │ ├── MeshShape.cs │ ├── MutableCompoundShape.cs │ ├── OffsetCenterOfMassShape.cs │ ├── PlaneShape.cs │ ├── RotatedTranslatedShape.cs │ ├── ScaledShape.cs │ ├── Shape.cs │ ├── SphereShape.cs │ ├── StaticCompoundShape.cs │ ├── TaperedCapsuleShape.cs │ ├── TaperedCylinderShape.cs │ └── TriangleShape.cs │ ├── ShapeCastResult.cs │ ├── ShapeCastSettings.cs │ ├── ShapeColor.cs │ ├── ShapeFilter.cs │ ├── ShapeSubType.cs │ ├── ShapeType.cs │ ├── SimShapeFilter.cs │ ├── Skeleton.cs │ ├── SoftBodyConstraintColor.cs │ ├── SoftBodyCreationSettings.cs │ ├── SpringMode.cs │ ├── SpringSettings.cs │ ├── SubShapeID.cs │ ├── SubShapeIDPair.cs │ ├── SwingType.cs │ ├── TransformedShape.cs │ ├── Triangle.cs │ └── ValidateResult.cs └── tests ├── BaseTest.cs ├── ConstraintsTests.cs ├── JoltColorTests.cs ├── JoltPhysicsSharp.Tests.csproj └── ShapeTests.cs /.clang-format: -------------------------------------------------------------------------------- 1 | DisableFormat: true 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to: 3 | # treat as text and 4 | # normalize to Unix-style line endings 5 | ############################################################################### 6 | * text eol=lf 7 | 8 | ############################################################################### 9 | # Set explicit file behavior to: 10 | # treat as text and 11 | # normalize to Unix-style line endings 12 | ############################################################################### 13 | *.cmd text eol=lf 14 | *.config text eol=lf 15 | *.cs text eol=lf 16 | *.csproj text eol=lf 17 | *.hlsl text eol=lf 18 | *.json text eol=lf 19 | *.md text eol=lf 20 | *.props text eol=lf 21 | *.ps1 text eol=lf 22 | *.resx text eol=lf 23 | *.sh text eol=lf 24 | *.sln text eol=lf 25 | *.targets text eol=lf 26 | *.yml text eol=lf 27 | *.cmd text eol=crlf 28 | *.bat text eol=crlf 29 | 30 | ############################################################################### 31 | # Set explicit file behavior to: 32 | # treat as text and 33 | # normalize to Windows-style line endings 34 | ############################################################################### 35 | *.sln text eol=crlf 36 | 37 | ############################################################################### 38 | # Set explicit file behavior to: 39 | # treat as binary 40 | ############################################################################### 41 | *.png binary 42 | *.jpg binary 43 | *.gif binary 44 | *.wav binary 45 | *.snk binary 46 | *.dll binary 47 | *.so binary 48 | *.dylib binary -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [amerkoleci] 2 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'main' 7 | paths-ignore: 8 | - '*.md' 9 | - 'LICENSE' 10 | pull_request: 11 | paths-ignore: 12 | - '*.md' 13 | - 'LICENSE' 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v4 21 | 22 | - name: Setup .NET SDK 23 | uses: actions/setup-dotnet@v4 24 | with: 25 | global-json-file: ./global.json 26 | 27 | - name: Pack 28 | run: dotnet pack JoltPhysicsSharp.sln --configuration Release 29 | 30 | - name: Publish to NuGet 31 | if: github.event_name == 'push' 32 | run: dotnet nuget push artifacts/package/release/*.nupkg -k ${{secrets.NUGET_TOKEN}} --skip-duplicate --source https://api.nuget.org/v3/index.json 33 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | Debug 4 | $(MSBuildThisFileDirectory) 5 | $(MSBuildThisFileDirectory)native/ 6 | 7 | 8 | 9 | https://github.com/amerkoleci/JoltPhysicsSharp 10 | git 11 | true 12 | 13 | 14 | 15 | true 16 | 13.0 17 | enable 18 | enable 19 | true 20 | strict 21 | preview 22 | $(MSBuildThisFileDirectory)NuGet.config 23 | true 24 | true 25 | true 26 | true 27 | 28 | 29 | 30 | Amer Koleci and Contributors 31 | Copyright (c) Amer Koleci and Contributors 32 | JoltPhysicsSharp 33 | MIT 34 | true 35 | $(RepositoryUrl) 36 | game-engine game-development physics physics-engine physics-simulation 37 | 38 | 39 | 40 | 41 | portable 42 | true 43 | true 44 | true 45 | snupkg 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | true 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Directory.Packages.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /JoltPhysicsSharp.Native.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Amer Koleci and Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JoltPhysicsSharp 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/amerkoleci/JoltPhysicsSharp/blob/main/LICENSE) 4 | [![Build status](https://github.com/amerkoleci/JoltPhysicsSharp/workflows/Build/badge.svg)](https://github.com/amerkoleci/JoltPhysicsSharp/actions) 5 | [![NuGet](https://img.shields.io/nuget/v/JoltPhysicsSharp.svg)](https://www.nuget.org/packages/JoltPhysicsSharp) 6 | 7 | Cross platform modern **.net9.0** and **.net8.0** bindings for [JoltPhysics](https://github.com/jrouwe/JoltPhysics) using [joltc](https://github.com/amerkoleci/joltc). 8 | 9 | ## Sponsors 10 | Please consider [SPONSOR](https://github.com/sponsors/amerkoleci) me to further help development and to allow faster issue triaging and new features to be implemented. 11 | **_NOTE:_** **any feature request** would require a [sponsor](https://github.com/sponsors/amerkoleci) in order to allow faster implementation and allow this project to continue. 12 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "9.0.100", 4 | "rollForward": "latestFeature", 5 | "allowPrerelease": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /native/android-arm/libjoltc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amerkoleci/JoltPhysicsSharp/0e00bb1fb7c92cb615a3033494537a1ff516d144/native/android-arm/libjoltc.so -------------------------------------------------------------------------------- /native/android-arm64/libjoltc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amerkoleci/JoltPhysicsSharp/0e00bb1fb7c92cb615a3033494537a1ff516d144/native/android-arm64/libjoltc.so -------------------------------------------------------------------------------- /native/android-x64/libjoltc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amerkoleci/JoltPhysicsSharp/0e00bb1fb7c92cb615a3033494537a1ff516d144/native/android-x64/libjoltc.so -------------------------------------------------------------------------------- /native/linux-arm64/libjoltc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amerkoleci/JoltPhysicsSharp/0e00bb1fb7c92cb615a3033494537a1ff516d144/native/linux-arm64/libjoltc.so -------------------------------------------------------------------------------- /native/linux-x64/libjoltc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amerkoleci/JoltPhysicsSharp/0e00bb1fb7c92cb615a3033494537a1ff516d144/native/linux-x64/libjoltc.so -------------------------------------------------------------------------------- /native/osx/libjoltc.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amerkoleci/JoltPhysicsSharp/0e00bb1fb7c92cb615a3033494537a1ff516d144/native/osx/libjoltc.dylib -------------------------------------------------------------------------------- /native/win-arm64/joltc.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amerkoleci/JoltPhysicsSharp/0e00bb1fb7c92cb615a3033494537a1ff516d144/native/win-arm64/joltc.dll -------------------------------------------------------------------------------- /native/win-arm64/joltc_double.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amerkoleci/JoltPhysicsSharp/0e00bb1fb7c92cb615a3033494537a1ff516d144/native/win-arm64/joltc_double.dll -------------------------------------------------------------------------------- /native/win-x64/joltc.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amerkoleci/JoltPhysicsSharp/0e00bb1fb7c92cb615a3033494537a1ff516d144/native/win-x64/joltc.dll -------------------------------------------------------------------------------- /native/win-x64/joltc_double.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amerkoleci/JoltPhysicsSharp/0e00bb1fb7c92cb615a3033494537a1ff516d144/native/win-x64/joltc_double.dll -------------------------------------------------------------------------------- /samples/01-HelloWorld/01-HelloWorld.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | Exe 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /samples/01-HelloWorld/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics; 5 | using System.Numerics; 6 | using JoltPhysicsSharp; 7 | using Alimer.SampleFramework; 8 | using Raylib_cs; 9 | using static Raylib_cs.Raylib; 10 | 11 | namespace HelloWorld; 12 | 13 | public static class Program 14 | { 15 | class HelloWorldApp : Application 16 | { 17 | const int NumberOfBoxes = 12; 18 | 19 | public HelloWorldApp() 20 | : base("01 - Hello World") 21 | { 22 | _ = CreateFloor(100, Layers.NonMoving); 23 | 24 | // add NumberOfBoxes cubes 25 | for (int i = 0; i < NumberOfBoxes; i++) 26 | { 27 | _ = CreateBox( 28 | new Vector3(0.5f), 29 | new Vector3(0, i * 2 + 0.5f, 0), 30 | Quaternion.Identity, 31 | MotionType.Dynamic, 32 | Layers.Moving 33 | ); 34 | } 35 | } 36 | } 37 | 38 | public static unsafe void Main() 39 | { 40 | using HelloWorldApp app = new(); 41 | app.Run(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /samples/Alimer.SampleFramework/Alimer.SampleFramework.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /samples/Alimer.SampleFramework/DisposableObject.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics; 5 | using System.Runtime.CompilerServices; 6 | 7 | namespace Alimer.SampleFramework; 8 | 9 | /// An object which is disposable. 10 | public abstract class DisposableObject : IDisposable 11 | { 12 | private volatile uint _isDisposed; 13 | 14 | protected DisposableObject() 15 | { 16 | _isDisposed = 0; 17 | } 18 | 19 | ~DisposableObject() 20 | { 21 | Dispose(false); 22 | } 23 | 24 | /// Gets true if the object has been disposed; otherwise, false. 25 | public bool IsDisposed => _isDisposed != 0; 26 | 27 | /// 28 | public void Dispose() 29 | { 30 | if (Interlocked.Exchange(ref _isDisposed, 1) == 0) 31 | { 32 | Dispose(disposing: true); 33 | GC.SuppressFinalize(this); 34 | } 35 | } 36 | 37 | /// 38 | /// true if the method was called from ; otherwise, false. 39 | protected abstract void Dispose(bool disposing); 40 | 41 | /// Asserts that the object has not been disposed. 42 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 43 | [Conditional("DEBUG")] 44 | protected void AssertNotDisposed() => Debug.Assert(_isDisposed == 0); 45 | 46 | /// Throws an exception if the object has been disposed. 47 | /// The object has been disposed. 48 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 49 | protected void ThrowIfDisposed() 50 | { 51 | if (_isDisposed != 0) 52 | { 53 | throw new ObjectDisposedException(GetType().Name); 54 | } 55 | } 56 | 57 | /// Marks the object as being disposed. 58 | protected void MarkDisposed() => Interlocked.Exchange(ref _isDisposed, 1); 59 | } 60 | -------------------------------------------------------------------------------- /samples/HelloWorld/HelloWorld.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | Exe 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /samples/HelloWorld/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics; 5 | using System.Numerics; 6 | using JoltPhysicsSharp; 7 | 8 | namespace HelloWorld; 9 | 10 | public static class Program 11 | { 12 | private static MeshShapeSettings CreateTorusMesh(float inTorusRadius, float inTubeRadius, int inTorusSegments = 16, int inTubeSegments = 16) 13 | { 14 | int cNumVertices = inTorusSegments * inTubeSegments; 15 | 16 | // Create torus 17 | int triangleIndex = 0; 18 | Span triangleVertices = stackalloc Vector3[cNumVertices]; 19 | Span indexedTriangles = stackalloc IndexedTriangle[cNumVertices * 2]; 20 | 21 | for (int torus_segment = 0; torus_segment < inTorusSegments; ++torus_segment) 22 | { 23 | Matrix4x4 rotation = Matrix4x4.CreateFromAxisAngle(Vector3.UnitY, (float)torus_segment * 2.0f * (float)Math.PI / inTorusSegments); 24 | for (int tube_segment = 0; tube_segment < inTubeSegments; ++tube_segment) 25 | { 26 | // Create vertices 27 | float tube_angle = (float)tube_segment * 2.0f * (float)Math.PI / inTubeSegments; 28 | Vector3 pos = Vector3.Transform( 29 | new Vector3(inTorusRadius + inTubeRadius * (float)Math.Sin(tube_angle), inTubeRadius * (float)Math.Cos(tube_angle), 0), 30 | rotation); 31 | triangleVertices[triangleIndex] = pos; 32 | 33 | // Create indices 34 | int start_idx = torus_segment * inTubeSegments + tube_segment; 35 | indexedTriangles[triangleIndex] = new(start_idx, (start_idx + 1) % cNumVertices, (start_idx + inTubeSegments) % cNumVertices); 36 | indexedTriangles[triangleIndex + 1] = new((start_idx + 1) % cNumVertices, (start_idx + inTubeSegments + 1) % cNumVertices, (start_idx + inTubeSegments) % cNumVertices); 37 | 38 | triangleIndex++; 39 | } 40 | } 41 | 42 | return new MeshShapeSettings(triangleVertices, indexedTriangles); 43 | } 44 | 45 | public static unsafe void Main() 46 | { 47 | if (!Foundation.Init(false)) 48 | { 49 | return; 50 | } 51 | 52 | Foundation.SetTraceHandler((message) => 53 | { 54 | Console.WriteLine(message); 55 | }); 56 | 57 | #if DEBUG 58 | Foundation.SetAssertFailureHandler((inExpression, inMessage, inFile, inLine) => 59 | { 60 | string message = inMessage ?? inExpression; 61 | 62 | string outMessage = $"[JoltPhysics] Assertion failure at {inFile}:{inLine}: {message}"; 63 | 64 | Debug.WriteLine(outMessage); 65 | 66 | throw new Exception(outMessage); 67 | }); 68 | #endif 69 | 70 | { 71 | using Sample sample = new HelloWorld(); 72 | //using Sample sample = new AlternativeCollissionFilteringSample(); 73 | sample.Initialize(); 74 | sample.Run(); 75 | 76 | // Create capsule 77 | float mHeightStanding = 1.35f; 78 | float mRadiusStanding = 0.3f; 79 | 80 | CapsuleShape capsule = new(0.5f * mHeightStanding, mRadiusStanding); 81 | 82 | CharacterVirtualSettings characterSettings = new(); 83 | characterSettings.Shape = new RotatedTranslatedShapeSettings(new Vector3(0, 0.5f * mHeightStanding + mRadiusStanding, 0), Quaternion.Identity, capsule).Create(); 84 | 85 | // Configure supporting volume 86 | characterSettings.SupportingVolume = new Plane(Vector3.UnitY, -mHeightStanding); // Accept contacts that touch the lower sphere of the capsule 87 | 88 | //CharacterVirtual character = new(characterSettings, new Vector3(0, 0, 0), Quaternion.Identity, 0, physicsSystem); 89 | } 90 | 91 | Foundation.Shutdown(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /samples/HelloWorld/Samples/HelloWorld.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics; 5 | using System.Numerics; 6 | using JoltPhysicsSharp; 7 | 8 | namespace HelloWorld; 9 | 10 | public class HelloWorld : Sample 11 | { 12 | private Body _floor; 13 | private Body _sphere; 14 | 15 | public HelloWorld() 16 | { 17 | 18 | } 19 | 20 | public override void Initialize() 21 | { 22 | base.Initialize(); 23 | 24 | _floor = CreateFloor(100, Layers.NonMoving); 25 | _sphere = CreateSphere(0.5f, new Vector3(0.0f, 2.0f, 0.0f), Quaternion.Identity, MotionType.Dynamic, Layers.Moving); 26 | 27 | BodyInterface.SetPosition(_sphere.ID, new Vector3(100.0f, 2.0f, 0.0f), Activation.Activate); 28 | BodyInterface.SetLinearVelocity(_sphere.ID, new Vector3(0.0f, -5.0f, 0.0f)); 29 | } 30 | 31 | public override void Run() 32 | { 33 | const float deltaTime = 1.0f / 60.0f; 34 | 35 | // Optional step: Before starting the physics simulation you can optimize the broad phase. This improves collision detection performance (it's pointless here because we only have 2 bodies). 36 | // You should definitely not call this every frame or when e.g. streaming in a new level section as it is an expensive operation. 37 | // Instead insert all new objects in batches instead of 1 at a time to keep the broad phase efficient. 38 | System!.OptimizeBroadPhase(); 39 | 40 | uint step = 0; 41 | while (BodyInterface.IsActive(_sphere.ID)) 42 | { 43 | // Next step 44 | ++step; 45 | 46 | var transform = BodyInterface.GetTransformedShape(BodyLockInterface, _sphere.ID); 47 | 48 | // Output current position and velocity of the sphere 49 | Vector3 position = BodyInterface.GetCenterOfMassPosition(_sphere.ID); 50 | Vector3 velocity = BodyInterface.GetLinearVelocity(_sphere.ID); 51 | //Matrix4x4 transform = bodyInterface.GetWorldTransform(sphereID); 52 | //Vector3 translation = bodyInterface.GetWorldTransform(sphereID).Translation; 53 | //Matrix4x4 centerOfMassTransform = bodyInterface.GetCenterOfMassTransform(sphereID); 54 | Console.WriteLine($"Step {step} : Position = ({position}), Velocity = ({velocity})"); 55 | 56 | // If you take larger steps than 1 / 60th of a second you need to do multiple collision steps in order to keep the simulation stable. Do 1 collision step per 1 / 60th of a second (round up). 57 | const int collisionSteps = 1; 58 | 59 | // Step the world 60 | PhysicsUpdateError error = System.Update(deltaTime, collisionSteps, JobSystem); 61 | Debug.Assert(error == PhysicsUpdateError.None); 62 | 63 | GC.Collect(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Activation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Enum used by AddBody to determine if the body needs to be initially active 8 | /// 9 | public enum Activation 10 | { 11 | /// 12 | /// Activate the body, making it part of the simulation. 13 | /// 14 | Activate = 0, 15 | /// 16 | /// Leave activation state as it is (will not deactivate an active body) 17 | /// 18 | DontActivate = 1, 19 | } 20 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ActiveEdgeMode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public enum ActiveEdgeMode 7 | { 8 | CollideOnlyWithActive, 9 | CollideWithAll, 10 | } 11 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/AllowedDOFs.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Enum used in and to indicate which degrees of freedom a body has. 8 | /// 9 | [Flags] 10 | public enum AllowedDOFs 11 | { 12 | /// 13 | /// All degrees of freedom are allowed. 14 | /// 15 | All = 0b111111, 16 | /// 17 | /// Body cannot move in world space X axis. 18 | /// 19 | TranslationX = 0b000001, 20 | /// 21 | /// Body cannot move in world space Y axis. 22 | /// 23 | TranslationY = 0b000010, 24 | /// 25 | /// Body cannot move in world space Z axis. 26 | /// 27 | TranslationZ = 0b000100, 28 | /// 29 | /// Body cannot rotate around local space X axis. 30 | /// 31 | RotationX = 0b001000, 32 | /// 33 | /// Body cannot rotate around local space Y axis. 34 | /// 35 | RotationY = 0b010000, 36 | /// 37 | /// Body cannot rotate around local space Z axis. 38 | /// 39 | RotationZ = 0b100000, 40 | /// 41 | /// Body can only move in X and Y axis and rotate around Z axis 42 | /// 43 | Plane2D = TranslationX | TranslationY | RotationZ, 44 | } 45 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BackFaceMode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public enum BackFaceMode 7 | { 8 | IgnoreBackFaces, 9 | CollideWithBackFaces, 10 | } 11 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BodyDrawFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Runtime.InteropServices; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public abstract class BodyDrawFilter : NativeObject 10 | { 11 | private static readonly JPH_BodyDrawFilter_Procs _procs; 12 | private readonly nint _listenerUserData; 13 | 14 | static BodyDrawFilter() 15 | { 16 | _procs = new JPH_BodyDrawFilter_Procs 17 | { 18 | ShouldDraw = &ShouldDrawCallback, 19 | }; 20 | JPH_BodyDrawFilter_SetProcs(in _procs); 21 | } 22 | 23 | public BodyDrawFilter() 24 | { 25 | _listenerUserData = DelegateProxies.CreateUserData(this, true); 26 | 27 | Handle = JPH_BodyDrawFilter_Create(_listenerUserData); 28 | } 29 | 30 | protected override void DisposeNative() 31 | { 32 | DelegateProxies.GetUserData(_listenerUserData, out GCHandle gch); 33 | 34 | JPH_BodyDrawFilter_Destroy(Handle); 35 | gch.Free(); 36 | } 37 | 38 | protected abstract bool ShouldDraw(Body body); 39 | 40 | [UnmanagedCallersOnly] 41 | private static Bool8 ShouldDrawCallback(nint context, nint body) 42 | { 43 | BodyDrawFilter listener = DelegateProxies.GetUserData(context, out _); 44 | return listener.ShouldDraw(Body.GetObject(body)!); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BodyFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Runtime.InteropServices; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public abstract class BodyFilter : NativeObject 10 | { 11 | private static readonly JPH_BodyFilter_Procs _procs; 12 | private readonly nint _listenerUserData; 13 | 14 | static BodyFilter() 15 | { 16 | _procs = new JPH_BodyFilter_Procs 17 | { 18 | ShouldCollide = &ShouldCollideCallback, 19 | ShouldCollideLocked = &ShouldCollideLockedCallback, 20 | }; 21 | JPH_BodyFilter_SetProcs(in _procs); 22 | } 23 | 24 | public BodyFilter() 25 | { 26 | _listenerUserData = DelegateProxies.CreateUserData(this, true); 27 | Handle = JPH_BodyFilter_Create(_listenerUserData); 28 | } 29 | 30 | protected override void DisposeNative() 31 | { 32 | DelegateProxies.GetUserData(_listenerUserData, out GCHandle gch); 33 | 34 | JPH_BodyFilter_Destroy(Handle); 35 | gch.Free(); 36 | } 37 | 38 | protected abstract bool ShouldCollide(BodyID bodyID); 39 | protected abstract bool ShouldCollideLocked(Body body); 40 | 41 | [UnmanagedCallersOnly] 42 | private static Bool8 ShouldCollideCallback(nint context, BodyID bodyID) 43 | { 44 | BodyFilter listener = DelegateProxies.GetUserData(context, out _); 45 | return listener.ShouldCollide(bodyID); 46 | } 47 | 48 | [UnmanagedCallersOnly] 49 | private static Bool8 ShouldCollideLockedCallback(nint context, nint body) 50 | { 51 | BodyFilter listener = DelegateProxies.GetUserData(context, out _); 52 | return listener.ShouldCollideLocked(Body.GetObject(body)!); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BodyID.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public readonly struct BodyID(uint id) : IEquatable 7 | { 8 | /// 9 | /// The value for an invalid body ID 10 | /// 11 | public const uint InvalidBodyID = 0xffffffff; 12 | 13 | /// 14 | /// This bit is used by the broadphase 15 | /// 16 | public const uint BroadPhaseBit = 0x00800000; 17 | 18 | /// 19 | /// Maximum value for body index (also the maximum amount of bodies supported - 1) 20 | /// 21 | public const uint MaxBodyIndex = 0x7fffff; 22 | 23 | /// 24 | /// Maximum value for the sequence number 25 | /// 26 | public const byte MaxSequenceNumber = 0xff; 27 | 28 | public uint ID { get; } = id; 29 | public bool IsValid => ID != InvalidBodyID; 30 | public bool IsInvalid => ID == InvalidBodyID; 31 | 32 | /// 33 | /// Get index in body array 34 | /// 35 | public readonly uint Index => ID & MaxBodyIndex; 36 | 37 | /// 38 | /// Get sequence number of body. 39 | /// 40 | public readonly byte SequenceNumber => (byte)(ID >> 24); 41 | 42 | /// 43 | /// Returns the index and sequence number combined in an uint 44 | /// 45 | /// 46 | public readonly uint IndexAndSequenceNumber => ID; 47 | 48 | public static BodyID Invalid => new(0xffffffff); 49 | public static implicit operator BodyID(uint id) => new(id); 50 | public static implicit operator uint(in BodyID id) => id.IndexAndSequenceNumber; 51 | 52 | public static bool operator ==(BodyID left, BodyID right) => left.ID == right.ID; 53 | public static bool operator !=(BodyID left, BodyID right) => left.ID != right.ID; 54 | public static bool operator ==(BodyID left, uint right) => left.ID == right; 55 | public static bool operator !=(BodyID left, uint right) => left.ID != right; 56 | public bool Equals(BodyID other) => ID == other.ID; 57 | 58 | /// 59 | public override bool Equals(object? obj) => obj is BodyID handle && Equals(handle); 60 | 61 | /// 62 | public override int GetHashCode() => ID.GetHashCode(); 63 | 64 | public override string ToString() => ID.ToString(); 65 | } 66 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BodyLockInterface.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public readonly struct BodyLockInterface : IEquatable 9 | { 10 | public BodyLockInterface(nint handle) { Handle = handle; } 11 | public nint Handle { get; } 12 | public bool IsNull => Handle == 0; 13 | public static BodyLockInterface Null => new(0); 14 | public static implicit operator BodyLockInterface(nint handle) => new(handle); 15 | public static bool operator ==(BodyLockInterface left, BodyLockInterface right) => left.Handle == right.Handle; 16 | public static bool operator !=(BodyLockInterface left, BodyLockInterface right) => left.Handle != right.Handle; 17 | public static bool operator ==(BodyLockInterface left, nint right) => left.Handle == right; 18 | public static bool operator !=(BodyLockInterface left, nint right) => left.Handle != right; 19 | public bool Equals(BodyLockInterface other) => Handle == other.Handle; 20 | 21 | /// 22 | public override bool Equals(object? obj) => obj is BodyLockInterface handle && Equals(handle); 23 | 24 | /// 25 | public override int GetHashCode() => Handle.GetHashCode(); 26 | 27 | public void LockRead(in BodyID bodyID, out BodyLockRead @lock) 28 | { 29 | JPH_BodyLockInterface_LockRead(Handle, bodyID, out @lock); 30 | } 31 | 32 | public void UnlockRead(in BodyLockRead @lock) 33 | { 34 | JPH_BodyLockInterface_UnlockRead(Handle, in @lock); 35 | } 36 | 37 | public void LockWrite(in BodyID bodyID, out BodyLockWrite @lock) 38 | { 39 | JPH_BodyLockInterface_LockWrite(Handle, bodyID, out @lock); 40 | } 41 | 42 | public void UnlockWrite(in BodyLockWrite @lock) 43 | { 44 | JPH_BodyLockInterface_UnlockWrite(Handle, in @lock); 45 | } 46 | 47 | public unsafe BodyLockMultiRead LockMultiRead(Span bodyIDs) 48 | { 49 | uint* bodyIDsPtr = stackalloc uint[bodyIDs.Length]; 50 | for (int i = 0; i < bodyIDs.Length; i++) 51 | { 52 | bodyIDsPtr[i] = bodyIDs[i]; 53 | } 54 | 55 | return JPH_BodyLockInterface_LockMultiRead(Handle, bodyIDsPtr, (uint)bodyIDs.Length); 56 | } 57 | 58 | public unsafe BodyLockMultiWrite LockMultiWrite(Span bodyIDs) 59 | { 60 | uint* bodyIDsPtr = stackalloc uint[bodyIDs.Length]; 61 | for (int i = 0; i < bodyIDs.Length; i++) 62 | { 63 | bodyIDsPtr[i] = bodyIDs[i]; 64 | } 65 | 66 | return JPH_BodyLockInterface_LockMultiWrite(Handle, bodyIDsPtr, (uint)bodyIDs.Length); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BodyLockMultiRead.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public readonly struct BodyLockMultiRead : IEquatable, IDisposable 10 | { 11 | public BodyLockMultiRead(nint handle) { Handle = handle; } 12 | public nint Handle { get; } 13 | public bool IsNull => Handle == 0; 14 | public static BodyLockInterface Null => new(0); 15 | public static implicit operator BodyLockMultiRead(nint handle) => new(handle); 16 | public static bool operator ==(BodyLockMultiRead left, BodyLockMultiRead right) => left.Handle == right.Handle; 17 | public static bool operator !=(BodyLockMultiRead left, BodyLockMultiRead right) => left.Handle != right.Handle; 18 | public static bool operator ==(BodyLockMultiRead left, nint right) => left.Handle == right; 19 | public static bool operator !=(BodyLockMultiRead left, nint right) => left.Handle != right; 20 | public bool Equals(BodyLockMultiRead other) => Handle == other.Handle; 21 | 22 | /// 23 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is BodyLockMultiRead handle && Equals(handle); 24 | 25 | /// 26 | public override int GetHashCode() => Handle.GetHashCode(); 27 | 28 | /// 29 | public void Dispose() => JPH_BodyLockMultiRead_Destroy(Handle); 30 | 31 | public Body? GetBody(uint bodyIndex) 32 | { 33 | return Body.GetObject(JPH_BodyLockMultiRead_GetBody(Handle, bodyIndex)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BodyLockMultiWrite.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public readonly struct BodyLockMultiWrite : IEquatable, IDisposable 10 | { 11 | public BodyLockMultiWrite(nint handle) { Handle = handle; } 12 | public nint Handle { get; } 13 | public bool IsNull => Handle == 0; 14 | public static BodyLockInterface Null => new(0); 15 | public static implicit operator BodyLockMultiWrite(nint handle) => new(handle); 16 | public static bool operator ==(BodyLockMultiWrite left, BodyLockMultiWrite right) => left.Handle == right.Handle; 17 | public static bool operator !=(BodyLockMultiWrite left, BodyLockMultiWrite right) => left.Handle != right.Handle; 18 | public static bool operator ==(BodyLockMultiWrite left, nint right) => left.Handle == right; 19 | public static bool operator !=(BodyLockMultiWrite left, nint right) => left.Handle != right; 20 | public bool Equals(BodyLockMultiWrite other) => Handle == other.Handle; 21 | 22 | /// 23 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is BodyLockMultiWrite handle && Equals(handle); 24 | 25 | /// 26 | public override int GetHashCode() => Handle.GetHashCode(); 27 | 28 | /// 29 | public void Dispose() => JPH_BodyLockMultiWrite_Destroy(Handle); 30 | 31 | public Body? GetBody(uint bodyIndex) 32 | { 33 | return Body.GetObject(JPH_BodyLockMultiWrite_GetBody(Handle, bodyIndex)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BodyLockRead.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public readonly struct BodyLockRead 7 | { 8 | public readonly BodyLockInterface LockInterface; 9 | public readonly nint Mutex; /* JPH_SharedMutex */ 10 | public readonly nint BodyHandle; 11 | 12 | public Body? Body => Body.GetObject(BodyHandle); 13 | 14 | /// 15 | /// Test if the lock was successful (if the body ID was valid) 16 | /// 17 | public bool Succeeded => BodyHandle != 0; 18 | 19 | /// 20 | /// Test if the lock was successful (if the body ID was valid) and the body is still in the broad phase 21 | /// 22 | public bool SucceededAndIsInBroadPhase => BodyHandle != 0 && Body!.IsInBroadPhase; 23 | } 24 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BodyLockWrite.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public readonly struct BodyLockWrite 7 | { 8 | public readonly BodyLockInterface LockInterface; 9 | public readonly nint Mutex; /* JPH_SharedMutex */ 10 | public readonly nint BodyHandle; 11 | 12 | public Body? Body => Body.GetObject(BodyHandle); 13 | 14 | /// 15 | /// Test if the lock was successful (if the body ID was valid) 16 | /// 17 | public bool Succeeded => BodyHandle != 0; 18 | 19 | /// 20 | /// Test if the lock was successful (if the body ID was valid) and the body is still in the broad phase 21 | /// 22 | public bool SucceededAndIsInBroadPhase => BodyHandle != 0 && Body!.IsInBroadPhase; 23 | } 24 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BodyType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Defines the type of 8 | /// 9 | public enum BodyType 10 | { 11 | Rigid = 0, 12 | Soft = 1 13 | } 14 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Bool8.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public readonly partial struct Bool8(byte value) : IComparable, IComparable, IEquatable 7 | { 8 | public readonly byte Value = value; 9 | 10 | public static Bool8 True => new(1); 11 | public static Bool8 False => new(0); 12 | 13 | public static bool operator ==(Bool8 left, Bool8 right) => left.Value == right.Value; 14 | 15 | public static bool operator !=(Bool8 left, Bool8 right) => left.Value != right.Value; 16 | 17 | public static bool operator <(Bool8 left, Bool8 right) => left.Value < right.Value; 18 | 19 | public static bool operator <=(Bool8 left, Bool8 right) => left.Value <= right.Value; 20 | 21 | public static bool operator >(Bool8 left, Bool8 right) => left.Value > right.Value; 22 | 23 | public static bool operator >=(Bool8 left, Bool8 right) => left.Value >= right.Value; 24 | 25 | public static implicit operator bool(Bool8 value) => value.Value != 0; 26 | 27 | public static implicit operator Bool8(bool value) => new Bool8(value ? (byte)1 : (byte)0); 28 | 29 | public static bool operator false(Bool8 value) => value.Value == 0; 30 | 31 | public static bool operator true(Bool8 value) => value.Value != 0; 32 | 33 | public static implicit operator Bool8(byte value) => new Bool8(value); 34 | 35 | public int CompareTo(object? obj) 36 | { 37 | if (obj is Bool8 other) 38 | { 39 | return CompareTo(other); 40 | } 41 | 42 | return (obj is null) ? 1 : throw new ArgumentException($"obj is not an instance of {nameof(Bool8)}."); 43 | } 44 | 45 | public int CompareTo(Bool8 other) => Value.CompareTo(other.Value); 46 | 47 | public override bool Equals(object? obj) => (obj is Bool8 other) && Equals(other); 48 | 49 | public bool Equals(Bool8 other) => Value.Equals(other.Value); 50 | 51 | public override int GetHashCode() => Value.GetHashCode(); 52 | 53 | public override string ToString() => Value != 0 ? "True" : "False"; 54 | } 55 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BroadPhaseCastResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public readonly struct BroadPhaseCastResult 7 | { 8 | public readonly BodyID BodyID; 9 | public readonly float Fraction; 10 | } 11 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BroadPhaseLayer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public readonly struct BroadPhaseLayer(byte value) : IEquatable 7 | { 8 | public byte Value { get; } = value; 9 | 10 | public static implicit operator BroadPhaseLayer(byte id) => new(id); 11 | public static implicit operator byte(in BroadPhaseLayer id) => id.Value; 12 | 13 | public static bool operator ==(BroadPhaseLayer left, BroadPhaseLayer right) => left.Value == right.Value; 14 | public static bool operator !=(BroadPhaseLayer left, BroadPhaseLayer right) => left.Value != right.Value; 15 | public static bool operator ==(BroadPhaseLayer left, byte right) => left.Value == right; 16 | public static bool operator !=(BroadPhaseLayer left, byte right) => left.Value != right; 17 | public bool Equals(BroadPhaseLayer other) => Value == other.Value; 18 | 19 | /// 20 | public override bool Equals(object? obj) => obj is BroadPhaseLayer handle && Equals(handle); 21 | 22 | /// 23 | public override int GetHashCode() => Value.GetHashCode(); 24 | 25 | public override string ToString() => Value.ToString(); 26 | } 27 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BroadPhaseLayerFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Runtime.InteropServices; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public abstract class BroadPhaseLayerFilter : NativeObject 10 | { 11 | private static readonly JPH_BroadPhaseLayerFilter_Procs _procs; 12 | private readonly nint _listenerUserData; 13 | 14 | static BroadPhaseLayerFilter() 15 | { 16 | _procs = new JPH_BroadPhaseLayerFilter_Procs 17 | { 18 | ShouldCollide = &ShouldCollideCallback, 19 | }; 20 | JPH_BroadPhaseLayerFilter_SetProcs(in _procs); 21 | } 22 | 23 | public BroadPhaseLayerFilter() 24 | { 25 | _listenerUserData = DelegateProxies.CreateUserData(this, true); 26 | Handle = JPH_BroadPhaseLayerFilter_Create(_listenerUserData); 27 | } 28 | 29 | protected override void DisposeNative() 30 | { 31 | DelegateProxies.GetUserData(_listenerUserData, out GCHandle gch); 32 | 33 | JPH_BroadPhaseLayerFilter_Destroy(Handle); 34 | gch.Free(); 35 | } 36 | 37 | protected abstract bool ShouldCollide(BroadPhaseLayer layer); 38 | 39 | [UnmanagedCallersOnly] 40 | private static Bool8 ShouldCollideCallback(IntPtr context, BroadPhaseLayer layer) 41 | { 42 | BroadPhaseLayerFilter listener = DelegateProxies.GetUserData(context, out _); 43 | return listener.ShouldCollide(layer); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BroadPhaseLayerInterface.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public abstract class BroadPhaseLayerInterface : NativeObject 7 | { 8 | protected BroadPhaseLayerInterface(nint handle) 9 | { 10 | Handle = handle; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BroadPhaseLayerInterfaceMask.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed class BroadPhaseLayerInterfaceMask(uint numBroadPhaseLayers) : BroadPhaseLayerInterface(JPH_BroadPhaseLayerInterfaceMask_Create(numBroadPhaseLayers)) 9 | { 10 | public void ConfigureLayer(in BroadPhaseLayer broadPhaseLayer, uint groupsToInclude, uint groupsToExclude) 11 | { 12 | JPH_BroadPhaseLayerInterfaceMask_ConfigureLayer(Handle, in broadPhaseLayer, groupsToInclude, groupsToExclude); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BroadPhaseLayerInterfaceTable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed class BroadPhaseLayerInterfaceTable : BroadPhaseLayerInterface 9 | { 10 | public BroadPhaseLayerInterfaceTable(uint numObjectLayers, uint numBroadPhaseLayers) 11 | : base(JPH_BroadPhaseLayerInterfaceTable_Create(numObjectLayers, numBroadPhaseLayers)) 12 | { 13 | } 14 | 15 | public void MapObjectToBroadPhaseLayer(ObjectLayer objectLayer, BroadPhaseLayer broadPhaseLayer) 16 | { 17 | JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(Handle, objectLayer, broadPhaseLayer); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/BroadPhaseQuery.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | using unsafe JPH_RayCastBodyCollector = delegate* unmanaged; 10 | using unsafe JPH_CollideShapeBodyCollector = delegate* unmanaged; 11 | 12 | public readonly struct BroadPhaseQuery : IEquatable 13 | { 14 | public BroadPhaseQuery(nint handle) { Handle = handle; } 15 | public nint Handle { get; } 16 | public bool IsNull => Handle == 0; 17 | public static BroadPhaseQuery Null => new(0); 18 | public static implicit operator BroadPhaseQuery(nint handle) => new(handle); 19 | public static bool operator ==(BroadPhaseQuery left, BroadPhaseQuery right) => left.Handle == right.Handle; 20 | public static bool operator !=(BroadPhaseQuery left, BroadPhaseQuery right) => left.Handle != right.Handle; 21 | public static bool operator ==(BroadPhaseQuery left, nint right) => left.Handle == right; 22 | public static bool operator !=(BroadPhaseQuery left, nint right) => left.Handle != right; 23 | public bool Equals(BroadPhaseQuery other) => Handle == other.Handle; 24 | 25 | /// 26 | public override bool Equals(object? obj) => obj is BroadPhaseQuery handle && Equals(handle); 27 | 28 | /// 29 | public override int GetHashCode() => Handle.GetHashCode(); 30 | 31 | public unsafe bool CastRay( 32 | in Ray ray, 33 | Memory results, 34 | JPH_RayCastBodyCollector callback, 35 | nint userData = 0, 36 | BroadPhaseLayerFilter? broadPhaseFilter = default, 37 | ObjectLayerFilter? objectLayerFilter = default) 38 | { 39 | return JPH_BroadPhaseQuery_CastRay(Handle, 40 | in ray.Position, in ray.Direction, 41 | callback, userData, 42 | broadPhaseFilter?.Handle ?? 0, 43 | objectLayerFilter?.Handle ?? 0); 44 | } 45 | 46 | public unsafe bool CollideAABox( 47 | in BoundingBox box, 48 | JPH_CollideShapeBodyCollector callback, 49 | nint userData = 0, 50 | BroadPhaseLayerFilter? broadPhaseFilter = default, 51 | ObjectLayerFilter? objectLayerFilter = default) 52 | { 53 | return JPH_BroadPhaseQuery_CollideAABox(Handle, 54 | in box, 55 | callback, userData, 56 | broadPhaseFilter?.Handle ?? 0, 57 | objectLayerFilter?.Handle ?? 0); 58 | } 59 | 60 | public unsafe bool CollideSphere( 61 | in BoundingSphere sphere, 62 | JPH_CollideShapeBodyCollector callback, 63 | nint userData = 0, 64 | BroadPhaseLayerFilter? broadPhaseFilter = default, 65 | ObjectLayerFilter? objectLayerFilter = default) 66 | { 67 | return JPH_BroadPhaseQuery_CollideSphere(Handle, 68 | sphere.Center, sphere.Radius, 69 | callback, userData, 70 | broadPhaseFilter?.Handle ?? 0, 71 | objectLayerFilter?.Handle ?? 0); 72 | } 73 | 74 | public unsafe bool CollidePoint( 75 | in Vector3 point, 76 | JPH_CollideShapeBodyCollector callback, 77 | nint userData = 0, 78 | BroadPhaseLayerFilter? broadPhaseFilter = default, 79 | ObjectLayerFilter? objectLayerFilter = default) 80 | { 81 | return JPH_BroadPhaseQuery_CollidePoint(Handle, 82 | in point, 83 | callback, userData, 84 | broadPhaseFilter?.Handle ?? 0, 85 | objectLayerFilter?.Handle ?? 0); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Character/CharacterBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public abstract class CharacterBase : NativeObject 10 | { 11 | protected CharacterBase() 12 | { 13 | } 14 | 15 | protected CharacterBase(nint handle) 16 | : base(handle) 17 | { 18 | } 19 | 20 | protected CharacterBase(nint handle, bool owns) 21 | : base(handle, owns) 22 | { 23 | } 24 | 25 | protected override void DisposeNative() 26 | { 27 | JPH_CharacterBase_Destroy(Handle); 28 | } 29 | 30 | public float CosMaxSlopeAngle => JPH_CharacterBase_GetCosMaxSlopeAngle(Handle); 31 | public float MaxSlopeAngle 32 | { 33 | set => JPH_CharacterBase_SetMaxSlopeAngle(Handle, value); 34 | } 35 | 36 | public Vector3 Up 37 | { 38 | get 39 | { 40 | JPH_CharacterBase_GetUp(Handle, out Vector3 result); 41 | return result; 42 | } 43 | set 44 | { 45 | JPH_CharacterBase_SetUp(Handle, in value); 46 | } 47 | } 48 | 49 | public GroundState GroundState 50 | { 51 | get => JPH_CharacterBase_GetGroundState(Handle); 52 | } 53 | 54 | public bool IsSupported 55 | { 56 | get => JPH_CharacterBase_IsSupported(Handle); 57 | } 58 | 59 | public Vector3 GroundPosition 60 | { 61 | get 62 | { 63 | JPH_CharacterBase_GetGroundPosition(Handle, out Vector3 position); 64 | return position; 65 | } 66 | } 67 | 68 | public Vector3 GroundNormal 69 | { 70 | get 71 | { 72 | JPH_CharacterBase_GetGroundNormal(Handle, out Vector3 normal); 73 | return normal; 74 | } 75 | } 76 | 77 | public Vector3 GroundVelocity 78 | { 79 | get 80 | { 81 | JPH_CharacterBase_GetGroundVelocity(Handle, out Vector3 velocity); 82 | return velocity; 83 | } 84 | } 85 | 86 | public uint GroundBodyId 87 | { 88 | get => JPH_CharacterBase_GetGroundBodyId(Handle); 89 | } 90 | 91 | public uint GroundSubShapeId 92 | { 93 | get => JPH_CharacterBase_GetGroundSubShapeId(Handle); 94 | } 95 | 96 | public ulong GroundUserDat 97 | { 98 | get => JPH_CharacterBase_GetGroundUserData(Handle); 99 | } 100 | 101 | 102 | public bool IsSlopeTooSteep(in Vector3 value) 103 | { 104 | return JPH_CharacterBase_IsSlopeTooSteep(Handle, in value); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Character/CharacterBaseSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public abstract class CharacterBaseSettings 10 | { 11 | protected CharacterBaseSettings() 12 | { 13 | } 14 | 15 | internal void FromNative(in JPH_CharacterBaseSettings settings) 16 | { 17 | Up = settings.up; 18 | SupportingVolume = settings.supportingVolume; 19 | MaxSlopeAngle = settings.maxSlopeAngle; 20 | EnhancedInternalEdgeRemoval = settings.enhancedInternalEdgeRemoval; 21 | //Shape = settings.shape != 0 ? new 22 | } 23 | 24 | 25 | public Vector3 Up { get; set; } 26 | 27 | public Plane SupportingVolume { get; set; } 28 | 29 | public float MaxSlopeAngle { get; set; } 30 | 31 | public bool EnhancedInternalEdgeRemoval { get; set; } 32 | 33 | public Shape? Shape { get; set; } 34 | } 35 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Character/CharacterSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public sealed class CharacterSettings : CharacterBaseSettings 10 | { 11 | public unsafe CharacterSettings() 12 | { 13 | JPH_CharacterSettings native; 14 | JPH_CharacterSettings_Init(&native); 15 | 16 | FromNative(native.baseSettings); 17 | 18 | Layer = native.layer; 19 | Mass = native.mass; 20 | Friction = native.friction; 21 | GravityFactor = native.gravityFactor; 22 | AllowedDOFs = native.allowedDOFs; 23 | } 24 | 25 | public ObjectLayer Layer { get; set; } 26 | 27 | public float Mass { get; set; } 28 | 29 | public float Friction { get; set; } 30 | 31 | public float GravityFactor { get; set; } 32 | 33 | public AllowedDOFs AllowedDOFs { get; set; } 34 | 35 | internal unsafe void ToNative(JPH_CharacterSettings* native) 36 | { 37 | native->baseSettings.up = Up; 38 | native->baseSettings.supportingVolume = SupportingVolume; 39 | native->baseSettings.maxSlopeAngle = MaxSlopeAngle; 40 | native->baseSettings.enhancedInternalEdgeRemoval = EnhancedInternalEdgeRemoval; 41 | native->baseSettings.shape = Shape != null ? Shape.Handle : 0; 42 | 43 | native->layer = Layer; 44 | native->mass = Mass; 45 | native->friction = Friction; 46 | native->gravityFactor = GravityFactor; 47 | native->allowedDOFs = AllowedDOFs; 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Character/CharacterVirtualSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public sealed class CharacterVirtualSettings : CharacterBaseSettings 10 | { 11 | public unsafe CharacterVirtualSettings() 12 | { 13 | JPH_CharacterVirtualSettings native; 14 | JPH_CharacterVirtualSettings_Init(&native); 15 | 16 | FromNative(native.baseSettings); 17 | 18 | ID = native.ID; 19 | Mass = native.mass; 20 | MaxStrength = native.maxStrength; 21 | ShapeOffset = native.shapeOffset; 22 | BackFaceMode = native.backFaceMode; 23 | PredictiveContactDistance = native.predictiveContactDistance; 24 | MaxCollisionIterations = native.maxCollisionIterations; 25 | MaxConstraintIterations = native.maxConstraintIterations; 26 | MinTimeRemaining = native.minTimeRemaining; 27 | CollisionTolerance = native.collisionTolerance; 28 | CharacterPadding = native.characterPadding; 29 | MaxNumHits = native.maxNumHits; 30 | HitReductionCosMaxAngle = native.hitReductionCosMaxAngle; 31 | PenetrationRecoverySpeed = native.penetrationRecoverySpeed; 32 | InnerBodyShape = native.innerBodyShape != 0 ? Shape.GetObject(native.innerBodyShape) : null; 33 | InnerBodyIDOverride = native.innerBodyIDOverride; 34 | InnerBodyLayer = native.innerBodyLayer; 35 | } 36 | 37 | public CharacterID ID { get; set; } 38 | public float Mass { get; set; } 39 | 40 | public float MaxStrength { get; set; } 41 | 42 | public Vector3 ShapeOffset { get; set; } 43 | 44 | public BackFaceMode BackFaceMode { get; set; } 45 | 46 | public float PredictiveContactDistance { get; set; } 47 | 48 | public uint MaxCollisionIterations { get; set; } 49 | 50 | public uint MaxConstraintIterations { get; set; } 51 | 52 | public float MinTimeRemaining { get; set; } 53 | 54 | public float CollisionTolerance { get; set; } 55 | 56 | public float CharacterPadding { get; set; } 57 | 58 | public uint MaxNumHits { get; set; } 59 | 60 | public float HitReductionCosMaxAngle { get; set; } 61 | 62 | public float PenetrationRecoverySpeed { get; set; } 63 | 64 | public Shape? InnerBodyShape { get; set; } 65 | public BodyID InnerBodyIDOverride { get; set; } 66 | public ObjectLayer InnerBodyLayer { get; set; } 67 | 68 | internal unsafe void ToNative(JPH_CharacterVirtualSettings* native) 69 | { 70 | native->baseSettings.up = Up; 71 | native->baseSettings.supportingVolume = SupportingVolume; 72 | native->baseSettings.maxSlopeAngle = MaxSlopeAngle; 73 | native->baseSettings.enhancedInternalEdgeRemoval = EnhancedInternalEdgeRemoval; 74 | native->baseSettings.shape = Shape != null ? Shape.Handle : 0; 75 | 76 | native->ID = ID; 77 | native->mass = Mass; 78 | native->maxStrength = MaxStrength; 79 | native->shapeOffset = ShapeOffset; 80 | native->backFaceMode = BackFaceMode; 81 | native->predictiveContactDistance = PredictiveContactDistance; 82 | native->maxCollisionIterations = MaxCollisionIterations; 83 | native->maxConstraintIterations = MaxConstraintIterations; 84 | native->minTimeRemaining = MinTimeRemaining; 85 | native->collisionTolerance = CollisionTolerance; 86 | native->characterPadding = CharacterPadding; 87 | native->maxNumHits = MaxNumHits; 88 | native->hitReductionCosMaxAngle = HitReductionCosMaxAngle; 89 | native->penetrationRecoverySpeed = PenetrationRecoverySpeed; 90 | native->innerBodyShape = InnerBodyShape != null ? InnerBodyShape.Handle : 0; 91 | native->innerBodyIDOverride = InnerBodyIDOverride; 92 | native->innerBodyLayer = InnerBodyLayer; 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Character/ExtendedUpdateSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public readonly record struct ExtendedUpdateSettings 10 | { 11 | public ExtendedUpdateSettings() 12 | { 13 | StickToFloorStepDown = new Vector3(0, -0.5f, 0); 14 | WalkStairsStepUp = new Vector3(0, 0.4f, 0); 15 | WalkStairsMinStepForward = 0.02f; 16 | WalkStairsStepForwardTest = 0.15f; 17 | WalkStairsCosAngleForwardContact = MathF.Cos(MathUtil.DegreesToRadians(75.0f)); 18 | WalkStairsStepDownExtra = Vector3.Zero; 19 | } 20 | 21 | public Vector3 StickToFloorStepDown { get; init; } 22 | public Vector3 WalkStairsStepUp { get; init; } 23 | public float WalkStairsMinStepForward { get; init; } 24 | public float WalkStairsStepForwardTest { get; init; } 25 | public float WalkStairsCosAngleForwardContact { get; init; } 26 | public Vector3 WalkStairsStepDownExtra { get; init; } 27 | } 28 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Character/GroundState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public enum GroundState 7 | { 8 | OnGround = 0, 9 | OnSteepGround = 1, 10 | NotSupported = 2, 11 | InAir = 3 12 | } 13 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/CharacterID.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public readonly partial struct CharacterID(uint value) : IComparable, IComparable, IEquatable, IFormattable 9 | { 10 | public readonly uint Value = value; 11 | 12 | public static bool operator ==(CharacterID left, CharacterID right) => left.Value == right.Value; 13 | 14 | public static bool operator !=(CharacterID left, CharacterID right) => left.Value != right.Value; 15 | 16 | public static bool operator <(CharacterID left, CharacterID right) => left.Value < right.Value; 17 | 18 | public static bool operator <=(CharacterID left, CharacterID right) => left.Value <= right.Value; 19 | 20 | public static bool operator >(CharacterID left, CharacterID right) => left.Value > right.Value; 21 | 22 | public static bool operator >=(CharacterID left, CharacterID right) => left.Value >= right.Value; 23 | 24 | 25 | public static implicit operator CharacterID(uint value) => new (value); 26 | 27 | public static explicit operator uint(CharacterID value) => value.Value; 28 | 29 | public int CompareTo(object? obj) 30 | { 31 | if (obj is CharacterID other) 32 | { 33 | return CompareTo(other); 34 | } 35 | 36 | return (obj is null) ? 1 : throw new ArgumentException($"obj is not an instance of {nameof(CharacterID)}."); 37 | } 38 | 39 | public int CompareTo(CharacterID other) => Value.CompareTo(other.Value); 40 | 41 | public override bool Equals([NotNullWhen(true)] object? obj) => (obj is CharacterID other) && Equals(other); 42 | 43 | public bool Equals(CharacterID other) => Value.Equals(other.Value); 44 | 45 | public override int GetHashCode() => Value.GetHashCode(); 46 | 47 | public override string ToString() => Value.ToString(); 48 | 49 | public string ToString(string? format, IFormatProvider? formatProvider) => Value.ToString(format, formatProvider); 50 | } 51 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/CollectFacesMode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public enum CollectFacesMode 7 | { 8 | CollectFaces, 9 | NoFaces, 10 | } 11 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/CollidePointResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public readonly struct CollidePointResult 7 | { 8 | public readonly BodyID BodyID; 9 | public readonly SubShapeID subShapeID2; 10 | } 11 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/CollideShapeResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public readonly unsafe struct CollideShapeResult 9 | { 10 | public readonly Vector3 ContactPointOn1; 11 | public readonly Vector3 ContactPointOn2; 12 | public readonly Vector3 PenetrationAxis; 13 | public readonly float PenetrationDepth; 14 | public readonly SubShapeID SubShapeID1; 15 | public readonly SubShapeID SubShapeID2; 16 | public readonly BodyID BodyID2; 17 | internal readonly int Shape1FaceCount; 18 | internal readonly Vector3* Shape1Faces; 19 | internal readonly int Shape2FaceCount; 20 | internal readonly Vector3* Shape2Faces; 21 | public Span Shape1Face => new(Shape1Faces, Shape1FaceCount); 22 | public Span Shape2Face => new(Shape2Faces, Shape2FaceCount); 23 | } 24 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/CollideShapeSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using System.Runtime.InteropServices; 6 | using static JoltPhysicsSharp.JoltApi; 7 | 8 | namespace JoltPhysicsSharp; 9 | 10 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 11 | public struct CollideShapeSettings 12 | { 13 | // CollideSettingsBase 14 | 15 | /// 16 | /// How active edges (edges that a moving object should bump into) are handled 17 | /// 18 | public ActiveEdgeMode ActiveEdgeMode; 19 | 20 | /// 21 | /// If colliding faces should be collected or only the collision point 22 | /// 23 | public CollectFacesMode CollectFacesMode; 24 | 25 | /// 26 | /// If objects are closer than this distance, they are considered to be colliding (used for GJK) (unit: meter) 27 | /// 28 | public float CollisionTolerance; 29 | 30 | /// 31 | /// A factor that determines the accuracy of the penetration depth calculation. If the change of the squared distance is less than tolerance * current_penetration_depth^2 the algorithm will terminate. (unit: dimensionless) 32 | /// 33 | public float PenetrationTolerance; 34 | 35 | /// 36 | /// When is a movement direction can be provided. When hitting an inactive edge, the system will select the triangle normal as penetration depth only if it impedes the movement less than with the calculated penetration depth. 37 | /// 38 | public Vector3 ActiveEdgeMovementDirection; 39 | 40 | /// 41 | /// When > 0 contacts in the vicinity of the query shape can be found. All nearest contacts that are not further away than this distance will be found (unit: meter) 42 | /// 43 | public float MaxSeparationDistance; 44 | 45 | /// 46 | /// How backfacing triangles should be treated 47 | /// 48 | public BackFaceMode BackFaceMode; 49 | 50 | public unsafe CollideShapeSettings() 51 | { 52 | JPH_CollideShapeSettings native; 53 | JPH_CollideShapeSettings_Init(&native); 54 | 55 | ActiveEdgeMode = native.@base.activeEdgeMode; 56 | CollectFacesMode = native.@base.collectFacesMode; 57 | CollisionTolerance = native.@base.collisionTolerance; 58 | PenetrationTolerance = native.@base.penetrationTolerance; 59 | ActiveEdgeMovementDirection = native.@base.activeEdgeMovementDirection; 60 | 61 | MaxSeparationDistance = native.maxSeparationDistance; 62 | BackFaceMode = native.backFaceMode; 63 | } 64 | 65 | internal static CollideShapeSettings FromNative(in JPH_CollideShapeSettings native) 66 | { 67 | CollideShapeSettings result = default; 68 | result.ActiveEdgeMode = native.@base.activeEdgeMode; 69 | result.CollectFacesMode = native.@base.collectFacesMode; 70 | result.CollisionTolerance = native.@base.collisionTolerance; 71 | result.PenetrationTolerance = native.@base.penetrationTolerance; 72 | result.ActiveEdgeMovementDirection = native.@base.activeEdgeMovementDirection; 73 | result.MaxSeparationDistance = native.maxSeparationDistance; 74 | result.BackFaceMode = native.backFaceMode; 75 | return result; 76 | } 77 | 78 | internal readonly unsafe void ToNative(JPH_CollideShapeSettings* native) 79 | { 80 | native->@base.activeEdgeMode = ActiveEdgeMode; 81 | native->@base.collectFacesMode = CollectFacesMode; 82 | native->@base.collisionTolerance = CollisionTolerance; 83 | native->@base.penetrationTolerance = PenetrationTolerance; 84 | native->@base.activeEdgeMovementDirection = ActiveEdgeMovementDirection; 85 | 86 | native->maxSeparationDistance = MaxSeparationDistance; 87 | native->backFaceMode = BackFaceMode; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/CollisionCollectorType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public enum CollisionCollectorType 7 | { 8 | AllHit = 0, 9 | AllHitSorted = 1, 10 | ClosestHit = 2, 11 | AnyHit = 3, 12 | } 13 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/CollisionEstimationResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public readonly unsafe struct CollisionEstimationResult 9 | { 10 | public readonly struct Impulse 11 | { 12 | public readonly float ContactImpulse; 13 | public readonly float FrictionImpulse1; 14 | public readonly float FrictionImpulse2; 15 | } 16 | 17 | public readonly Vector3 LinearVelocity1; 18 | public readonly Vector3 AngularVelocity1; 19 | public readonly Vector3 LinearVelocity2; 20 | public readonly Vector3 AngularVelocity2; 21 | 22 | public readonly Vector3 Tangent1; 23 | public readonly Vector3 Tangent2; 24 | 25 | internal readonly int ImpulseCount; 26 | internal readonly Impulse* ImpulsesPtr; 27 | public Span Impulses => new(ImpulsesPtr, ImpulseCount); 28 | } 29 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/CollisionGroup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public partial struct CollisionGroup 9 | { 10 | public GroupFilter? GroupFilter = default; 11 | public CollisionGroupID GroupID = CollisionGroupID.Invalid; 12 | public CollisionSubGroupID SubGroupID = CollisionSubGroupID.Invalid; 13 | 14 | public CollisionGroup() 15 | { 16 | } 17 | 18 | public CollisionGroup(GroupFilter? groupFilter, CollisionGroupID groupID, CollisionSubGroupID subGroupID) 19 | { 20 | GroupFilter = groupFilter; 21 | GroupID = groupID; 22 | SubGroupID = subGroupID; 23 | } 24 | 25 | /// 26 | /// Check if this object collides with another object 27 | /// 28 | /// 29 | /// 30 | public readonly bool CanCollide(in CollisionGroup other) 31 | { 32 | // Call the CanCollide function of the first group filter that's not null 33 | if (GroupFilter != null) 34 | return GroupFilter.CanCollide(this, other); 35 | else if (other.GroupFilter != null) 36 | return other.GroupFilter.CanCollide(other, this); 37 | else 38 | return true; 39 | } 40 | 41 | internal void ToNative(out JPH_CollisionGroup result) 42 | { 43 | result = new JPH_CollisionGroup 44 | { 45 | groupFilter = (GroupFilter != null) ? GroupFilter.Handle : 0, 46 | groupID = GroupID, 47 | subGroupID = SubGroupID 48 | }; 49 | } 50 | 51 | internal static CollisionGroup FromNative(in JPH_CollisionGroup group) 52 | { 53 | return new(GroupFilter.GetObject(group.groupFilter), group.groupID, group.subGroupID); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/CollisionGroupID.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public readonly partial struct CollisionGroupID(uint value) : IComparable, IComparable, IEquatable, IFormattable 9 | { 10 | public readonly uint Value = value; 11 | 12 | public static CollisionGroupID Invalid => new(~0U); 13 | 14 | public static bool operator ==(CollisionGroupID left, CollisionGroupID right) => left.Value == right.Value; 15 | 16 | public static bool operator !=(CollisionGroupID left, CollisionGroupID right) => left.Value != right.Value; 17 | 18 | public static bool operator <(CollisionGroupID left, CollisionGroupID right) => left.Value < right.Value; 19 | 20 | public static bool operator <=(CollisionGroupID left, CollisionGroupID right) => left.Value <= right.Value; 21 | 22 | public static bool operator >(CollisionGroupID left, CollisionGroupID right) => left.Value > right.Value; 23 | 24 | public static bool operator >=(CollisionGroupID left, CollisionGroupID right) => left.Value >= right.Value; 25 | 26 | 27 | public static implicit operator CollisionGroupID(uint value) => new (value); 28 | 29 | public static explicit operator uint(CollisionGroupID value) => value.Value; 30 | 31 | public int CompareTo(object? obj) 32 | { 33 | if (obj is CollisionGroupID other) 34 | { 35 | return CompareTo(other); 36 | } 37 | 38 | return (obj is null) ? 1 : throw new ArgumentException($"obj is not an instance of {nameof(CollisionGroupID)}."); 39 | } 40 | 41 | public int CompareTo(CollisionGroupID other) => Value.CompareTo(other.Value); 42 | 43 | public override bool Equals([NotNullWhen(true)] object? obj) => (obj is CollisionGroupID other) && Equals(other); 44 | 45 | public bool Equals(CollisionGroupID other) => Value.Equals(other.Value); 46 | 47 | public override int GetHashCode() => Value.GetHashCode(); 48 | 49 | public override string ToString() => Value.ToString(); 50 | 51 | public string ToString(string? format, IFormatProvider? formatProvider) => Value.ToString(format, formatProvider); 52 | } 53 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/CollisionSubGroupID.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public readonly partial struct CollisionSubGroupID(uint value) : IComparable, IComparable, IEquatable, IFormattable 9 | { 10 | public readonly uint Value = value; 11 | 12 | public static CollisionSubGroupID Invalid => new(~0U); 13 | 14 | public static bool operator ==(CollisionSubGroupID left, CollisionSubGroupID right) => left.Value == right.Value; 15 | 16 | public static bool operator !=(CollisionSubGroupID left, CollisionSubGroupID right) => left.Value != right.Value; 17 | 18 | public static bool operator <(CollisionSubGroupID left, CollisionSubGroupID right) => left.Value < right.Value; 19 | 20 | public static bool operator <=(CollisionSubGroupID left, CollisionSubGroupID right) => left.Value <= right.Value; 21 | 22 | public static bool operator >(CollisionSubGroupID left, CollisionSubGroupID right) => left.Value > right.Value; 23 | 24 | public static bool operator >=(CollisionSubGroupID left, CollisionSubGroupID right) => left.Value >= right.Value; 25 | 26 | 27 | public static implicit operator CollisionSubGroupID(uint value) => new (value); 28 | 29 | public static explicit operator uint(CollisionSubGroupID value) => value.Value; 30 | 31 | public int CompareTo(object? obj) 32 | { 33 | if (obj is CollisionSubGroupID other) 34 | { 35 | return CompareTo(other); 36 | } 37 | 38 | return (obj is null) ? 1 : throw new ArgumentException($"obj is not an instance of {nameof(CollisionSubGroupID)}."); 39 | } 40 | 41 | public int CompareTo(CollisionSubGroupID other) => Value.CompareTo(other.Value); 42 | 43 | public override bool Equals([NotNullWhen(true)] object? obj) => (obj is CollisionSubGroupID other) && Equals(other); 44 | 45 | public bool Equals(CollisionSubGroupID other) => Value.Equals(other.Value); 46 | 47 | public override int GetHashCode() => Value.GetHashCode(); 48 | 49 | public override string ToString() => Value.ToString(); 50 | 51 | public string ToString(string? format, IFormatProvider? formatProvider) => Value.ToString(format, formatProvider); 52 | } 53 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ConstraintSpace.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public enum ConstraintSpace 7 | { 8 | LocalToBodyCOM = 0, 9 | WorldSpace = 1, 10 | } 11 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ConstraintSubType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Defines the subtype of 8 | /// 9 | public enum ConstraintSubType 10 | { 11 | Fixed = 0, 12 | Point = 1, 13 | Hinge = 2, 14 | Slider = 3, 15 | Distance = 4, 16 | Cone = 5, 17 | SwingTwist = 6, 18 | SixDOF = 7, 19 | Path = 8, 20 | Vehicle = 9, 21 | RackAndPinion = 10, 22 | Gear = 11, 23 | Pulley = 12, 24 | 25 | User1 = 13, 26 | User2 = 14, 27 | User3 = 15, 28 | User4 = 16, 29 | } 30 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ConstraintType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Defines the type of 8 | /// 9 | public enum ConstraintType 10 | { 11 | Constraint = 0, 12 | TwoBodyConstraint = 1, 13 | } 14 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Constraints/ConeConstraint.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public unsafe class ConeConstraintSettings : TwoBodyConstraintSettings 10 | { 11 | public ConeConstraintSettings() 12 | { 13 | JPH_ConeConstraintSettings native; 14 | JPH_ConeConstraintSettings_Init(&native); 15 | 16 | FromNative(native); 17 | } 18 | 19 | internal ConeConstraintSettings(in JPH_ConeConstraintSettings native) 20 | { 21 | FromNative(native); 22 | } 23 | 24 | public ConstraintSpace Space { get; set; } 25 | 26 | public Vector3 Point1 { get; set; } 27 | public Vector3 TwistAxis1 { get; set; } 28 | public Vector3 Point2 { get; set; } 29 | public Vector3 TwistAxis2 { get; set; } 30 | public float HalfConeAngle { get; set; } 31 | 32 | public override TwoBodyConstraint CreateConstraint(in Body body1, in Body body2) 33 | { 34 | return new ConeConstraint(CreateConstraintNative(in body1, in body2)); 35 | } 36 | 37 | internal nint CreateConstraintNative(in Body body1, in Body body2) 38 | { 39 | JPH_ConeConstraintSettings nativeSettings; 40 | ToNative(&nativeSettings); 41 | 42 | return JPH_ConeConstraint_Create(&nativeSettings, body1.Handle, body2.Handle); 43 | } 44 | 45 | private void FromNative(in JPH_ConeConstraintSettings native) 46 | { 47 | FromNative(native.baseSettings); 48 | 49 | Space = native.space; 50 | Point1 = native.point1; 51 | TwistAxis1 = native.twistAxis1; 52 | Point2 = native.point2; 53 | TwistAxis2 = native.twistAxis2; 54 | HalfConeAngle = native.halfConeAngle; 55 | } 56 | 57 | internal void ToNative(JPH_ConeConstraintSettings* native) 58 | { 59 | ToNative(ref native->baseSettings); 60 | 61 | native->space = Space; 62 | native->point1 = Point1; 63 | native->twistAxis1 = TwistAxis1; 64 | native->point2 = Point2; 65 | native->twistAxis2 = TwistAxis2; 66 | native->halfConeAngle = HalfConeAngle; 67 | } 68 | } 69 | 70 | public unsafe class ConeConstraint : TwoBodyConstraint 71 | { 72 | internal ConeConstraint(nint handle) 73 | : base(handle) 74 | { 75 | } 76 | 77 | public ConeConstraint(ConeConstraintSettings settings, in Body body1, in Body body2) 78 | : base(settings.CreateConstraintNative(in body1, in body2)) 79 | { 80 | } 81 | 82 | public ConeConstraintSettings Settings 83 | { 84 | get 85 | { 86 | JPH_ConeConstraint_GetSettings(Handle, out JPH_ConeConstraintSettings native); 87 | return new(native); 88 | } 89 | } 90 | 91 | public float CosHalfConeAngle 92 | { 93 | get => JPH_ConeConstraint_GetCosHalfConeAngle(Handle); 94 | set => JPH_ConeConstraint_SetHalfConeAngle(Handle, value); 95 | } 96 | 97 | public Vector3 TotalLambdaPosition 98 | { 99 | get 100 | { 101 | JPH_ConeConstraint_GetTotalLambdaPosition(Handle, out Vector3 result); 102 | return result; 103 | } 104 | } 105 | 106 | public float TotalLambdaRotation => JPH_ConeConstraint_GetTotalLambdaRotation(Handle); 107 | } 108 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Constraints/Constraint.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public abstract class ConstraintSettings 10 | { 11 | 12 | internal void FromNative(in JPH_ConstraintSettings settings) 13 | { 14 | Enabled = settings.enabled; 15 | ConstraintPriority = settings.constraintPriority; 16 | NumVelocityStepsOverride = settings.numVelocityStepsOverride; 17 | NumPositionStepsOverride = settings.numPositionStepsOverride; 18 | DrawConstraintSize = settings.drawConstraintSize; 19 | UserData = settings.userData; 20 | } 21 | 22 | internal void ToNative(ref JPH_ConstraintSettings native) 23 | { 24 | native.enabled = Enabled; 25 | native.constraintPriority = ConstraintPriority; 26 | native.numVelocityStepsOverride = NumVelocityStepsOverride; 27 | native.numPositionStepsOverride = NumPositionStepsOverride; 28 | native.drawConstraintSize = DrawConstraintSize; 29 | native.userData = UserData; 30 | } 31 | 32 | public bool Enabled { get; set; } 33 | 34 | public uint ConstraintPriority { get; set; } 35 | 36 | public uint NumVelocityStepsOverride { get; set; } 37 | public uint NumPositionStepsOverride { get; set; } 38 | 39 | public float DrawConstraintSize { get; set; } 40 | 41 | public ulong UserData { get; set; } 42 | } 43 | 44 | public abstract class Constraint : NativeObject 45 | { 46 | protected Constraint(nint handle) 47 | : base(handle) 48 | { 49 | } 50 | 51 | protected override void DisposeNative() 52 | { 53 | JPH_Constraint_Destroy(Handle); 54 | } 55 | 56 | public ConstraintType Type => JPH_Constraint_GetType(Handle); 57 | 58 | public ConstraintSubType SubType => JPH_Constraint_GetSubType(Handle); 59 | 60 | public uint NumVelocityStepsOverride 61 | { 62 | get => JPH_Constraint_GetNumVelocityStepsOverride(Handle); 63 | set => JPH_Constraint_SetNumVelocityStepsOverride(Handle, value); 64 | } 65 | 66 | public uint NumPositionStepsOverride 67 | { 68 | get => JPH_Constraint_GetNumPositionStepsOverride(Handle); 69 | set => JPH_Constraint_SetNumPositionStepsOverride(Handle, value); 70 | } 71 | 72 | public bool Enabled 73 | { 74 | get => JPH_Constraint_GetEnabled(Handle); 75 | set => JPH_Constraint_SetEnabled(Handle, value); 76 | } 77 | 78 | public uint Priority 79 | { 80 | get => JPH_Constraint_GetConstraintPriority(Handle); 81 | set => JPH_Constraint_SetConstraintPriority(Handle, value); 82 | } 83 | 84 | public ulong UserData 85 | { 86 | get => JPH_Constraint_GetUserData(Handle); 87 | set => JPH_Constraint_SetUserData(Handle, value); 88 | } 89 | 90 | public void NotifyShapeChanged(in BodyID bodyID, in Vector3 deltaCOM) 91 | { 92 | JPH_Constraint_NotifyShapeChanged(Handle, bodyID, in deltaCOM); 93 | } 94 | 95 | public void ResetWarmStart() 96 | { 97 | JPH_Constraint_ResetWarmStart(Handle); 98 | } 99 | 100 | public void SetupVelocityConstraint(float deltaTime) 101 | { 102 | JPH_Constraint_SetupVelocityConstraint(Handle, deltaTime); 103 | } 104 | 105 | public void WarmStartVelocityConstraint(float warmStartImpulseRatio) 106 | { 107 | JPH_Constraint_WarmStartVelocityConstraint(Handle, warmStartImpulseRatio); 108 | } 109 | 110 | public bool SolveVelocityConstraint(float deltaTime) 111 | { 112 | return JPH_Constraint_SolveVelocityConstraint(Handle, deltaTime); 113 | } 114 | 115 | public bool SolvePositionConstraint(float deltaTime, float baumgarte) 116 | { 117 | return JPH_Constraint_SolvePositionConstraint(Handle, deltaTime, baumgarte); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Constraints/GearConstraint.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public unsafe class GearConstraintSettings : TwoBodyConstraintSettings 10 | { 11 | public GearConstraintSettings() 12 | { 13 | JPH_GearConstraintSettings native; 14 | JPH_GearConstraintSettings_Init(&native); 15 | 16 | FromNative(native); 17 | } 18 | 19 | internal GearConstraintSettings(in JPH_GearConstraintSettings native) 20 | { 21 | FromNative(native); 22 | } 23 | 24 | public ConstraintSpace Space { get; set; } 25 | public Vector3 HingeAxis1 { get; set; } 26 | public Vector3 HingeAxis2 { get; set; } 27 | public float Ratio { get; set; } 28 | 29 | public override TwoBodyConstraint CreateConstraint(in Body body1, in Body body2) 30 | { 31 | return new GearConstraint(CreateConstraintNative(in body1, in body2)); 32 | } 33 | 34 | internal nint CreateConstraintNative(in Body body1, in Body body2) 35 | { 36 | JPH_GearConstraintSettings nativeSettings; 37 | ToNative(&nativeSettings); 38 | 39 | return JPH_GearConstraint_Create(&nativeSettings, body1.Handle, body2.Handle); 40 | } 41 | 42 | private void FromNative(in JPH_GearConstraintSettings native) 43 | { 44 | FromNative(native.baseSettings); 45 | 46 | Space = native.space; 47 | HingeAxis1 = native.hingeAxis1; 48 | HingeAxis2 = native.hingeAxis2; 49 | Ratio = native.ratio; 50 | } 51 | 52 | internal void ToNative(JPH_GearConstraintSettings* native) 53 | { 54 | ToNative(ref native->baseSettings); 55 | 56 | native->space = Space; 57 | native->hingeAxis1 = HingeAxis1; 58 | native->hingeAxis2 = HingeAxis2; 59 | native->ratio = Ratio; 60 | } 61 | } 62 | 63 | public sealed class GearConstraint : TwoBodyConstraint 64 | { 65 | internal GearConstraint(nint handle) 66 | : base(handle) 67 | { 68 | } 69 | 70 | public GearConstraint(GearConstraintSettings settings, in Body body1, in Body body2) 71 | : base(settings.CreateConstraintNative(in body1, in body2)) 72 | { 73 | } 74 | 75 | public GearConstraintSettings Settings 76 | { 77 | get 78 | { 79 | JPH_GearConstraint_GetSettings(Handle, out JPH_GearConstraintSettings native); 80 | return new(native); 81 | } 82 | } 83 | 84 | public float TotalLambda => JPH_GearConstraint_GetTotalLambda(Handle); 85 | } 86 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Constraints/PointConstraint.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using System.Runtime.CompilerServices; 6 | using static JoltPhysicsSharp.JoltApi; 7 | 8 | namespace JoltPhysicsSharp; 9 | 10 | public sealed unsafe class PointConstraintSettings : TwoBodyConstraintSettings 11 | { 12 | public PointConstraintSettings() 13 | { 14 | JPH_PointConstraintSettings native; 15 | JPH_PointConstraintSettings_Init(&native); 16 | 17 | FromNative(native); 18 | 19 | } 20 | 21 | internal PointConstraintSettings(in JPH_PointConstraintSettings native) 22 | { 23 | FromNative(native); 24 | } 25 | 26 | public ConstraintSpace Space { get; set; } 27 | public Vector3 Point1 { get; set; } 28 | public Vector3 Point2 { get; set; } 29 | 30 | public override TwoBodyConstraint CreateConstraint(in Body body1, in Body body2) 31 | { 32 | return new PointConstraint(CreateConstraintNative(in body1, in body2)); 33 | } 34 | 35 | internal nint CreateConstraintNative(in Body body1, in Body body2) 36 | { 37 | JPH_PointConstraintSettings nativeSettings; 38 | ToNative(&nativeSettings); 39 | 40 | return JPH_PointConstraint_Create(&nativeSettings, body1.Handle, body2.Handle); 41 | } 42 | 43 | private void FromNative(in JPH_PointConstraintSettings native) 44 | { 45 | FromNative(native.baseSettings); 46 | 47 | Space = native.space; 48 | Point1 = native.point1; 49 | Point2 = native.point2; 50 | } 51 | 52 | internal void ToNative(JPH_PointConstraintSettings* native) 53 | { 54 | ToNative(ref native->baseSettings); 55 | 56 | native->space = Space; 57 | native->point1 = Point1; 58 | native->point2 = Point2; 59 | } 60 | } 61 | 62 | public sealed unsafe class PointConstraint : TwoBodyConstraint 63 | { 64 | internal PointConstraint(nint handle) 65 | : base(handle) 66 | { 67 | } 68 | 69 | public PointConstraint(PointConstraintSettings settings, in Body body1, in Body body2) 70 | : base(settings.CreateConstraintNative(in body1, in body2)) 71 | { 72 | } 73 | 74 | public PointConstraintSettings Settings 75 | { 76 | get 77 | { 78 | JPH_PointConstraint_GetSettings(Handle, out JPH_PointConstraintSettings native); 79 | return new(native); 80 | } 81 | } 82 | 83 | public void SetPoint1(ConstraintSpace space, in Vector3 value) 84 | { 85 | fixed (Vector3* valuePtr = &value) 86 | JPH_PointConstraint_SetPoint1(Handle, space, valuePtr); 87 | } 88 | 89 | public void SetPoint2(ConstraintSpace space, in Vector3 value) 90 | { 91 | fixed (Vector3* valuePtr = &value) 92 | JPH_PointConstraint_SetPoint2(Handle, space, valuePtr); 93 | } 94 | 95 | public Vector3 TotalLambdaPosition 96 | { 97 | get 98 | { 99 | JPH_PointConstraint_GetTotalLambdaPosition(Handle, out Vector3 result); 100 | return result; 101 | } 102 | } 103 | 104 | public void GetTotalLambdaPosition(out Vector3 result) 105 | { 106 | JPH_PointConstraint_GetTotalLambdaPosition(Handle, out result); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Constraints/TwoBodyConstraint.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using System.Runtime.CompilerServices; 6 | using static JoltPhysicsSharp.JoltApi; 7 | 8 | namespace JoltPhysicsSharp; 9 | 10 | public abstract class TwoBodyConstraintSettings : ConstraintSettings 11 | { 12 | public abstract TwoBodyConstraint CreateConstraint(in Body body1, in Body body2); 13 | } 14 | 15 | public abstract unsafe class TwoBodyConstraint : Constraint 16 | { 17 | protected TwoBodyConstraint(nint handle) 18 | : base(handle) 19 | { 20 | } 21 | 22 | public Body Body1 23 | { 24 | get => Body.GetObject(JPH_TwoBodyConstraint_GetBody1(Handle))!; 25 | } 26 | 27 | public Body Body2 28 | { 29 | get => Body.GetObject(JPH_TwoBodyConstraint_GetBody2(Handle))!; 30 | } 31 | 32 | public Matrix4x4 ConstraintToBody1Matrix 33 | { 34 | get 35 | { 36 | JPH_TwoBodyConstraint_GetConstraintToBody1Matrix(Handle, out Matrix4x4 result); 37 | return result; 38 | } 39 | } 40 | 41 | public Matrix4x4 ConstraintToBody2Matrix 42 | { 43 | get 44 | { 45 | JPH_TwoBodyConstraint_GetConstraintToBody2Matrix(Handle, out Matrix4x4 result); 46 | return result; 47 | } 48 | } 49 | 50 | public void GetConstraintToBody1Matrix(out Matrix4x4 result) 51 | { 52 | JPH_TwoBodyConstraint_GetConstraintToBody1Matrix(Handle, out result); 53 | } 54 | 55 | public void GetConstraintToBody2Matrix(out Matrix4x4 result) 56 | { 57 | JPH_TwoBodyConstraint_GetConstraintToBody2Matrix(Handle, out result); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ContactManifold.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using System.Runtime.CompilerServices; 6 | using static JoltPhysicsSharp.JoltApi; 7 | 8 | namespace JoltPhysicsSharp; 9 | 10 | public readonly unsafe struct ContactManifold(nint handle) : IEquatable 11 | { 12 | public nint Handle { get; } = handle; public bool IsNull => Handle == 0; 13 | public static ContactManifold Null => new(0); 14 | public static implicit operator ContactManifold(nint handle) => new(handle); 15 | public static bool operator ==(ContactManifold left, ContactManifold right) => left.Handle == right.Handle; 16 | public static bool operator !=(ContactManifold left, ContactManifold right) => left.Handle != right.Handle; 17 | public static bool operator ==(ContactManifold left, nint right) => left.Handle == right; 18 | public static bool operator !=(ContactManifold left, nint right) => left.Handle != right; 19 | public bool Equals(ContactManifold other) => Handle == other.Handle; 20 | 21 | /// 22 | public override bool Equals(object? obj) => obj is ContactManifold handle && Equals(handle); 23 | 24 | /// 25 | public override int GetHashCode() => Handle.GetHashCode(); 26 | 27 | public readonly Vector3 WorldSpaceNormal 28 | { 29 | get 30 | { 31 | JPH_ContactManifold_GetWorldSpaceNormal(Handle, out Vector3 result); 32 | return result; 33 | } 34 | } 35 | 36 | public readonly float PenetrationDepth 37 | { 38 | get 39 | { 40 | return JPH_ContactManifold_GetPenetrationDepth(Handle); 41 | } 42 | } 43 | 44 | public readonly SubShapeID SubShapeID1 45 | { 46 | get 47 | { 48 | return JPH_ContactManifold_GetSubShapeID1(Handle); 49 | } 50 | } 51 | 52 | public readonly SubShapeID SubShapeID2 53 | { 54 | get 55 | { 56 | return JPH_ContactManifold_GetSubShapeID2(Handle); 57 | } 58 | } 59 | 60 | public readonly uint PointCount 61 | { 62 | get 63 | { 64 | return JPH_ContactManifold_GetPointCount(Handle); 65 | } 66 | } 67 | 68 | public Vector3 GetWorldSpaceContactPointOn1(uint index) 69 | { 70 | Vector3 result; 71 | JPH_ContactManifold_GetWorldSpaceContactPointOn1(Handle, index, &result); 72 | return result; 73 | } 74 | 75 | public void GetWorldSpaceContactPointOn1(uint index, out Vector3 result) 76 | { 77 | Unsafe.SkipInit(out result); 78 | fixed (Vector3* resultPtr = &result) 79 | JPH_ContactManifold_GetWorldSpaceContactPointOn1(Handle, index, resultPtr); 80 | } 81 | 82 | public void GetWorldSpaceContactPointOn1(uint index, Vector3* result) 83 | { 84 | JPH_ContactManifold_GetWorldSpaceContactPointOn1(Handle, index, result); 85 | } 86 | 87 | public Vector3 GetWorldSpaceContactPointOn2(uint index) 88 | { 89 | Vector3 result; 90 | JPH_ContactManifold_GetWorldSpaceContactPointOn2(Handle, index, &result); 91 | return result; 92 | } 93 | 94 | public void GetWorldSpaceContactPointOn2(uint index, out Vector3 result) 95 | { 96 | Unsafe.SkipInit(out result); 97 | fixed (Vector3* resultPtr = &result) 98 | JPH_ContactManifold_GetWorldSpaceContactPointOn2(Handle, index, resultPtr); 99 | } 100 | 101 | public void GetWorldSpaceContactPointOn2(uint index, Vector3* result) 102 | { 103 | JPH_ContactManifold_GetWorldSpaceContactPointOn2(Handle, index, result); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ContactSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using System.Runtime.CompilerServices; 6 | using static JoltPhysicsSharp.JoltApi; 7 | 8 | namespace JoltPhysicsSharp; 9 | 10 | public readonly unsafe struct ContactSettings(nint handle) : IEquatable 11 | { 12 | public nint Handle { get; } = handle; public bool IsNull => Handle == 0; 13 | public static ContactSettings Null => new(0); 14 | public static implicit operator ContactSettings(nint handle) => new(handle); 15 | public static bool operator ==(ContactSettings left, ContactSettings right) => left.Handle == right.Handle; 16 | public static bool operator !=(ContactSettings left, ContactSettings right) => left.Handle != right.Handle; 17 | public static bool operator ==(ContactSettings left, nint right) => left.Handle == right; 18 | public static bool operator !=(ContactSettings left, nint right) => left.Handle != right; 19 | public bool Equals(ContactSettings other) => Handle == other.Handle; 20 | 21 | /// 22 | public override bool Equals(object? obj) => obj is ContactSettings handle && Equals(handle); 23 | 24 | /// 25 | public override int GetHashCode() => Handle.GetHashCode(); 26 | 27 | public float Friction 28 | { 29 | readonly get => JPH_ContactSettings_GetFriction(Handle); 30 | set => JPH_ContactSettings_SetFriction(Handle, value); 31 | } 32 | 33 | public float Restitution 34 | { 35 | readonly get => JPH_ContactSettings_GetRestitution(Handle); 36 | set => JPH_ContactSettings_SetRestitution(Handle, value); 37 | } 38 | 39 | public float InvMassScale1 40 | { 41 | readonly get => JPH_ContactSettings_GetInvMassScale1(Handle); 42 | set => JPH_ContactSettings_SetInvMassScale1(Handle, value); 43 | } 44 | 45 | public float InvInertiaScale1 46 | { 47 | readonly get => JPH_ContactSettings_GetInvInertiaScale1(Handle); 48 | set => JPH_ContactSettings_SetInvInertiaScale1(Handle, value); 49 | } 50 | 51 | public float InvMassScale2 52 | { 53 | readonly get => JPH_ContactSettings_GetInvMassScale2(Handle); 54 | set => JPH_ContactSettings_SetInvMassScale2(Handle, value); 55 | } 56 | 57 | public float InvInertiaScale2 58 | { 59 | readonly get => JPH_ContactSettings_GetInvInertiaScale2(Handle); 60 | set => JPH_ContactSettings_SetInvInertiaScale2(Handle, value); 61 | } 62 | 63 | public bool IsSensor 64 | { 65 | get => JPH_ContactSettings_GetIsSensor(Handle); 66 | set => JPH_ContactSettings_SetIsSensor(Handle, value); 67 | } 68 | 69 | public Vector3 RelativeLinearSurfaceVelocity 70 | { 71 | get 72 | { 73 | Vector3 result; 74 | JPH_ContactSettings_GetRelativeLinearSurfaceVelocity(Handle, &result); 75 | return result; 76 | } 77 | set 78 | { 79 | JPH_ContactSettings_SetRelativeLinearSurfaceVelocity(Handle, &value); 80 | } 81 | } 82 | 83 | public Vector3 RelativeAngularSurfaceVelocity 84 | { 85 | get 86 | { 87 | Vector3 result; 88 | JPH_ContactSettings_GetRelativeAngularSurfaceVelocity(Handle, &result); 89 | return result; 90 | } 91 | set 92 | { 93 | JPH_ContactSettings_SetRelativeAngularSurfaceVelocity(Handle, &value); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/DelegateProxies.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | internal delegate object UserDataDelegate(); 10 | 11 | internal static partial class DelegateProxies 12 | { 13 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 14 | public static T? Create(object managedDel, T nativeDel, out GCHandle gch, out nint contextPtr) 15 | { 16 | if (managedDel == null) 17 | { 18 | gch = default; 19 | contextPtr = IntPtr.Zero; 20 | return default; 21 | } 22 | 23 | gch = GCHandle.Alloc(managedDel); 24 | contextPtr = GCHandle.ToIntPtr(gch); 25 | return nativeDel; 26 | } 27 | 28 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 29 | public static void Create(object managedDel, out GCHandle gch, out nint contextPtr) 30 | { 31 | if (managedDel == null) 32 | { 33 | gch = default; 34 | contextPtr = 0; 35 | return; 36 | } 37 | 38 | gch = GCHandle.Alloc(managedDel); 39 | contextPtr = GCHandle.ToIntPtr(gch); 40 | } 41 | 42 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 43 | public static nint CreateUserData(object userData, bool makeWeak = false) 44 | { 45 | userData = makeWeak ? new WeakReference(userData) : userData; 46 | var del = new UserDataDelegate(() => userData); 47 | Create(del, out _, out nint ctx); 48 | return ctx; 49 | } 50 | 51 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 52 | public static T? Get(nint context, out GCHandle handle) 53 | { 54 | if (context == 0) 55 | { 56 | handle = default; 57 | return default; 58 | } 59 | 60 | handle = GCHandle.FromIntPtr(context); 61 | return (T)handle.Target!; 62 | } 63 | 64 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 65 | public static T GetUserData(nint context, out GCHandle handle) 66 | { 67 | UserDataDelegate del = Get(context, out handle)!; 68 | object value = del.Invoke(); 69 | return value is WeakReference weak ? (T)weak.Target! : (T)value; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/DrawSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public struct DrawSettings 9 | { 10 | /// 11 | /// Draw the GetSupport() function, used for convex collision detection 12 | /// 13 | public Bool8 DrawGetSupportFunction = false; 14 | /// 15 | /// When drawing the support function, also draw which direction mapped to a specific support point 16 | /// 17 | public Bool8 DrawSupportDirection = false; 18 | /// 19 | /// Draw the faces that were found colliding during collision detection 20 | /// 21 | public Bool8 DrawGetSupportingFace = false; 22 | /// 23 | /// Draw the shapes of all bodies 24 | /// 25 | public Bool8 DrawShape = true; 26 | /// 27 | /// When mDrawShape is true and this is true, the shapes will be drawn in wireframe instead of solid. 28 | /// 29 | public Bool8 DrawShapeWireframe = false; 30 | /// 31 | /// Coloring scheme to use for shapes 32 | /// 33 | public ShapeColor DrawShapeColor = ShapeColor.MotionTypeColor; 34 | /// 35 | /// Draw a bounding box per body 36 | /// 37 | public Bool8 DrawBoundingBox = false; 38 | /// 39 | /// Draw the center of mass for each body 40 | /// 41 | public Bool8 DrawCenterOfMassTransform = false; 42 | /// 43 | /// Draw the world transform (which can be different than the center of mass) for each body 44 | /// 45 | public Bool8 DrawWorldTransform = false; 46 | /// 47 | /// Draw the velocity vector for each body 48 | /// 49 | public Bool8 DrawVelocity = false; 50 | /// 51 | /// Draw the mass and inertia (as the box equivalent) for each body 52 | /// 53 | public Bool8 DrawMassAndInertia = false; 54 | /// 55 | /// Draw stats regarding the sleeping algorithm of each body 56 | /// 57 | public Bool8 DrawSleepStats = false; 58 | /// 59 | /// Draw the vertices of soft bodies 60 | /// 61 | public Bool8 DrawSoftBodyVertices = false; 62 | /// 63 | /// Draw the velocities of the vertices of soft bodies 64 | /// 65 | public Bool8 DrawSoftBodyVertexVelocities = false; 66 | /// 67 | /// Draw the edge constraints of soft bodies 68 | /// 69 | public Bool8 DrawSoftBodyEdgeConstraints = false; 70 | /// 71 | /// Draw the bend constraints of soft bodies 72 | /// 73 | public Bool8 DrawSoftBodyBendConstraints = false; 74 | /// 75 | /// Draw the volume constraints of soft bodies 76 | /// 77 | public Bool8 DrawSoftBodyVolumeConstraints = false; 78 | /// 79 | /// Draw the skin constraints of soft bodies 80 | /// 81 | public Bool8 DrawSoftBodySkinConstraints = false; 82 | /// 83 | /// Draw the LRA constraints of soft bodies 84 | /// 85 | public Bool8 DrawSoftBodyLRAConstraints = false; 86 | /// 87 | /// Draw the predicted bounds of soft bodies 88 | /// 89 | public Bool8 DrawSoftBodyPredictedBounds = false; 90 | /// 91 | /// Coloring scheme to use for soft body constraints 92 | /// 93 | public SoftBodyConstraintColor DrawSoftBodyConstraintColor = SoftBodyConstraintColor.ConstraintType; 94 | 95 | public DrawSettings() 96 | { 97 | 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Foundation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Runtime.InteropServices; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public static class Foundation 10 | { 11 | /// 12 | /// If objects are closer than this distance, they are considered to be colliding (used for GJK) (unit: meter) 13 | /// 14 | public const float DefaultCollisionTolerance = 1.0e-4f; 15 | 16 | /// 17 | /// A factor that determines the accuracy of the penetration depth calculation. If the change of the squared distance is less than tolerance * current_penetration_depth^2 the algorithm will terminate. (unit: dimensionless) 18 | /// 19 | public const float DefaultPenetrationTolerance = 1.0e-4f; 20 | 21 | /// 22 | /// How much padding to add around objects 23 | /// 24 | public const float DefaultConvexRadius = 0.05f; 25 | 26 | /// 27 | /// Used by (Tapered)CapsuleShape to determine when supporting face is an edge rather than a point (unit: meter) 28 | /// 29 | public const float CapsuleProjectionSlop = 0.02f; 30 | 31 | /// 32 | /// Maximum amount of jobs to allow 33 | /// 34 | public const int MaxPhysicsJobs = 2048; 35 | 36 | /// 37 | /// Maximum amount of barriers to allow 38 | /// 39 | public const int MaxPhysicsBarriers = 8; 40 | 41 | public static bool Init(bool doublePrecision = false) 42 | { 43 | JoltApi.DoublePrecision = doublePrecision; 44 | return JPH_Init(); 45 | } 46 | 47 | public static void Shutdown() => JPH_Shutdown(); 48 | 49 | private static TraceDelegate? s_traceCallback; 50 | private static AssertFailedDelegate? s_assertCallback; 51 | 52 | public static unsafe void SetTraceHandler(TraceDelegate callback) 53 | { 54 | s_traceCallback = callback; 55 | 56 | JPH_SetTraceHandler(callback != null ? &OnNativeTraceCallback : null); 57 | } 58 | 59 | public static unsafe void SetAssertFailureHandler(AssertFailedDelegate callback) 60 | { 61 | s_assertCallback = callback; 62 | 63 | JPH_SetAssertFailureHandler(callback != null ? &OnNativeAssertCallback : null); 64 | } 65 | 66 | public delegate void TraceDelegate(string message); 67 | 68 | public delegate bool AssertFailedDelegate(string expression, string message, string file, uint line); 69 | 70 | [UnmanagedCallersOnly] 71 | private static unsafe void OnNativeTraceCallback(byte* messagePtr) 72 | { 73 | if (s_traceCallback != null) 74 | { 75 | string message = ConvertToManaged(messagePtr)!; 76 | s_traceCallback(message); 77 | } 78 | } 79 | 80 | [UnmanagedCallersOnly] 81 | private static unsafe Bool8 OnNativeAssertCallback(byte* expressionPtr, byte* messagePtr, byte* filePtr, uint line) 82 | { 83 | string expression = ConvertToManaged(expressionPtr)!; 84 | string message = ConvertToManaged(messagePtr)!; 85 | string file = ConvertToManaged(filePtr)!; 86 | 87 | if (s_assertCallback != null) 88 | { 89 | return s_assertCallback(expression, message, file, line); 90 | } 91 | 92 | return Bool8.True; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/GroupFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | 9 | public unsafe class GroupFilter : NativeObject 10 | { 11 | internal GroupFilter(nint handle, bool owns = true) 12 | : base(handle, owns) 13 | { 14 | } 15 | 16 | protected override void DisposeNative() 17 | { 18 | JPH_GroupFilter_Destroy(Handle); 19 | } 20 | 21 | public bool CanCollide(in CollisionGroup group1, in CollisionGroup group2) 22 | { 23 | group1.ToNative(out JPH_CollisionGroup group1Native); 24 | group2.ToNative(out JPH_CollisionGroup group2Native); 25 | return JPH_GroupFilter_CanCollide(Handle, &group1Native, &group2Native); 26 | } 27 | 28 | internal static GroupFilter? GetObject(nint handle) 29 | { 30 | return GetOrAddObject(handle, (nint h) => new GroupFilter(h, false)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/GroupFilterTable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using System.Runtime.InteropServices; 6 | using static JoltPhysicsSharp.JoltApi; 7 | 8 | namespace JoltPhysicsSharp; 9 | 10 | public sealed class GroupFilterTable : GroupFilter 11 | { 12 | public GroupFilterTable(uint numSubGroups = 0) 13 | : base(JPH_GroupFilterTable_Create(numSubGroups)) 14 | { 15 | } 16 | 17 | internal GroupFilterTable(nint handle, bool owns = true) 18 | : base(handle, owns) 19 | { 20 | } 21 | 22 | public void DisableCollision(CollisionSubGroupID subGroup1, CollisionSubGroupID subGroup2) 23 | { 24 | JPH_GroupFilterTable_DisableCollision(Handle, subGroup1, subGroup2); 25 | } 26 | 27 | public void EnableCollision(CollisionSubGroupID subGroup1, CollisionSubGroupID subGroup2) 28 | { 29 | JPH_GroupFilterTable_EnableCollision(Handle, subGroup1, subGroup2); 30 | } 31 | public bool IsCollisionEnabled(CollisionSubGroupID subGroup1, CollisionSubGroupID subGroup2) 32 | { 33 | return JPH_GroupFilterTable_IsCollisionEnabled(Handle, subGroup1, subGroup2); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/IndexedTriangle.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public readonly struct IndexedTriangle : IEquatable 7 | { 8 | public IndexedTriangle(in uint i1, in uint i2, in uint i3, uint materialIndex = 0, uint userData = 0) 9 | { 10 | I1 = i1; 11 | I2 = i2; 12 | I3 = i3; 13 | MaterialIndex = materialIndex; 14 | UserData = userData; 15 | } 16 | 17 | public IndexedTriangle(in int i1, in int i2, in int i3, uint materialIndex = 0, uint userData = 0) 18 | { 19 | I1 = (uint)i1; 20 | I2 = (uint)i2; 21 | I3 = (uint)i3; 22 | MaterialIndex = materialIndex; 23 | UserData = userData; 24 | } 25 | 26 | public uint I1 { get; } 27 | public uint I2 { get; } 28 | public uint I3 { get; } 29 | public uint MaterialIndex { get; } 30 | public uint UserData { get; } 31 | 32 | public static bool operator ==(IndexedTriangle left, IndexedTriangle right) 33 | { 34 | return 35 | left.I1 == right.I1 36 | && left.I2 == right.I2 37 | && left.I3 == right.I3 38 | && left.MaterialIndex == right.MaterialIndex 39 | && left.UserData == right.UserData; 40 | } 41 | 42 | public static bool operator !=(IndexedTriangle left, IndexedTriangle right) 43 | { 44 | return left.I1 != right.I1 || left.I2 != right.I2 || left.I3 != right.I3 || left.MaterialIndex != right.MaterialIndex || left.UserData != right.UserData; 45 | } 46 | 47 | public bool Equals(IndexedTriangle other) => this == other; 48 | 49 | /// 50 | public override bool Equals(object? obj) => obj is IndexedTriangle handle && Equals(handle); 51 | 52 | /// 53 | public override int GetHashCode() => HashCode.Combine(I1, I2, I3, MaterialIndex); 54 | 55 | public override string ToString() => $"I1: {I1}, I2: {I2}, I3: {I3}, MaterialIndex: {MaterialIndex}, UserData: {UserData}"; 56 | } 57 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/IndexedTriangleNoMaterial.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public readonly struct IndexedTriangleNoMaterial : IEquatable 7 | { 8 | public IndexedTriangleNoMaterial(in uint i1, in uint i2, in uint i3) 9 | { 10 | I1 = i1; 11 | I2 = i2; 12 | I3 = i3; 13 | } 14 | 15 | public uint I1 { get; } 16 | public uint I2 { get; } 17 | public uint I3 { get; } 18 | 19 | public static bool operator ==(IndexedTriangleNoMaterial left, IndexedTriangleNoMaterial right) 20 | { 21 | return left.I1 == right.I1 && left.I2 == right.I2 && left.I3 == right.I3; 22 | } 23 | 24 | public static bool operator !=(IndexedTriangleNoMaterial left, IndexedTriangleNoMaterial right) 25 | { 26 | return left.I1 != right.I1 || left.I2 != right.I2 || left.I3 != right.I3; 27 | } 28 | 29 | public bool Equals(IndexedTriangleNoMaterial other) => this == other; 30 | 31 | /// 32 | public override bool Equals(object? obj) => obj is IndexedTriangleNoMaterial handle && Equals(handle); 33 | 34 | /// 35 | public override int GetHashCode() => HashCode.Combine(I1, I2, I3); 36 | 37 | public override string ToString() => $"I1: {I1}, I2: {I2}, I3: {I3}"; 38 | } 39 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/JobSystem.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public abstract class JobSystem : NativeObject 9 | { 10 | protected JobSystem(nint handle) 11 | { 12 | Handle = handle; 13 | } 14 | 15 | 16 | protected override void DisposeNative() 17 | { 18 | JPH_JobSystem_Destroy(Handle); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/JobSystemThreadPool.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed unsafe class JobSystemThreadPool : JobSystem 9 | { 10 | public JobSystemThreadPool() 11 | : base(JPH_JobSystemThreadPool_Create(null)) 12 | { 13 | } 14 | 15 | public JobSystemThreadPool(in JobSystemThreadPoolConfig config) 16 | : base(JPH_JobSystemThreadPool_Create(in config)) 17 | { 18 | } 19 | } 20 | 21 | public struct JobSystemThreadPoolConfig 22 | { 23 | public uint maxJobs; 24 | public uint maxBarriers; 25 | public int numThreads; 26 | } 27 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Jolt.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics; 5 | using System.Runtime.CompilerServices; 6 | using static JoltPhysicsSharp.JoltApi; 7 | 8 | namespace JoltPhysicsSharp; 9 | 10 | public static class Jolt 11 | { 12 | public static unsafe CollisionEstimationResult EstimateCollisionResponse(in Body body1, in Body body2, in ContactManifold manifold, float combinedFriction, float combinedRestitution, float minVelocityForRestitution = 1.0f, int numIterations = 10) 13 | { 14 | Debug.Assert(numIterations > 0); 15 | 16 | CollisionEstimationResult result; 17 | JPH_EstimateCollisionResponse( 18 | body1.Handle, 19 | body2.Handle, 20 | manifold.Handle, 21 | combinedFriction, 22 | combinedRestitution, 23 | minVelocityForRestitution, 24 | numIterations, 25 | &result); 26 | return result; 27 | } 28 | 29 | [SkipLocalsInit] 30 | public static unsafe void EstimateCollisionResponse(in Body body1, in Body body2, in ContactManifold manifold, out CollisionEstimationResult result, float combinedFriction, float combinedRestitution, float minVelocityForRestitution = 1.0f, int numIterations = 10) 31 | { 32 | Debug.Assert(numIterations > 0); 33 | Unsafe.SkipInit(out result); 34 | 35 | // Pin - Pin data in preparation for calling the P/Invoke. 36 | fixed (CollisionEstimationResult* __result_native = &result) 37 | { 38 | JPH_EstimateCollisionResponse( 39 | body1.Handle, 40 | body2.Handle, 41 | manifold.Handle, 42 | combinedFriction, 43 | combinedRestitution, 44 | minVelocityForRestitution, 45 | numIterations, 46 | __result_native); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/JoltPhysicsSharp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0;net9.0 5 | Cross platform .NET bindings for Jolt Physics engine 6 | physics standard game gamedev jolt 7 | README.md 8 | true 9 | true 10 | 11 | 12 | 13 | 14 | 2.16.2 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | runtimes/win-x64/native 26 | true 27 | False 28 | 29 | 30 | runtimes/win-x64/native 31 | true 32 | False 33 | 34 | 35 | runtimes/win-arm64/native 36 | True 37 | False 38 | 39 | 40 | runtimes/win-arm64/native 41 | True 42 | False 43 | 44 | 45 | runtimes\linux-x64\native 46 | True 47 | False 48 | 49 | 50 | runtimes\linux-arm64\native 51 | True 52 | False 53 | 54 | 55 | runtimes\osx\native 56 | True 57 | False 58 | 59 | 60 | runtimes/android-arm/native 61 | True 62 | False 63 | 64 | 65 | runtimes/android-arm64/native 66 | True 67 | False 68 | 69 | 70 | runtimes/android-x64/native 71 | True 72 | False 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/MathUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using System.Runtime.CompilerServices; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public static class MathUtil 10 | { 11 | /// 12 | /// Converts degrees to radians. 13 | /// 14 | /// Converts degrees to radians. 15 | /// The converted value. 16 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 17 | public static float DegreesToRadians(float degree) => degree * (MathF.PI / 180.0f); 18 | 19 | /// 20 | /// Converts radians to degrees. 21 | /// 22 | /// The angle in radians. 23 | /// The converted value. 24 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 25 | public static float RadiansToDegrees(float radians) => radians * (180.0f / MathF.PI); 26 | 27 | public static Vector3 GetNormalizedPerpendicular(this Vector3 vector) 28 | { 29 | if (MathF.Abs(vector.X) > MathF.Abs(vector.Y)) 30 | { 31 | float len = MathF.Sqrt(vector.X * vector.X + vector.Z * vector.Z); 32 | return new(vector.Z / len, 0.0f, -vector.X / len); 33 | } 34 | else 35 | { 36 | float len = MathF.Sqrt(vector.Y * vector.Y + vector.Z * vector.Z); 37 | return new(0.0f, vector.Z / len, -vector.Y / len); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Matrix4x4Extensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public static class Matrix4x4Extensions 9 | { 10 | public static Vector4 GetColumn(in this Matrix4x4 matrix, int j) 11 | { 12 | return new(matrix[0, j], matrix[1, j], matrix[2,j], matrix[3,j]); 13 | } 14 | 15 | public static void SetColumn(ref this Matrix4x4 matrix, int j, Vector4 value) 16 | { 17 | matrix[0, j] = value.X; 18 | matrix[1, j] = value.Y; 19 | matrix[2, j] = value.Z; 20 | matrix[3, j] = value.W; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/MotionProperties.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public readonly unsafe struct MotionProperties(nint handle) : IEquatable 10 | { 11 | public nint Handle { get; } = handle; 12 | public readonly bool IsNull => Handle == 0; 13 | public readonly bool IsNotNull => Handle != 0; 14 | public static MotionProperties Null => new(0); 15 | public static implicit operator MotionProperties(nint handle) => new(handle); 16 | public static bool operator ==(MotionProperties left, MotionProperties right) => left.Handle == right.Handle; 17 | public static bool operator !=(MotionProperties left, MotionProperties right) => left.Handle != right.Handle; 18 | public static bool operator ==(MotionProperties left, nint right) => left.Handle == right; 19 | public static bool operator !=(MotionProperties left, nint right) => left.Handle != right; 20 | public bool Equals(MotionProperties other) => Handle == other.Handle; 21 | 22 | /// 23 | public override bool Equals(object? obj) => obj is MotionProperties handle && Equals(handle); 24 | 25 | /// 26 | public override int GetHashCode() => Handle.GetHashCode(); 27 | 28 | public AllowedDOFs AllowedDOFs 29 | { 30 | get => JPH_MotionProperties_GetAllowedDOFs(Handle); 31 | } 32 | 33 | public float LinearDamping 34 | { 35 | readonly get => JPH_MotionProperties_GetLinearDamping(Handle); 36 | set => JPH_MotionProperties_SetLinearDamping(Handle, value); 37 | } 38 | 39 | public float AngularDamping 40 | { 41 | readonly get => JPH_MotionProperties_GetAngularDamping(Handle); 42 | set => JPH_MotionProperties_SetAngularDamping(Handle, value); 43 | } 44 | 45 | public float InverseMassUnchecked 46 | { 47 | get => JPH_MotionProperties_GetInverseMassUnchecked(Handle); 48 | } 49 | 50 | public Vector3 InverseInertiaDiagonal 51 | { 52 | get 53 | { 54 | Vector3 result; 55 | JPH_MotionProperties_GetInverseInertiaDiagonal(Handle, &result); 56 | return result; 57 | } 58 | } 59 | 60 | public Quaternion InertiaRotation 61 | { 62 | get 63 | { 64 | Quaternion result; 65 | JPH_MotionProperties_GetInertiaRotation(Handle, &result); 66 | return result; 67 | } 68 | } 69 | 70 | public void SetMassProperties(AllowedDOFs allowedDOFs, in MassProperties massProperties) 71 | { 72 | JPH_MotionProperties_SetMassProperties(Handle, allowedDOFs, in massProperties); 73 | } 74 | 75 | public void SetInverseMass(float inverseMass) 76 | { 77 | JPH_MotionProperties_SetInverseMass(Handle, inverseMass); 78 | } 79 | 80 | public void SetInverseInertia(in Vector3 diagonal, in Quaternion rotation) 81 | { 82 | fixed (Vector3* diagonalPtr = &diagonal) 83 | fixed (Quaternion* rotationPtr = &rotation) 84 | JPH_MotionProperties_SetInverseInertia(Handle, diagonalPtr, rotationPtr); 85 | } 86 | 87 | public void ScaleToMass(float mass) 88 | { 89 | JPH_MotionProperties_ScaleToMass(Handle, mass); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/MotionQuality.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Motion quality, or how well it detects collisions when it has a high velocity 8 | /// 9 | public enum MotionQuality 10 | { 11 | /// 12 | /// Update the body in discrete steps. Body will tunnel throuh thin objects if its velocity is high enough. 13 | /// This is the cheapest way of simulating a body. 14 | /// 15 | Discrete = 0, 16 | 17 | /// 18 | /// Update the body using linear casting. When stepping the body, its collision shape is cast from 19 | /// start to destination using the starting rotation. The body will not be able to tunnel through thin 20 | /// objects at high velocity, but tunneling is still possible if the body is long and thin and has high 21 | /// angular velocity. Time is stolen from the object (which means it will move up to the first collision 22 | /// and will not bounce off the surface until the next integration step). This will make the body appear 23 | /// to go slower when it collides with high velocity. In order to not get stuck, the body is always 24 | /// allowed to move by a fraction of it's inner radius, which may eventually lead it to pass through geometry. 25 | /// 26 | /// Note that if you're using a collision listener, you can receive contact added/persisted notifications of contacts 27 | /// that may in the end not happen. This happens between bodies that are using casting: If bodies A and B collide at t1 28 | /// and B and C collide at t2 where t2 < t1 and A and C don't collide. In this case you may receive an incorrect contact 29 | /// point added callback between A and B (which will be removed the next frame). 30 | /// 31 | LinearCast = 1, 32 | } 33 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/MotionType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Motion type of a physics body 8 | /// 9 | public enum MotionType 10 | { 11 | /// 12 | /// Non movable 13 | /// 14 | Static = 0, 15 | /// 16 | /// Movable using velocities only, does not respond to forces 17 | /// 18 | Kinematic = 1, 19 | /// 20 | /// Responds to forces as a normal physics object 21 | /// 22 | Dynamic = 2 23 | } 24 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/MotorSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public record struct MotorSettings 9 | { 10 | public SpringSettings SpringSettings; 11 | public float MinForceLimit = float.MinValue; 12 | public float MaxForceLimit = float.MaxValue; 13 | public float MinTorqueLimit = float.MinValue; 14 | public float MaxTorqueLimit = float.MaxValue; 15 | 16 | public MotorSettings() 17 | { 18 | SpringSettings = new SpringSettings(SpringMode.FrequencyAndDamping, 2.0f, 1.0f); 19 | } 20 | 21 | public MotorSettings(float frequency, float damping) 22 | { 23 | SpringSettings = new SpringSettings(SpringMode.FrequencyAndDamping, frequency, damping); 24 | Debug.Assert(IsValid); 25 | } 26 | 27 | public MotorSettings(float frequency, float damping, float forceLimit, float torqueLimit) 28 | { 29 | SpringSettings = new SpringSettings(SpringMode.FrequencyAndDamping, frequency, damping); 30 | MinForceLimit = -forceLimit; 31 | MaxForceLimit = forceLimit; 32 | MinTorqueLimit = -torqueLimit; 33 | MaxTorqueLimit = torqueLimit; 34 | Debug.Assert(IsValid); 35 | } 36 | 37 | /// 38 | /// Check if settings are valid 39 | /// 40 | public readonly bool IsValid 41 | { 42 | get 43 | { 44 | return SpringSettings.FrequencyOrStiffness >= 0.0f && SpringSettings.Damping >= 0.0f && MinForceLimit <= MaxForceLimit && MinTorqueLimit <= MaxTorqueLimit; 45 | } 46 | } 47 | 48 | /// 49 | /// Set asymmetric force limits 50 | /// 51 | /// 52 | /// 53 | public void SetForceLimits(float min, float max) 54 | { 55 | Debug.Assert(min <= max); 56 | 57 | MinForceLimit = min; 58 | MaxForceLimit = max; 59 | } 60 | 61 | /// 62 | /// Set asymmetric torque limits 63 | /// 64 | /// 65 | /// 66 | public void SetTorqueLimits(float min, float max) 67 | { 68 | Debug.Assert(min <= max); 69 | 70 | MinTorqueLimit = min; 71 | MaxTorqueLimit = max; 72 | } 73 | 74 | /// 75 | /// Set symmetric force limits 76 | /// 77 | /// 78 | public void SetForceLimit(float limit) 79 | { 80 | MinForceLimit = -limit; 81 | MaxForceLimit = limit; 82 | } 83 | 84 | /// 85 | /// Set symmetric torque limits 86 | /// 87 | /// 88 | public void SetTorqueLimit(float limit) 89 | { 90 | MinTorqueLimit = -limit; 91 | MaxTorqueLimit = limit; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/MotorState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public enum MotorState 7 | { 8 | Off, 9 | Velocity, 10 | Position, 11 | } 12 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ObjectLayer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public readonly struct ObjectLayer(uint value) : IEquatable 9 | { 10 | public const int Bits = 32; // Must be updated according to JPH_OBJECT_LAYER_BITS 11 | 12 | /// 13 | /// Constant value used to indicate an invalid object layer 14 | /// 15 | public const uint ObjectLayerInvalid = ~0U; 16 | public uint Value { get; } = value; 17 | public bool IsValid => Value != ObjectLayerInvalid; 18 | public bool IsInvalid => Value == ObjectLayerInvalid; 19 | 20 | public static ObjectLayer Invalid => new(ObjectLayerInvalid); 21 | 22 | public static implicit operator ObjectLayer(uint id) => new(id); 23 | public static implicit operator uint(in ObjectLayer id) => id.Value; 24 | 25 | public static bool operator ==(ObjectLayer left, ObjectLayer right) => left.Value == right.Value; 26 | public static bool operator !=(ObjectLayer left, ObjectLayer right) => left.Value != right.Value; 27 | public static bool operator ==(ObjectLayer left, uint right) => left.Value == right; 28 | public static bool operator !=(ObjectLayer left, uint right) => left.Value != right; 29 | public bool Equals(ObjectLayer other) => Value == other.Value; 30 | 31 | /// 32 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is ObjectLayer handle && Equals(handle); 33 | 34 | /// 35 | public override int GetHashCode() => Value.GetHashCode(); 36 | 37 | public override string ToString() => Value.ToString(); 38 | } 39 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ObjectLayerFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Runtime.InteropServices; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public abstract class ObjectLayerFilter : NativeObject 10 | { 11 | private static readonly JPH_ObjectLayerFilter_Procs _procs; 12 | private readonly nint _listenerUserData; 13 | 14 | static ObjectLayerFilter() 15 | { 16 | _procs = new JPH_ObjectLayerFilter_Procs 17 | { 18 | ShouldCollide = &ShouldCollideCallback, 19 | }; 20 | JPH_ObjectLayerFilter_SetProcs(in _procs); 21 | } 22 | 23 | public ObjectLayerFilter() 24 | { 25 | _listenerUserData = DelegateProxies.CreateUserData(this, true); 26 | Handle = JPH_ObjectLayerFilter_Create(_listenerUserData); 27 | } 28 | 29 | protected override void DisposeNative() 30 | { 31 | DelegateProxies.GetUserData(_listenerUserData, out GCHandle gch); 32 | 33 | JPH_ObjectLayerFilter_Destroy(Handle); 34 | gch.Free(); 35 | } 36 | 37 | protected abstract bool ShouldCollide(ObjectLayer layer); 38 | 39 | [UnmanagedCallersOnly] 40 | private static Bool8 ShouldCollideCallback(IntPtr context, ObjectLayer layer) 41 | { 42 | ObjectLayerFilter listener = DelegateProxies.GetUserData(context, out _); 43 | return listener.ShouldCollide(layer); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ObjectLayerPairFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public abstract class ObjectLayerPairFilter : NativeObject 7 | { 8 | protected ObjectLayerPairFilter(nint handle, bool owns) 9 | : base(handle, owns) 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ObjectLayerPairFilterMask.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed class ObjectLayerPairFilterMask : ObjectLayerPairFilter 9 | { 10 | public const int NumBits = ObjectLayer.Bits / 2; 11 | public const int Mask = (1 << NumBits) - 1; 12 | 13 | internal ObjectLayerPairFilterMask(nint handle, bool owns) 14 | : base(handle, owns) 15 | { 16 | } 17 | 18 | public ObjectLayerPairFilterMask() 19 | : this(JPH_ObjectLayerPairFilterMask_Create(), true) 20 | { 21 | } 22 | 23 | public static ObjectLayer GetObjectLayer(uint group, uint mask = Mask) 24 | { 25 | return JPH_ObjectLayerPairFilterMask_GetObjectLayer(group, mask); 26 | } 27 | 28 | public static uint GetGroup(in ObjectLayer layer) 29 | { 30 | return JPH_ObjectLayerPairFilterMask_GetGroup(in layer); 31 | } 32 | 33 | public static uint GetMask(in ObjectLayer layer) 34 | { 35 | return JPH_ObjectLayerPairFilterMask_GetMask(in layer); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ObjectLayerPairFilterTable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed class ObjectLayerPairFilterTable : ObjectLayerPairFilter 9 | { 10 | internal ObjectLayerPairFilterTable(nint handle, bool owns) 11 | : base(handle, owns) 12 | { 13 | } 14 | 15 | public ObjectLayerPairFilterTable(uint numObjectLayers) 16 | : this(JPH_ObjectLayerPairFilterTable_Create(numObjectLayers), true) 17 | { 18 | } 19 | 20 | public void DisableCollision(ObjectLayer layer1, ObjectLayer layer2) 21 | { 22 | JPH_ObjectLayerPairFilterTable_DisableCollision(Handle, layer1, layer2); 23 | } 24 | 25 | public void EnableCollision(ObjectLayer layer1, ObjectLayer layer2) 26 | { 27 | JPH_ObjectLayerPairFilterTable_EnableCollision(Handle, layer1, layer2); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ObjectVsBroadPhaseLayerFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public abstract class ObjectVsBroadPhaseLayerFilter : NativeObject 7 | { 8 | protected ObjectVsBroadPhaseLayerFilter(nint handle) 9 | : base(handle) 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ObjectVsBroadPhaseLayerFilterMask.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed class ObjectVsBroadPhaseLayerFilterMask : ObjectVsBroadPhaseLayerFilter 9 | { 10 | public ObjectVsBroadPhaseLayerFilterMask(BroadPhaseLayerInterface broadPhaseLayerInterface) 11 | : base(JPH_ObjectVsBroadPhaseLayerFilterMask_Create(broadPhaseLayerInterface.Handle)) 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ObjectVsBroadPhaseLayerFilterTable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed class ObjectVsBroadPhaseLayerFilterTable : ObjectVsBroadPhaseLayerFilter 9 | { 10 | public ObjectVsBroadPhaseLayerFilterTable( 11 | BroadPhaseLayerInterface broadPhaseLayerInterface, uint numBroadPhaseLayers, 12 | ObjectLayerPairFilter objectLayerPairFilter, uint numObjectLayers) 13 | : base(JPH_ObjectVsBroadPhaseLayerFilterTable_Create(broadPhaseLayerInterface.Handle, numBroadPhaseLayers, objectLayerPairFilter.Handle, numObjectLayers)) 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/OverrideMassProperties.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Enum used in to indicate how mass and inertia should be calculated. 8 | /// 9 | public enum OverrideMassProperties 10 | { 11 | /// 12 | /// Tells the system to calculate the mass and inertia based on density 13 | /// 14 | CalculateMassAndInertia, 15 | /// 16 | /// Tells the system to take the mass from and to calculate the inertia based on density of the shapes and to scale it to the provided mass 17 | /// 18 | CalculateInertia, 19 | /// 20 | /// Tells the system to take the mass and inertia from 21 | /// 22 | MassAndInertiaProvided 23 | } 24 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/PhysicsMaterial.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public class PhysicsMaterial : NativeObject 9 | { 10 | public PhysicsMaterial(string name, in JoltColor color) 11 | : base(JPH_PhysicsMaterial_Create(name, color.PackedValue), true) 12 | { 13 | } 14 | 15 | internal PhysicsMaterial(nint handle, bool owns) 16 | : base(handle, owns) 17 | { 18 | } 19 | 20 | protected override void DisposeNative() 21 | { 22 | JPH_PhysicsMaterial_Destroy(Handle); 23 | } 24 | 25 | public string? DebugName => JPH_PhysicsMaterial_GetDebugName(Handle); 26 | public uint DebugColor => JPH_PhysicsMaterial_GetDebugColor(Handle); 27 | 28 | internal static PhysicsMaterial? GetObject(nint handle) 29 | { 30 | return GetOrAddObject(handle, (nint h) => new PhysicsMaterial(h, false)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/PhysicsSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public record struct PhysicsSettings 7 | { 8 | public int MaxInFlightBodyPairs; 9 | public int StepListenersBatchSize; 10 | public int StepListenerBatchesPerJob; 11 | public float Baumgarte; 12 | public float SpeculativeContactDistance; 13 | public float PenetrationSlop; 14 | public float LinearCastThreshold; 15 | public float LinearCastMaxPenetration; 16 | public float ManifoldTolerance; 17 | public float MaxPenetrationDistance; 18 | public float BodyPairCacheMaxDeltaPositionSq; 19 | public float BodyPairCacheCosMaxDeltaRotationDiv2; 20 | public float ContactNormalCosMaxDeltaRotation; 21 | public float ContactPointPreserveLambdaMaxDistSq; 22 | public uint NumVelocitySteps; 23 | public uint NumPositionSteps; 24 | public float MinVelocityForRestitution; 25 | public float TimeBeforeSleep; 26 | public float PointVelocitySleepThreshold; 27 | public Bool8 DeterministicSimulation; 28 | public Bool8 ConstraintWarmStart; 29 | public Bool8 UseBodyPairContactCache; 30 | public Bool8 UseManifoldReduction; 31 | public Bool8 UseLargeIslandSplitter; 32 | public Bool8 AllowSleeping; 33 | public Bool8 CheckActiveEdges; 34 | } 35 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/PhysicsUpdateError.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Enum used by to report error conditions during the call. This is a bit field, multiple errors can trigger in the same update. 8 | /// 9 | [Flags] 10 | public enum PhysicsUpdateError 11 | { 12 | /// 13 | /// No errors. 14 | /// 15 | None = 0, 16 | /// 17 | /// The manifold cache is full, this means that the total number of contacts between bodies is too high. 18 | /// Some contacts were ignored. Increase maxContactConstraints in . 19 | /// 20 | ManifoldCacheFull = 1 << 0, 21 | /// 22 | /// The body pair cache is full, this means that too many bodies contacted. Some contacts were ignored. 23 | /// Increase maxBodyPairs in . 24 | /// 25 | BodyPairCacheFull = 1 << 1, 26 | /// 27 | /// The contact constraints buffer is full. Some contacts were ignored. 28 | /// Increase inMaxContactConstraints in . 29 | /// 30 | ContactConstraintsFull = 1 << 2, 31 | } 32 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Ragdoll.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public class RagdollSettings : NativeObject 10 | { 11 | internal RagdollSettings(nint handle, bool owns = true) 12 | : base(handle, owns) 13 | { 14 | } 15 | 16 | public RagdollSettings() 17 | : base(JPH_RagdollSettings_Create()) 18 | { 19 | } 20 | 21 | protected override void DisposeNative() 22 | { 23 | JPH_RagdollSettings_Destroy(Handle); 24 | } 25 | 26 | public Skeleton? Skeleton 27 | { 28 | get => Skeleton.GetObject(JPH_RagdollSettings_GetSkeleton(Handle)); 29 | set => JPH_RagdollSettings_SetSkeleton(Handle, value?.Handle ?? nint.Zero); 30 | } 31 | 32 | public bool Stabilize() => JPH_RagdollSettings_Stabilize(Handle); 33 | 34 | public unsafe void DisableParentChildCollisions(in Matrix4x4? jointMatrices = default, float minSeparationDistance = 0.0f) 35 | { 36 | Matrix4x4 callJointMatrices = jointMatrices.GetValueOrDefault(); 37 | JPH_RagdollSettings_DisableParentChildCollisions(Handle, 38 | jointMatrices.HasValue ? &callJointMatrices : default, 39 | minSeparationDistance); 40 | } 41 | 42 | public void CalculateBodyIndexToConstraintIndex() 43 | { 44 | JPH_RagdollSettings_CalculateBodyIndexToConstraintIndex(Handle); 45 | } 46 | 47 | public int GetConstraintIndexForBodyIndex(int bodyIndex) 48 | { 49 | return JPH_RagdollSettings_GetConstraintIndexForBodyIndex(Handle, bodyIndex); 50 | } 51 | 52 | public void CalculateConstraintIndexToBodyIdxPair() 53 | { 54 | JPH_RagdollSettings_CalculateConstraintIndexToBodyIdxPair(Handle); 55 | } 56 | } 57 | 58 | public class Ragdoll : NativeObject 59 | { 60 | internal Ragdoll(nint handle, bool owns = true) 61 | : base(handle, owns) 62 | { 63 | } 64 | 65 | public Ragdoll(RagdollSettings settings, PhysicsSystem system) 66 | : base(JPH_RagdollSettings_CreateRagdoll(settings.Handle, system.Handle, 0u, 0u)) 67 | { 68 | } 69 | 70 | public Ragdoll(RagdollSettings settings, PhysicsSystem system, CollisionGroupID collisionGroup) 71 | : base(JPH_RagdollSettings_CreateRagdoll(settings.Handle, system.Handle, collisionGroup.Value, 0u)) 72 | { 73 | } 74 | 75 | public Ragdoll(RagdollSettings settings, PhysicsSystem system, CollisionGroupID collisionGroup, ulong userData) 76 | : base(JPH_RagdollSettings_CreateRagdoll(settings.Handle, system.Handle, collisionGroup.Value, userData)) 77 | { 78 | } 79 | 80 | protected override void DisposeNative() 81 | { 82 | JPH_Ragdoll_Destroy(Handle); 83 | } 84 | 85 | public void AddToPhysicsSystem(Activation activationMode = Activation.Activate, bool lockBodies = true) 86 | { 87 | JPH_Ragdoll_AddToPhysicsSystem(Handle, activationMode, lockBodies); 88 | } 89 | 90 | public void RemoveFromPhysicsSystem(bool lockBodies = true) 91 | { 92 | JPH_Ragdoll_RemoveFromPhysicsSystem(Handle, lockBodies); 93 | } 94 | 95 | public void Activate(bool lockBodies = true) => JPH_Ragdoll_Activate(Handle, lockBodies); 96 | public bool IsActive(bool lockBodies = true) => JPH_Ragdoll_IsActive(Handle, lockBodies); 97 | public void ResetWarmStart() => JPH_Ragdoll_ResetWarmStart(Handle); 98 | 99 | internal static Ragdoll? GetObject(nint handle) => GetOrAddObject(handle, (nint h) => new Ragdoll(h, false)); 100 | } 101 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/RayCastResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public struct RayCastResult 7 | { 8 | /// 9 | /// C Float Epsilon. 10 | /// C# Float Epsilon has a different value than C Float Epsilon, which we need for default values 11 | /// 12 | const float CEpsilon = 1.192092896e-07F; 13 | 14 | public BodyID BodyID; 15 | public float Fraction; 16 | public uint/*SubShapeID*/ subShapeID2; 17 | 18 | /// 19 | /// Default values for raycasting. 20 | /// Required for raycasting successfully, as it expects these values to do it correctly. 21 | /// 22 | public static RayCastResult Default => new() 23 | { 24 | BodyID = BodyID.Invalid, 25 | Fraction = 1.0f + CEpsilon, 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/RayCastSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | 8 | namespace JoltPhysicsSharp; 9 | 10 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 11 | public struct RayCastSettings : IEquatable 12 | { 13 | /// 14 | /// How backfacing triangles should be treated (should we report back facing hits for triangle based shapes, e.g. MeshShape/HeightFieldShape?) 15 | /// 16 | public BackFaceMode BackFaceModeTriangles = BackFaceMode.IgnoreBackFaces; 17 | 18 | /// 19 | /// How backfacing convex objects should be treated (should we report back facing hits for convex shapes?) 20 | /// 21 | public BackFaceMode BackFaceModeConvex = BackFaceMode.IgnoreBackFaces; 22 | 23 | /// 24 | /// If convex shapes should be treated as solid. When true, a ray starting inside a convex shape will generate a hit at fraction 0. 25 | /// 26 | public bool TreatConvexAsSolid = true; 27 | 28 | public RayCastSettings() 29 | { 30 | 31 | } 32 | 33 | /// 34 | /// Determines whether the specified is equal to this instance. 35 | /// 36 | /// The to compare with this instance. 37 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 38 | public readonly bool Equals(RayCastSettings other) 39 | { 40 | return 41 | BackFaceModeTriangles == other.BackFaceModeTriangles 42 | && BackFaceModeConvex == other.BackFaceModeConvex 43 | && TreatConvexAsSolid == other.TreatConvexAsSolid; 44 | } 45 | 46 | public static bool operator ==(RayCastSettings left, RayCastSettings right) => left.Equals(right); 47 | public static bool operator !=(RayCastSettings left, RayCastSettings right) => !left.Equals(right); 48 | 49 | /// 50 | public override readonly bool Equals([NotNullWhen(true)] object? obj) => obj is RayCastSettings handle && Equals(handle); 51 | 52 | /// 53 | public override readonly int GetHashCode() => HashCode.Combine(BackFaceModeTriangles, BackFaceModeConvex, TreatConvexAsSolid); 54 | } 55 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/BoxShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public sealed class BoxShapeSettings : ConvexShapeSettings 10 | { 11 | public BoxShapeSettings(in Vector3 halfExent, float convexRadius = Foundation.DefaultConvexRadius) 12 | : base(JPH_BoxShapeSettings_Create(halfExent, convexRadius)) 13 | { 14 | } 15 | 16 | public override Shape Create() => new BoxShape(this); 17 | } 18 | 19 | public sealed class BoxShape : ConvexShape 20 | { 21 | public BoxShape(in Vector3 halfExent, float convexRadius = Foundation.DefaultConvexRadius) 22 | : base(JPH_BoxShape_Create(halfExent, convexRadius)) 23 | { 24 | } 25 | 26 | public BoxShape(BoxShapeSettings settings) 27 | : base(JPH_BoxShapeSettings_CreateShape(settings.Handle)) 28 | { 29 | } 30 | 31 | public Vector3 HalfExtent 32 | { 33 | get 34 | { 35 | JPH_BoxShape_GetHalfExtent(Handle, out Vector3 value); 36 | return value; 37 | } 38 | } 39 | 40 | public void GetHalfExtent(out Vector3 halfExtent) => JPH_BoxShape_GetHalfExtent(Handle, out halfExtent); 41 | 42 | public float ConvexRadius => JPH_BoxShape_GetConvexRadius(Handle); 43 | } 44 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/CapsuleShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public sealed class CapsuleShapeSettings : ConvexShapeSettings 10 | { 11 | public unsafe CapsuleShapeSettings(float halfHeightOfCylinder, float radius) 12 | : base(JPH_CapsuleShapeSettings_Create(halfHeightOfCylinder, radius)) 13 | { 14 | } 15 | 16 | public override Shape Create() => new CapsuleShape(this); 17 | } 18 | 19 | public sealed class CapsuleShape : ConvexShape 20 | { 21 | public CapsuleShape(float halfHeightOfCylinder, float radius) 22 | : base(JPH_CapsuleShape_Create(halfHeightOfCylinder, radius)) 23 | { 24 | } 25 | 26 | public CapsuleShape(CapsuleShapeSettings settings) 27 | : base(JPH_CapsuleShapeSettings_CreateShape(settings.Handle)) 28 | { 29 | } 30 | 31 | public float Radius => JPH_CapsuleShape_GetRadius(Handle); 32 | public float HalfHeightOfCylinder => JPH_CapsuleShape_GetHalfHeightOfCylinder(Handle); 33 | } 34 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/CompoundShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public abstract unsafe class CompoundShapeShapeSettings : ShapeSettings 10 | { 11 | protected CompoundShapeShapeSettings(nint handle) 12 | : base(handle) 13 | { 14 | } 15 | 16 | public uint NumSubShapes => JPH_CompoundShape_GetNumSubShapes(Handle); 17 | 18 | public void AddShape(in Vector3 position, in Quaternion rotation, ShapeSettings shapeSettings, uint userData = 0u) 19 | { 20 | fixed (Vector3* positionPtr = &position) 21 | fixed (Quaternion* rotationPtr = &rotation) 22 | { 23 | JPH_CompoundShapeSettings_AddShape(Handle, positionPtr, rotationPtr, shapeSettings.Handle, userData); 24 | } 25 | } 26 | 27 | public void AddShape(in Vector3 position, in Quaternion rotation, Shape shape, uint userData = 0u) 28 | { 29 | fixed (Vector3* positionPtr = &position) 30 | fixed (Quaternion* rotationPtr = &rotation) 31 | { 32 | JPH_CompoundShapeSettings_AddShape2(Handle, positionPtr, rotationPtr, shape.Handle, userData); 33 | } 34 | } 35 | } 36 | 37 | public abstract class CompoundShape : Shape 38 | { 39 | internal CompoundShape(nint handle) 40 | : base(handle) 41 | { 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/ConvexHullShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using System.Runtime.CompilerServices; 6 | using static JoltPhysicsSharp.JoltApi; 7 | 8 | namespace JoltPhysicsSharp; 9 | 10 | public sealed unsafe class ConvexHullShapeSettings : ConvexShapeSettings 11 | { 12 | public ConvexHullShapeSettings(Vector3* points, int pointsCount, float maxConvexRadius = Foundation.DefaultConvexRadius) 13 | : base(JPH_ConvexHullShapeSettings_Create(points, pointsCount, maxConvexRadius)) 14 | { 15 | } 16 | 17 | public ConvexHullShapeSettings(Vector3[] points, float maxConvexRadius = Foundation.DefaultConvexRadius) 18 | { 19 | fixed (Vector3* pointsPtr = points) 20 | { 21 | Handle = JPH_ConvexHullShapeSettings_Create(pointsPtr, points.Length, maxConvexRadius); 22 | } 23 | } 24 | 25 | public ConvexHullShapeSettings(ReadOnlySpan points, float maxConvexRadius = Foundation.DefaultConvexRadius) 26 | { 27 | fixed (Vector3* pointsPtr = points) 28 | { 29 | Handle = JPH_ConvexHullShapeSettings_Create(pointsPtr, points.Length, maxConvexRadius); 30 | } 31 | } 32 | 33 | public override Shape Create() => new ConvexHullShape(this); 34 | } 35 | 36 | public unsafe class ConvexHullShape : ConvexShape 37 | { 38 | public ConvexHullShape(ConvexHullShapeSettings settings) 39 | : base(JPH_ConvexHullShapeSettings_CreateShape(settings.Handle)) 40 | { 41 | } 42 | 43 | public uint GetNumPoints() 44 | { 45 | return JPH_ConvexHullShape_GetNumPoints(Handle); 46 | } 47 | 48 | public Vector3 GetPoint(uint index) 49 | { 50 | Vector3 result; 51 | JPH_ConvexHullShape_GetPoint(Handle, index, &result); 52 | return result; 53 | } 54 | 55 | public void GetPoint(uint index, out Vector3 result) 56 | { 57 | Unsafe.SkipInit(out result); 58 | 59 | fixed (Vector3* resultPtr = &result) 60 | JPH_ConvexHullShape_GetPoint(Handle, index, resultPtr); 61 | } 62 | 63 | public uint GetNumFaces() 64 | { 65 | return JPH_ConvexHullShape_GetNumFaces(Handle); 66 | } 67 | 68 | public uint GetNumVerticesInFace(uint faceIndex) 69 | { 70 | return JPH_ConvexHullShape_GetNumVerticesInFace(Handle, faceIndex); 71 | } 72 | 73 | /// 74 | /// Get the vertices indices of a face 75 | /// 76 | /// Index of the face. 77 | /// Maximum number of vertices to return. 78 | /// 79 | /// Array of vertices indices, must be at least maxVertices in size, the vertices are returned in counter clockwise order and the positions can be obtained using . 80 | /// 81 | /// 82 | /// Number of vertices in face, if this is bigger than inMaxVertices, not all vertices were retrieved. 83 | /// 84 | public uint GetFaceVertices(uint faceIndex, uint maxVertices, uint* outVertices) 85 | { 86 | return JPH_ConvexHullShape_GetFaceVertices(Handle, faceIndex, maxVertices, outVertices); 87 | } 88 | 89 | public uint GetFaceVertices(uint faceIndex, uint maxVertices, ReadOnlySpan outVertices) 90 | { 91 | fixed (uint* outVerticesPtr = outVertices) 92 | { 93 | return JPH_ConvexHullShape_GetFaceVertices(Handle, faceIndex, maxVertices, outVerticesPtr); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/ConvexShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public abstract class ConvexShapeSettings : ShapeSettings 9 | { 10 | protected ConvexShapeSettings() 11 | { 12 | } 13 | 14 | internal ConvexShapeSettings(nint handle) 15 | : base(handle) 16 | { 17 | } 18 | 19 | public float Density 20 | { 21 | get => JPH_ConvexShapeSettings_GetDensity(Handle); 22 | set => JPH_ConvexShapeSettings_SetDensity(Handle, value); 23 | } 24 | } 25 | 26 | public abstract class ConvexShape : Shape 27 | { 28 | internal ConvexShape(nint handle, bool owns = true) 29 | : base(handle, owns) 30 | { 31 | } 32 | 33 | public float Density 34 | { 35 | get => JPH_ConvexShape_GetDensity(Handle); 36 | set => JPH_ConvexShape_SetDensity(Handle, value); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/CylinderShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed class CylinderShapeSettings : ConvexShapeSettings 9 | { 10 | public unsafe CylinderShapeSettings(float halfHeight, float radius, float convexRadius = Foundation.DefaultConvexRadius) 11 | : base(JPH_CylinderShapeSettings_Create(halfHeight, radius, convexRadius)) 12 | { 13 | } 14 | 15 | public override Shape Create() => new CylinderShape(this); 16 | } 17 | 18 | 19 | public sealed class CylinderShape : ConvexShape 20 | { 21 | public CylinderShape(float halfHeight, float radius) 22 | : base(JPH_CylinderShape_Create(halfHeight, radius)) 23 | { 24 | } 25 | 26 | public CylinderShape(CylinderShapeSettings settings) 27 | : base(JPH_CylinderShapeSettings_CreateShape(settings.Handle)) 28 | { 29 | } 30 | 31 | public float Radius => JPH_CylinderShape_GetRadius(Handle); 32 | public float HalfHeight => JPH_CylinderShape_GetHalfHeight(Handle); 33 | } 34 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/DecoratedShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | namespace JoltPhysicsSharp; 6 | 7 | public abstract class DecoratedShapeSettings : ShapeSettings 8 | { 9 | protected DecoratedShapeSettings() 10 | { 11 | } 12 | 13 | internal DecoratedShapeSettings(nint handle) 14 | : base(handle) 15 | { 16 | } 17 | } 18 | 19 | public abstract class DecoratedShape : Shape 20 | { 21 | protected DecoratedShape() 22 | { 23 | } 24 | 25 | internal DecoratedShape(nint handle) 26 | : base(handle) 27 | { 28 | } 29 | 30 | public nint InnerShape => JPH_DecoratedShape_GetInnerShape(Handle); 31 | } 32 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/EmptyShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | /// 10 | /// Class that constructs an 11 | /// 12 | public class EmptyShapeSettings : ShapeSettings 13 | { 14 | internal EmptyShapeSettings(nint handle) 15 | : base(handle) 16 | { 17 | } 18 | 19 | public EmptyShapeSettings(in Vector3 centerOfMass) 20 | : base(JPH_EmptyShapeSettings_Create(in centerOfMass)) 21 | { 22 | } 23 | 24 | public override Shape Create() => new EmptyShape(this); 25 | } 26 | 27 | /// 28 | /// An empty shape that has no volume and collides with nothing. 29 | /// 30 | /// Possible use cases: 31 | /// - As a placeholder for a shape that will be created later. E.g. if you first need to create a body and only then know what shape it will have. 32 | /// - If you need a kinematic body to attach a constraint to, but you don't want the body to collide with anything. 33 | /// 34 | /// Note that, if possible, you should also put your body in an ObjectLayer that doesn't collide with anything. 35 | /// This ensures that collisions will be filtered out at broad phase level instead of at narrow phase level, this is more efficient. 36 | /// 37 | public class EmptyShape : Shape 38 | { 39 | internal EmptyShape(nint handle) 40 | : base(handle) 41 | { 42 | } 43 | 44 | public EmptyShape(in EmptyShapeSettings settings) 45 | : base(JPH_EmptyShapeSettings_CreateShape(settings.Handle)) 46 | { 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/MeshShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public enum MeshShapeBuildQuality 10 | { 11 | /// 12 | /// Favor runtime performance, takes more time to build the MeshShape but performs better 13 | /// 14 | FavorRuntimePerformance, 15 | /// 16 | /// Favor build speed, build the tree faster but the will be slower 17 | /// 18 | FavorBuildSpeed 19 | } 20 | 21 | public sealed unsafe class MeshShapeSettings : ConvexShapeSettings 22 | { 23 | public MeshShapeSettings(Triangle* triangles, int triangleCount) 24 | : base(JPH_MeshShapeSettings_Create(triangles, triangleCount)) 25 | { 26 | } 27 | 28 | public MeshShapeSettings(Vector3* vertices, int verticesCount, IndexedTriangle* triangles, int triangleCount) 29 | : base(JPH_MeshShapeSettings_Create2(vertices, verticesCount, triangles, triangleCount)) 30 | { 31 | } 32 | 33 | public MeshShapeSettings(Span triangles) 34 | { 35 | fixed (Triangle* trianglePtr = triangles) 36 | { 37 | Handle = JPH_MeshShapeSettings_Create(trianglePtr, triangles.Length); 38 | } 39 | } 40 | 41 | public MeshShapeSettings(Span vertices, Span triangles) 42 | { 43 | fixed (Vector3* verticesPtr = vertices) 44 | fixed (IndexedTriangle* trianglePtr = triangles) 45 | { 46 | Handle = JPH_MeshShapeSettings_Create2(verticesPtr, vertices.Length, trianglePtr, triangles.Length); 47 | } 48 | } 49 | 50 | public uint MaxTrianglesPerLeaf 51 | { 52 | get => JPH_MeshShapeSettings_GetMaxTrianglesPerLeaf(Handle); 53 | set => JPH_MeshShapeSettings_SetMaxTrianglesPerLeaf(Handle, value); 54 | } 55 | 56 | public float ActiveEdgeCosThresholdAngle 57 | { 58 | get => JPH_MeshShapeSettings_GetActiveEdgeCosThresholdAngle(Handle); 59 | set => JPH_MeshShapeSettings_SetActiveEdgeCosThresholdAngle(Handle, value); 60 | } 61 | 62 | public bool PerTriangleUserData 63 | { 64 | get => JPH_MeshShapeSettings_GetPerTriangleUserData(Handle); 65 | set => JPH_MeshShapeSettings_SetPerTriangleUserData(Handle, value); 66 | } 67 | 68 | public MeshShapeBuildQuality BuildQuality 69 | { 70 | get => JPH_MeshShapeSettings_GetBuildQuality(Handle); 71 | set => JPH_MeshShapeSettings_SetBuildQuality(Handle, value); 72 | } 73 | 74 | public override Shape Create() => new MeshShape(this); 75 | 76 | public void Sanitize() => JPH_MeshShapeSettings_Sanitize(Handle); 77 | } 78 | 79 | public sealed class MeshShape : Shape 80 | { 81 | public MeshShape(in MeshShapeSettings settings) 82 | : base(JPH_MeshShapeSettings_CreateShape(settings.Handle)) 83 | { 84 | } 85 | 86 | public uint GetTriangleUserData(uint triangleIndex) => JPH_MeshShape_GetTriangleUserData(Handle, triangleIndex); 87 | } 88 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/MutableCompoundShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public sealed class MutableCompoundShapeSettings : CompoundShapeShapeSettings 10 | { 11 | public MutableCompoundShapeSettings() 12 | : base(JPH_MutableCompoundShapeSettings_Create()) 13 | { 14 | } 15 | 16 | public override Shape Create() => new MutableCompoundShape(this); 17 | } 18 | 19 | public sealed class MutableCompoundShape : CompoundShape 20 | { 21 | public MutableCompoundShape(MutableCompoundShapeSettings settings) 22 | : base(JPH_MutableCompoundShape_Create(settings.Handle)) 23 | { 24 | } 25 | 26 | public uint AddShape(in Vector3 position, in Quaternion rotation, Shape child, uint userData = 0, uint index = uint.MaxValue) 27 | { 28 | return JPH_MutableCompoundShape_AddShape(Handle, in position, in rotation, child.Handle, userData, index); 29 | } 30 | 31 | public void RemoveShape(uint index) 32 | { 33 | JPH_MutableCompoundShape_RemoveShape(Handle, index); 34 | } 35 | 36 | public void ModifyShape(uint index,in Vector3 position, in Quaternion rotation) 37 | { 38 | JPH_MutableCompoundShape_ModifyShape(Handle, index, in position, in rotation); 39 | } 40 | 41 | public void ModifyShape(uint index, in Vector3 position, in Quaternion rotation, Shape newShape) 42 | { 43 | JPH_MutableCompoundShape_ModifyShape2(Handle, index, in position, in rotation, newShape.Handle); 44 | } 45 | 46 | public void AdjustCenterOfMass() 47 | { 48 | JPH_MutableCompoundShape_AdjustCenterOfMass(Handle); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/OffsetCenterOfMassShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public sealed class OffsetCenterOfMassShapeSettings : DecoratedShapeSettings 10 | { 11 | public OffsetCenterOfMassShapeSettings(in Vector3 offset, ShapeSettings shapeSettings) 12 | : base(JPH_OffsetCenterOfMassShapeSettings_Create(in offset, shapeSettings.Handle)) 13 | { 14 | } 15 | 16 | public OffsetCenterOfMassShapeSettings(in Vector3 offset, Shape shape) 17 | : base(JPH_OffsetCenterOfMassShapeSettings_Create2(in offset, shape.Handle)) 18 | { 19 | } 20 | 21 | public override Shape Create() => new OffsetCenterOfMassShape(this); 22 | } 23 | 24 | public sealed class OffsetCenterOfMassShape : ConvexShape 25 | { 26 | public OffsetCenterOfMassShape(in Vector3 offset, Shape shape) 27 | : base(JPH_OffsetCenterOfMassShape_Create(offset, shape.Handle)) 28 | { 29 | } 30 | 31 | public OffsetCenterOfMassShape(OffsetCenterOfMassShapeSettings settings) 32 | : base(JPH_OffsetCenterOfMassShapeSettings_CreateShape(settings.Handle)) 33 | { 34 | } 35 | 36 | public Vector3 Offset 37 | { 38 | get 39 | { 40 | JPH_OffsetCenterOfMassShape_GetOffset(Handle, out Vector3 value); 41 | return value; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/PlaneShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public sealed class PlaneShapeSettings : ShapeSettings 10 | { 11 | public const float DefaultHalfExtent = 1000.0f; 12 | 13 | public PlaneShapeSettings(in Plane plane, PhysicsMaterial? material = default, float halfExtent = DefaultHalfExtent) 14 | : base(JPH_PlaneShapeSettings_Create(in plane, material != null ? material.Handle : IntPtr.Zero, halfExtent)) 15 | { 16 | } 17 | 18 | internal PlaneShapeSettings(nint handle) 19 | : base(handle) 20 | { 21 | } 22 | 23 | public override Shape Create() => new PlaneShape(this); 24 | } 25 | 26 | public sealed class PlaneShape : Shape 27 | { 28 | internal PlaneShape(nint handle) 29 | : base(handle) 30 | { 31 | } 32 | 33 | public PlaneShape(in Plane plane, PhysicsMaterial? material = default, float halfExtent = PlaneShapeSettings.DefaultHalfExtent) 34 | : base(JPH_PlaneShape_Create(in plane, material != null ? material.Handle : IntPtr.Zero, halfExtent)) 35 | { 36 | } 37 | 38 | public PlaneShape(PlaneShapeSettings settings) 39 | : base(JPH_PlaneShapeSettings_CreateShape(settings.Handle)) 40 | { 41 | } 42 | 43 | public Plane Plane 44 | { 45 | get 46 | { 47 | JPH_PlaneShape_GetPlane(Handle, out Plane result); 48 | return result; 49 | } 50 | } 51 | 52 | public float HalfExtent 53 | { 54 | get => JPH_PlaneShape_GetHalfExtent(Handle); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/RotatedTranslatedShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public class RotatedTranslatedShapeSettings : DecoratedShapeSettings 10 | { 11 | public RotatedTranslatedShapeSettings(in Vector3 position, in Quaternion rotation, ShapeSettings shapeSettings) 12 | { 13 | Handle = JPH_RotatedTranslatedShapeSettings_Create(in position, in rotation, shapeSettings.Handle); 14 | } 15 | 16 | public RotatedTranslatedShapeSettings(in Vector3 position, in Quaternion rotation, Shape shape) 17 | { 18 | Handle = JPH_RotatedTranslatedShapeSettings_Create2(in position, in rotation, shape.Handle); 19 | } 20 | 21 | public Vector3 Position 22 | { 23 | get 24 | { 25 | JPH_RotatedTranslatedShape_GetPosition(Handle, out Vector3 position); 26 | return position; 27 | } 28 | } 29 | 30 | public Quaternion Rotation 31 | { 32 | get 33 | { 34 | JPH_RotatedTranslatedShape_GetRotation(Handle, out Quaternion rotation); 35 | return rotation; 36 | } 37 | } 38 | 39 | public override Shape Create() => new RotatedTranslatedShape(this); 40 | } 41 | 42 | public class RotatedTranslatedShape : DecoratedShape 43 | { 44 | public RotatedTranslatedShape(in Vector3 position, in Quaternion rotation, Shape shape) 45 | { 46 | Handle = JPH_RotatedTranslatedShape_Create(in position, in rotation, shape.Handle); 47 | } 48 | 49 | public RotatedTranslatedShape(RotatedTranslatedShapeSettings settings) 50 | : base(JPH_RotatedTranslatedShapeSettings_CreateShape(settings.Handle)) 51 | { 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/ScaledShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public class ScaledShapeSettings : DecoratedShapeSettings 10 | { 11 | public ScaledShapeSettings(ShapeSettings shapeSettings, in Vector3 scale) 12 | { 13 | Handle = JPH_ScaledShapeSettings_Create(shapeSettings.Handle, in scale); 14 | } 15 | 16 | public ScaledShapeSettings(Shape shape, in Vector3 scale) 17 | { 18 | Handle = JPH_ScaledShapeSettings_Create2(shape.Handle, in scale); 19 | } 20 | 21 | public Vector3 Scale 22 | { 23 | get 24 | { 25 | JPH_ScaledShape_GetScale(Handle, out Vector3 result); 26 | return result; 27 | } 28 | } 29 | 30 | public override Shape Create() => new ScaledShape(this); 31 | } 32 | 33 | public class ScaledShape : DecoratedShape 34 | { 35 | public ScaledShape(Shape shape, in Vector3 scale) 36 | : base(JPH_ScaledShape_Create(shape.Handle, in scale)) 37 | { 38 | } 39 | 40 | public ScaledShape(ScaledShapeSettings settings) 41 | : base(JPH_ScaledShapeSettings_CreateShape(settings.Handle)) 42 | { 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/SphereShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed class SphereShapeSettings : ConvexShapeSettings 9 | { 10 | public SphereShapeSettings(float radius) 11 | : base(JPH_SphereShapeSettings_Create(radius)) 12 | { 13 | } 14 | 15 | public float Radius 16 | { 17 | get => JPH_SphereShapeSettings_GetRadius(Handle); 18 | set => JPH_SphereShapeSettings_SetRadius(Handle, value); 19 | } 20 | 21 | public override Shape Create() => new SphereShape(this); 22 | } 23 | 24 | public sealed class SphereShape : ConvexShape 25 | { 26 | public SphereShape(float radius) 27 | : base(JPH_SphereShape_Create(radius)) 28 | { 29 | } 30 | 31 | public SphereShape(SphereShapeSettings settings) 32 | : base(JPH_SphereShapeSettings_CreateShape(settings.Handle)) 33 | { 34 | } 35 | 36 | public float Radius => JPH_SphereShape_GetRadius(Handle); 37 | } 38 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/StaticCompoundShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed class StaticCompoundShapeSettings : CompoundShapeShapeSettings 9 | { 10 | public StaticCompoundShapeSettings() 11 | : base(JPH_StaticCompoundShapeSettings_Create()) 12 | { 13 | } 14 | 15 | public override Shape Create() => new StaticCompoundShape(this); 16 | } 17 | 18 | public sealed class StaticCompoundShape : CompoundShape 19 | { 20 | internal StaticCompoundShape(nint handle) 21 | : base(handle) 22 | { 23 | } 24 | 25 | public StaticCompoundShape(StaticCompoundShapeSettings settings) 26 | : base(JPH_StaticCompoundShape_Create(settings.Handle)) 27 | { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/TaperedCapsuleShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public sealed class TaperedCapsuleShapeSettings : ConvexShapeSettings 10 | { 11 | public TaperedCapsuleShapeSettings(float halfHeightOfTaperedCylinder, float topRadius, float bottomRadius) 12 | : base(JPH_TaperedCapsuleShapeSettings_Create(halfHeightOfTaperedCylinder, topRadius, bottomRadius)) 13 | { 14 | } 15 | public override Shape Create() => new TaperedCapsuleShape(this); 16 | } 17 | 18 | public sealed class TaperedCapsuleShape : ConvexShape 19 | { 20 | public TaperedCapsuleShape(TaperedCapsuleShapeSettings settings) 21 | : base(JPH_TaperedCapsuleShapeSettings_CreateShape(settings.Handle)) 22 | { 23 | } 24 | 25 | public float TopRadius => JPH_TaperedCapsuleShape_GetTopRadius(Handle); 26 | public float BottomRadius => JPH_TaperedCapsuleShape_GetBottomRadius(Handle); 27 | public float HalfHeight => JPH_TaperedCapsuleShape_GetHalfHeight(Handle); 28 | } 29 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/TaperedCylinderShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed class TaperedCylinderShapeSettings : ConvexShapeSettings 9 | { 10 | public unsafe TaperedCylinderShapeSettings(float halfHeightOfTaperedCylinder, float topRadius, float bottomRadius, float convexRadius = Foundation.DefaultConvexRadius, PhysicsMaterial? material = default) 11 | : base(JPH_TaperedCylinderShapeSettings_Create(halfHeightOfTaperedCylinder, topRadius, bottomRadius, convexRadius, material != null ? material.Handle : IntPtr.Zero)) 12 | { 13 | } 14 | 15 | public override Shape Create() => new TaperedCylinderShape(this); 16 | } 17 | 18 | 19 | public sealed class TaperedCylinderShape : ConvexShape 20 | { 21 | public TaperedCylinderShape(TaperedCylinderShapeSettings settings) 22 | : base(JPH_TaperedCylinderShapeSettings_CreateShape(settings.Handle)) 23 | { 24 | } 25 | 26 | public float TopRadius => JPH_TaperedCylinderShape_GetTopRadius(Handle); 27 | public float BottomRadius => JPH_TaperedCylinderShape_GetBottomRadius(Handle); 28 | public float ConvexRadius => JPH_TaperedCylinderShape_GetConvexRadius(Handle); 29 | public float HalfHeight => JPH_TaperedCylinderShape_GetHalfHeight(Handle); 30 | } 31 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Shape/TriangleShape.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public sealed class TriangleShapeSettings : ConvexShapeSettings 10 | { 11 | public TriangleShapeSettings(in Vector3 v1, in Vector3 v2, in Vector3 v3, float convexRadius = 0.0f) 12 | : base(JPH_TriangleShapeSettings_Create(v1, v2, v3, convexRadius)) 13 | { 14 | } 15 | 16 | public override Shape Create() => new TriangleShape(this); 17 | } 18 | 19 | public sealed unsafe class TriangleShape : ConvexShape 20 | { 21 | public TriangleShape(in Vector3 v1, in Vector3 v2, in Vector3 v3, float convexRadius = 0.0f) 22 | : base(JPH_TriangleShape_Create(v1, v2, v3, convexRadius)) 23 | { 24 | } 25 | 26 | public TriangleShape(TriangleShapeSettings settings) 27 | : base(JPH_TriangleShapeSettings_CreateShape(settings.Handle)) 28 | { 29 | } 30 | 31 | public float ConvexRadius => JPH_TriangleShape_GetConvexRadius(Handle); 32 | 33 | public Vector3 Vertex1 34 | { 35 | get 36 | { 37 | Vector3 result; 38 | JPH_TriangleShape_GetVertex1(Handle, &result); 39 | return result; 40 | } 41 | } 42 | public Vector3 Vertex2 43 | { 44 | get 45 | { 46 | Vector3 result; 47 | JPH_TriangleShape_GetVertex2(Handle, &result); 48 | return result; 49 | } 50 | } 51 | 52 | public Vector3 Vertex3 53 | { 54 | get 55 | { 56 | Vector3 result; 57 | JPH_TriangleShape_GetVertex3(Handle, &result); 58 | return result; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ShapeCastResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public readonly struct ShapeCastResult 9 | { 10 | public readonly Vector3 ContactPointOn1; 11 | public readonly Vector3 ContactPointOn2; 12 | public readonly Vector3 PenetrationAxis; 13 | public readonly float PenetrationDepth; 14 | public readonly SubShapeID SubShapeID1; 15 | public readonly SubShapeID SubShapeID2; 16 | public readonly BodyID BodyID2; 17 | public readonly float Fraction; 18 | public readonly Bool8 IsBackFaceHit; 19 | } 20 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ShapeColor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Defines how to color soft body constraints 8 | /// 9 | public enum ShapeColor 10 | { 11 | /// 12 | /// Random color per instance 13 | /// 14 | InstanceColor, 15 | /// 16 | /// Convex = green, scaled = yellow, compound = orange, mesh = red 17 | /// 18 | ShapeTypeColor, 19 | /// 20 | /// Static = grey, keyframed = green, dynamic = random color per instance 21 | /// 22 | MotionTypeColor, 23 | /// 24 | /// Static = grey, keyframed = green, dynamic = yellow, sleeping = red 25 | /// 26 | SleepColor, 27 | /// 28 | /// Static = grey, active = random color per island, sleeping = light grey 29 | /// 30 | IslandColor, 31 | /// 32 | /// Color as defined by the PhysicsMaterial of the shape 33 | /// 34 | MaterialColor, 35 | } 36 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ShapeFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Runtime.InteropServices; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public abstract class ShapeFilter : NativeObject 10 | { 11 | private static readonly JPH_ShapeFilter_Procs _procs; 12 | private readonly nint _listenerUserData; 13 | 14 | static unsafe ShapeFilter() 15 | { 16 | _procs = new JPH_ShapeFilter_Procs 17 | { 18 | ShouldCollide = &ShouldCollideCallback, 19 | ShouldCollide2 = &ShouldCollide2Callback, 20 | }; 21 | JPH_ShapeFilter_SetProcs(in _procs); 22 | } 23 | 24 | public unsafe ShapeFilter() 25 | { 26 | _listenerUserData = DelegateProxies.CreateUserData(this, true); 27 | Handle = JPH_ShapeFilter_Create(_listenerUserData); 28 | } 29 | 30 | public BodyID BodyID2 31 | { 32 | get => JPH_ShapeFilter_GetBodyID2(Handle); 33 | set => JPH_ShapeFilter_SetBodyID2(Handle, value); 34 | } 35 | 36 | protected override void DisposeNative() 37 | { 38 | DelegateProxies.GetUserData(_listenerUserData, out GCHandle gch); 39 | JPH_ShapeFilter_Destroy(Handle); 40 | gch.Free(); 41 | } 42 | 43 | protected virtual bool ShouldCollide(Shape shape2, in SubShapeID subShapeIDOfShape2) 44 | { 45 | return true; 46 | } 47 | 48 | protected virtual bool ShouldCollide(Shape shape1, in SubShapeID subShapeIDOfShape1, Shape shape2, in SubShapeID subShapeIDOfShape2) 49 | { 50 | return true; 51 | } 52 | 53 | [UnmanagedCallersOnly] 54 | private static unsafe Bool8 ShouldCollideCallback(nint context, nint shape2, SubShapeID* subShapeIDOfShape2) 55 | { 56 | // TODO: Add cache for Shape 57 | ShapeFilter listener = DelegateProxies.GetUserData(context, out _); 58 | return listener.ShouldCollide(Shape.GetObject(shape2)!, *subShapeIDOfShape2); 59 | } 60 | 61 | [UnmanagedCallersOnly] 62 | private static unsafe Bool8 ShouldCollide2Callback(nint context, nint shape1, SubShapeID* subShapeIDOfShape1, nint shape2, SubShapeID* subShapeIDOfShape2) 63 | { 64 | // TODO: Add cache for Shape 65 | ShapeFilter listener = DelegateProxies.GetUserData(context, out _); 66 | return listener.ShouldCollide(Shape.GetObject(shape1)!, *subShapeIDOfShape1, Shape.GetObject(shape2)!, *subShapeIDOfShape2); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ShapeSubType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// This enumerates all shape types, each shape can return its type through 8 | /// 9 | public enum ShapeSubType 10 | { 11 | // Convex shapes 12 | Sphere, 13 | Box, 14 | Triangle, 15 | Capsule, 16 | TaperedCapsule, 17 | Cylinder, 18 | ConvexHull, 19 | 20 | // Compound shapes 21 | StaticCompound, 22 | MutableCompound, 23 | 24 | // Decorated shapes 25 | RotatedTranslated, 26 | Scaled, 27 | OffsetCenterOfMass, 28 | 29 | // Other shapes 30 | Mesh, 31 | HeightField, 32 | SoftBody, 33 | 34 | // User defined shapes 35 | User1, 36 | User2, 37 | User3, 38 | User4, 39 | User5, 40 | User6, 41 | User7, 42 | User8, 43 | 44 | // User defined convex shapes 45 | UserConvex1, 46 | UserConvex2, 47 | UserConvex3, 48 | UserConvex4, 49 | UserConvex5, 50 | UserConvex6, 51 | UserConvex7, 52 | UserConvex8, 53 | } 54 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ShapeType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Shapes are categorized in groups, each shape can return which group it belongs to through its function. 8 | /// 9 | public enum ShapeType 10 | { 11 | /// 12 | /// Used by , all shapes that use the generic convex vs convex collision detection system (box, sphere, capsule, tapered capsule, cylinder, triangle) 13 | /// 14 | Convex, 15 | /// 16 | /// Used by 17 | /// 18 | Compound, 19 | /// 20 | /// Used by 21 | /// 22 | Decorated, 23 | /// 24 | /// Used by 25 | /// 26 | Mesh, 27 | /// 28 | /// Used by 29 | /// 30 | HeightField, 31 | /// 32 | /// Used by 33 | /// 34 | SoftBody, 35 | 36 | /// 37 | /// User defined shape 1 38 | /// 39 | User1, 40 | /// 41 | /// User defined shape 2 42 | /// 43 | User2, 44 | /// 45 | /// User defined shape 3 46 | /// 47 | User3, 48 | /// 49 | /// User defined shape 4 50 | /// 51 | User4, 52 | } 53 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/SimShapeFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Runtime.InteropServices; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public abstract class SimShapeFilter : NativeObject 10 | { 11 | private static readonly JPH_SimShapeFilter_Procs _procs; 12 | private readonly nint _listenerUserData; 13 | 14 | static unsafe SimShapeFilter() 15 | { 16 | _procs = new JPH_SimShapeFilter_Procs 17 | { 18 | ShouldCollide = &ShouldCollideCallback 19 | }; 20 | JPH_SimShapeFilter_SetProcs(in _procs); 21 | } 22 | 23 | public SimShapeFilter() 24 | { 25 | _listenerUserData = DelegateProxies.CreateUserData(this, true); 26 | Handle = JPH_SimShapeFilter_Create(_listenerUserData); 27 | } 28 | 29 | protected override void DisposeNative() 30 | { 31 | DelegateProxies.GetUserData(_listenerUserData, out GCHandle gch); 32 | JPH_SimShapeFilter_Destroy(Handle); 33 | gch.Free(); 34 | } 35 | 36 | protected virtual bool ShouldCollide( 37 | Body body1, Shape shape1, in SubShapeID subShapeIDOfShape1, 38 | Body inBody2, Shape shape2, in SubShapeID subShapeIDOfShape2) 39 | { 40 | return true; 41 | } 42 | 43 | [UnmanagedCallersOnly] 44 | private static unsafe Bool8 ShouldCollideCallback(nint context, 45 | nint body1, nint shape1, SubShapeID* subShapeIDOfShape1, 46 | nint body2, nint shape2, SubShapeID* subShapeIDOfShape2) 47 | { 48 | SimShapeFilter listener = DelegateProxies.GetUserData(context, out _); 49 | return listener.ShouldCollide( 50 | Body.GetObject(body1)!, Shape.GetObject(shape1)!, *subShapeIDOfShape1, 51 | Body.GetObject(body2)!, Shape.GetObject(shape2)!, *subShapeIDOfShape2); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Skeleton.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using static JoltPhysicsSharp.JoltApi; 6 | 7 | namespace JoltPhysicsSharp; 8 | 9 | public class Skeleton : NativeObject 10 | { 11 | public struct Joint 12 | { 13 | public string Name; 14 | public string? ParentName; 15 | public int ParentJointIndex; 16 | } 17 | 18 | internal Skeleton(nint handle, bool owns = true) 19 | : base(handle, owns) 20 | { 21 | } 22 | 23 | public Skeleton() 24 | : base(JPH_Skeleton_Create()) 25 | { 26 | } 27 | 28 | protected override void DisposeNative() 29 | { 30 | JPH_Skeleton_Destroy(Handle); 31 | } 32 | 33 | public int JointCount => JPH_Skeleton_GetJointCount(Handle); 34 | 35 | public uint AddJoint(string name) => JPH_Skeleton_AddJoint(Handle, name); 36 | public uint AddJoint(string name, int parentIndex) => JPH_Skeleton_AddJoint2(Handle, name, parentIndex); 37 | public uint AddJoint(string name, string parentName) => JPH_Skeleton_AddJoint3(Handle, name, parentName); 38 | 39 | public unsafe Joint GetJoint(int index) 40 | { 41 | JPH_Skeleton_GetJoint(Handle, index, out SkeletonJoint nativeJoint); 42 | return new Joint 43 | { 44 | Name = ConvertToManaged(nativeJoint.name)!, 45 | ParentName = ConvertToManaged(nativeJoint.parentName), 46 | ParentJointIndex = nativeJoint.parentJointIndex 47 | }; 48 | } 49 | 50 | public unsafe void GetJoint(int index, out Joint joint) 51 | { 52 | JPH_Skeleton_GetJoint(Handle, index, out SkeletonJoint nativeJoint); 53 | joint = new() 54 | { 55 | Name = ConvertToManaged(nativeJoint.name)!, 56 | ParentName = ConvertToManaged(nativeJoint.parentName), 57 | ParentJointIndex = nativeJoint.parentJointIndex 58 | }; 59 | } 60 | 61 | public int GetJointIndex(string name) => JPH_Skeleton_GetJointIndex(Handle, name); 62 | 63 | public void CalculateParentJointIndices() => JPH_Skeleton_CalculateParentJointIndices(Handle); 64 | public bool AreJointsCorrectlyOrdered() => JPH_Skeleton_AreJointsCorrectlyOrdered(Handle); 65 | 66 | internal static Skeleton? GetObject(nint handle) => GetOrAddObject(handle, (nint h) => new Skeleton(h, false)); 67 | } 68 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/SoftBodyConstraintColor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Defines how to color soft body constraints 8 | /// 9 | public enum SoftBodyConstraintColor 10 | { 11 | /// 12 | /// Draw different types of constraints in different colors 13 | /// 14 | ConstraintType, 15 | /// 16 | /// Draw constraints in the same group in the same color, non-parallel group will be red 17 | /// 18 | ConstraintGroup, 19 | /// 20 | /// Draw constraints in the same group in the same color, non-parallel group will be red, and order within each group will be indicated with gradient 21 | /// 22 | ConstraintOrder, 23 | } 24 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/SoftBodyCreationSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using static JoltPhysicsSharp.JoltApi; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public sealed class SoftBodyCreationSettings : NativeObject 9 | { 10 | public SoftBodyCreationSettings() 11 | : base(JPH_SoftBodyCreationSettings_Create()) 12 | { 13 | } 14 | 15 | protected override void DisposeNative() 16 | { 17 | JPH_SoftBodyCreationSettings_Destroy(Handle); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/SpringMode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | /// 7 | /// Enum used by constraints to specify how the spring is defined 8 | /// 9 | public enum SpringMode 10 | { 11 | /// 12 | /// Frequency and damping are specified 13 | /// 14 | FrequencyAndDamping, 15 | /// 16 | /// Stiffness and damping are specified 17 | /// 18 | StiffnessAndDamping 19 | } 20 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/SpringSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public record struct SpringSettings 7 | { 8 | public SpringSettings(SpringMode mode, float frequencyOrStiffness, float damping) 9 | { 10 | Mode = mode; 11 | FrequencyOrStiffness = frequencyOrStiffness; 12 | Damping = damping; 13 | } 14 | 15 | public SpringMode Mode; 16 | public float FrequencyOrStiffness; 17 | public float Damping; 18 | } 19 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/SubShapeID.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public readonly partial struct SubShapeID(uint value) : IComparable, IComparable, IEquatable, IFormattable 7 | { 8 | public readonly uint Value = value; 9 | 10 | public static bool operator ==(SubShapeID left, SubShapeID right) => left.Value == right.Value; 11 | 12 | public static bool operator !=(SubShapeID left, SubShapeID right) => left.Value != right.Value; 13 | 14 | public static bool operator <(SubShapeID left, SubShapeID right) => left.Value < right.Value; 15 | 16 | public static bool operator <=(SubShapeID left, SubShapeID right) => left.Value <= right.Value; 17 | 18 | public static bool operator >(SubShapeID left, SubShapeID right) => left.Value > right.Value; 19 | 20 | public static bool operator >=(SubShapeID left, SubShapeID right) => left.Value >= right.Value; 21 | 22 | 23 | public static implicit operator SubShapeID(uint value) => new (value); 24 | 25 | public static explicit operator uint(SubShapeID value) => value.Value; 26 | 27 | public int CompareTo(object? obj) 28 | { 29 | if (obj is SubShapeID other) 30 | { 31 | return CompareTo(other); 32 | } 33 | 34 | return (obj is null) ? 1 : throw new ArgumentException("obj is not an instance of SubShapeID."); 35 | } 36 | 37 | public int CompareTo(SubShapeID other) => Value.CompareTo(other.Value); 38 | 39 | public override bool Equals(object? obj) => (obj is SubShapeID other) && Equals(other); 40 | 41 | public bool Equals(SubShapeID other) => Value.Equals(other.Value); 42 | 43 | public override int GetHashCode() => Value.GetHashCode(); 44 | 45 | public override string ToString() => Value.ToString(); 46 | 47 | public string ToString(string? format, IFormatProvider? formatProvider) => Value.ToString(format, formatProvider); 48 | } 49 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/SubShapeIDPair.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public readonly struct SubShapeIDPair 7 | { 8 | public readonly BodyID Body1ID; 9 | public readonly uint SubShapeID1; 10 | public readonly BodyID Body2ID; 11 | public readonly uint SubShapeID2; 12 | } 13 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/SwingType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public enum SwingType 7 | { 8 | Cone, 9 | Pyramid, 10 | } 11 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/Triangle.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | 6 | namespace JoltPhysicsSharp; 7 | 8 | public readonly struct Triangle : IEquatable 9 | { 10 | public Triangle(in Vector3 v1, in Vector3 v2, in Vector3 v3, uint materialIndex = 0) 11 | { 12 | V1 = v1; 13 | V2 = v2; 14 | V3 = v3; 15 | MaterialIndex = materialIndex; 16 | } 17 | 18 | public Vector3 V1 { get; } 19 | public Vector3 V2 { get; } 20 | public Vector3 V3 { get; } 21 | public uint MaterialIndex { get; } 22 | 23 | public static bool operator ==(Triangle left, Triangle right) 24 | { 25 | return left.V1 == right.V1 && left.V2 == right.V2 && left.V3 == right.V3 && left.MaterialIndex == right.MaterialIndex; 26 | } 27 | 28 | public static bool operator !=(Triangle left, Triangle right) 29 | { 30 | return left.V1 != right.V1 || left.V2 != right.V2 || left.V3 != right.V3 || left.MaterialIndex != right.MaterialIndex; 31 | } 32 | 33 | public bool Equals(Triangle other) => this == other; 34 | 35 | /// 36 | public override bool Equals(object? obj) => obj is Triangle handle && Equals(handle); 37 | 38 | /// 39 | public override int GetHashCode() => HashCode.Combine(V1, V2, V3, MaterialIndex); 40 | 41 | public override string ToString() => $"V1: {V1}, V2: {V2}, V3: {V3}, MaterialIndex: {MaterialIndex}"; 42 | } 43 | -------------------------------------------------------------------------------- /src/JoltPhysicsSharp/ValidateResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace JoltPhysicsSharp; 5 | 6 | public enum ValidateResult 7 | { 8 | /// 9 | /// Accept this and any further contact points for this body pair 10 | /// 11 | AcceptAllContactsForThisBodyPair, 12 | /// 13 | /// Accept this contact only (and continue calling this callback for every contact manifold for the same body pair) 14 | /// 15 | AcceptContact, 16 | /// 17 | /// Reject this contact only (but process any other contact manifolds for the same body pair) 18 | /// 19 | RejectContact, 20 | /// 21 | /// Rejects this and any further contact points for this body pair 22 | /// 23 | RejectAllContactsForThisBodyPair 24 | } 25 | -------------------------------------------------------------------------------- /tests/BaseTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics; 5 | using System.Numerics; 6 | using NUnit.Framework; 7 | 8 | namespace JoltPhysicsSharp.Tests; 9 | 10 | public abstract class BaseTest : IDisposable 11 | { 12 | protected BaseTest() 13 | { 14 | if (!Foundation.Init(true)) 15 | { 16 | return; 17 | } 18 | 19 | Foundation.SetTraceHandler((message) => 20 | { 21 | Console.WriteLine(message); 22 | }); 23 | 24 | #if DEBUG 25 | Foundation.SetAssertFailureHandler((inExpression, inMessage, inFile, inLine) => 26 | { 27 | string message = inMessage ?? inExpression; 28 | 29 | string outMessage = $"[JoltPhysics] Assertion failure at {inFile}:{inLine}: {message}"; 30 | 31 | Debug.WriteLine(outMessage); 32 | 33 | throw new Exception(outMessage); 34 | }); 35 | #endif 36 | } 37 | 38 | public void Dispose() 39 | { 40 | Foundation.Shutdown(); 41 | } 42 | 43 | protected static void CHECK_APPROX_EQUAL(float inLHS, float inRHS, float inTolerance = 1.0e-6f) 44 | { 45 | Assert.That(MathF.Abs(inRHS - inLHS) <= inTolerance, Is.True); 46 | } 47 | 48 | private static void CHECK_APPROX_EQUAL(in Vector3 inLHS, in Vector3 inRHS, float inTolerance = 1.0e-6f) 49 | { 50 | Assert.That(IsClose(inLHS, inRHS, inTolerance * inTolerance), Is.True); 51 | } 52 | 53 | private static bool IsClose(in Vector3 inV1, in Vector3 inV2, float inMaxDistSq = 1.0e-12f) 54 | { 55 | return (inV2 - inV1).LengthSquared() <= inMaxDistSq; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/ConstraintsTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | 7 | namespace JoltPhysicsSharp.Tests; 8 | 9 | [TestFixture(TestOf = typeof(Constraint))] 10 | public class ConstraintsTests : BaseTest 11 | { 12 | [Test] 13 | public static void TestHingeConstraintSettings() 14 | { 15 | HingeConstraintSettings settings = new(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/JoltColorTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | 7 | namespace JoltPhysicsSharp.Tests; 8 | 9 | [TestFixture(TestOf = typeof(JoltColor))] 10 | public class JoltColorTests 11 | { 12 | [Test] 13 | public static unsafe void DefaultsTest() 14 | { 15 | Assert.That(() => sizeof(JoltColor), Is.EqualTo(4)); 16 | 17 | var color = new JoltColor(255, 0, 255, 127); 18 | 19 | Assert.That(color.R, Is.EqualTo(255)); 20 | Assert.That(color.G, Is.EqualTo(0)); 21 | Assert.That(color.B, Is.EqualTo(255)); 22 | Assert.That(color.A, Is.EqualTo(127)); 23 | Assert.That(color.PackedValue, Is.EqualTo(2147418367)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/JoltPhysicsSharp.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0;net8.0 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/ShapeTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | 7 | namespace JoltPhysicsSharp.Tests; 8 | 9 | [TestFixture(TestOf = typeof(Shape))] 10 | public class ShapeTests : BaseTest 11 | { 12 | [Test] 13 | public static void TestConvexHullShape() 14 | { 15 | const float cDensity = 1.5f; 16 | 17 | // Create convex hull shape of a box 18 | ReadOnlySpan box = [ 19 | new(5, 6, 7), 20 | new(5, 6, 14), 21 | new(5, 12, 7), 22 | new(5, 12, 14), 23 | new(10, 6, 7), 24 | new(10, 6, 14), 25 | new(10, 12, 7), 26 | new(10, 12, 14) 27 | ]; 28 | 29 | ConvexHullShapeSettings settings = new(box); 30 | settings.Density = cDensity; 31 | 32 | using ConvexHullShape shape = new(settings); 33 | 34 | //RefConst shape = settings.Create().Get(); 35 | 36 | // Validate calculated center of mass 37 | //Vec3 com = shape->GetCenterOfMass(); 38 | //CHECK_APPROX_EQUAL(Vec3(7.5f, 9.0f, 10.5f), com, 1.0e-5f); 39 | 40 | // Calculate reference value of mass and inertia of a box 41 | //MassProperties reference; 42 | //reference.SetMassAndInertiaOfSolidBox(Vec3(5, 6, 7), cDensity); 43 | 44 | // Mass is easy to calculate, double check if SetMassAndInertiaOfSolidBox calculated it correctly 45 | //CHECK_APPROX_EQUAL(5.0f * 6.0f * 7.0f * cDensity, reference.mMass, 1.0e-6f); 46 | } 47 | } 48 | --------------------------------------------------------------------------------