├── UnityNativeCollision ├── ProjectSettings │ ├── ProjectVersion.txt │ ├── ClusterInputManager.asset │ ├── PresetManager.asset │ ├── XRSettings.asset │ ├── TimeManager.asset │ ├── EditorBuildSettings.asset │ ├── VFXManager.asset │ ├── AudioManager.asset │ ├── TagManager.asset │ ├── EditorSettings.asset │ ├── UnityConnectSettings.asset │ ├── DynamicsManager.asset │ ├── NavMeshAreas.asset │ ├── Physics2DSettings.asset │ ├── GraphicsSettings.asset │ ├── InputManager.asset │ ├── QualitySettings.asset │ └── ProBuilderSettings.json ├── Assets │ ├── Scenes.meta │ ├── Scenes │ │ └── CollisionTest.unity.meta │ ├── Plugins.meta │ ├── Plugins │ │ ├── Vella.Common.meta │ │ ├── Vella.Common │ │ │ ├── Vella.Common.asmdef.meta │ │ │ ├── BoundingBox.cs.meta │ │ │ ├── BurstAction.cs.meta │ │ │ ├── DebugDrawer.cs.meta │ │ │ ├── MathUtility.cs.meta │ │ │ ├── NativeBuffer.cs.meta │ │ │ ├── UnityColors.cs.meta │ │ │ ├── BoundingSphere.cs.meta │ │ │ ├── BurstFunction.cs.meta │ │ │ ├── NativeArray2D.cs.meta │ │ │ ├── NativePairBuffer.cs.meta │ │ │ ├── StructConversion.cs.meta │ │ │ ├── NativeArrayExtensions.cs.meta │ │ │ ├── NativeArrayNoLeakDetection.cs.meta │ │ │ ├── NativeBoundingHierarchy.cs.meta │ │ │ ├── Vella.Common.asmdef │ │ │ ├── NativeArrayExtensions.cs │ │ │ ├── NativeArray2D.cs │ │ │ ├── StructConversion.cs │ │ │ ├── BoundingSphere.cs │ │ │ ├── MathUtility.cs │ │ │ ├── NativePairBuffer.cs │ │ │ ├── BoundingBox.cs │ │ │ ├── BurstFunction.cs │ │ │ ├── BurstAction.cs │ │ │ ├── UnityColors.cs │ │ │ └── NativeArrayNoLeakDetection.cs │ │ ├── Vella.UnityNativeHull.meta │ │ └── Vella.UnityNativeHull │ │ │ ├── Tests.meta │ │ │ ├── Runtime.meta │ │ │ ├── Runtime │ │ │ ├── Vella.UnityNativeHull.asmdef.meta │ │ │ ├── NativeFace.cs.meta │ │ │ ├── NativeHull.cs.meta │ │ │ ├── HullCollision.cs.meta │ │ │ ├── HullFactory.cs.meta │ │ │ ├── HullIterators.cs.meta │ │ │ ├── HullOperations.cs.meta │ │ │ ├── HullValidation.cs.meta │ │ │ ├── NativeHalfEdge.cs.meta │ │ │ ├── NativeManifold.cs.meta │ │ │ ├── NativePlane.cs.meta │ │ │ ├── HullDrawingUtility.cs.meta │ │ │ ├── HullIntersection.cs.meta │ │ │ ├── NativeFace.cs │ │ │ ├── Vella.UnityNativeHull.asmdef │ │ │ ├── NativeHalfEdge.cs │ │ │ ├── HullIterators.cs │ │ │ ├── NativeManifold.cs │ │ │ ├── NativePlane.cs │ │ │ ├── HullValidation.cs │ │ │ ├── HullOperations.cs │ │ │ ├── NativeHull.cs │ │ │ ├── HullDrawingUtility.cs │ │ │ └── HullCollision.cs │ │ │ └── Tests │ │ │ ├── Vella.UnityNativeHull.Tests.asmdef.meta │ │ │ ├── BoxCollision.cs.meta │ │ │ ├── BoxCreation.cs.meta │ │ │ ├── Vella.UnityNativeHull.Tests.asmdef │ │ │ ├── BoxCreation.cs │ │ │ └── BoxCollision.cs │ ├── Translucent.mat.meta │ ├── BvhTestShape.cs.meta │ ├── BvhTester.cs.meta │ ├── HullTester.cs.meta │ ├── BvhTestShape.cs │ ├── Translucent.mat │ ├── BvhTester.cs │ └── HullTester.cs └── Packages │ └── manifest.json ├── .gitignore ├── LICENSE.md └── README.md /UnityNativeCollision/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2019.2.0a4 2 | m_EditorVersionWithRevision: 2019.2.0a4 (2403bdbdd88b) 3 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | m_DefaultList: [] 7 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e0532b7b012e1ec40ba5a82db1f96a98 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Scenes/CollisionTest.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9fc0d4010bbf28b4594072e72b8655ab 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6799766ccfd75c246b32b4aa1cb8c20c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02b275ea697e41d4aad6c3a5dc694bb9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/XRSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_SettingKeys": [ 3 | "VR Device Disabled", 4 | "VR Device User Alert" 5 | ], 6 | "m_SettingValues": [ 7 | "False", 8 | "False" 9 | ] 10 | } -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/Vella.Common.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b46976b8a773ae341bbd9ca990e20dfb 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c2249fd4b18bd204b86733eb699b23ec 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Translucent.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 16a27840c93e014469e411fb0e09a128 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 16002973bdc12934c898e367510c5c37 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 63f1bf3263d33ab498b066fe6a280f64 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/Vella.UnityNativeHull.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 56d587dec131a3d49b5ef08d8a57d219 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Tests/Vella.UnityNativeHull.Tests.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 20d27cc10906343478c2aa3abf797ef9 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/BvhTestShape.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8f0c82db246ae2c43b03fbe8dd4e952b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/BvhTester.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee89d433be7389c479d0029b60a3d9e7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/HullTester.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fe5597794b86a8445bff420f6db6c851 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/BoundingBox.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 48c9fe9405770b7418dc5160701ff736 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/BurstAction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a02677d648e7c594895f5a9fc25ce084 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/DebugDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 659c6160648b73545a0992555306a1b7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/MathUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4118bdaae46e8f5458b9714dccdebda0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/NativeBuffer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d6bf3dbadb83304b80a369e9c726341 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/UnityColors.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: facf6e46f9ee5f14c943e3c3046f5733 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/BoundingSphere.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f22db29f76f6e314788e5e2b5771ff0b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/BurstFunction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: af3587edc96ce1d48a83ef6814345dce 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/NativeArray2D.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4bf78c8dff15bdd468d827ef118577bb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/NativePairBuffer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 224529405c1173941bae9275f6c7cd8a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/StructConversion.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4ff74b40a7375f24da4f50bc1c9caf12 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/NativeArrayExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad47e8fa6f7b2a84ebd09b9c82a7495c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/Scenes/CollisionTest.unity 10 | guid: 9fc0d4010bbf28b4594072e72b8655ab 11 | m_configObjects: {} 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/NativeArrayNoLeakDetection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c5a743100627c144fbea9da557cfaa9a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/NativeBoundingHierarchy.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4825092555b85fc44a9efa310f030442 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/NativeFace.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7135ca1799f1aa64b92237149a186e61 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/NativeHull.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f1df3aee7fdd4cf44ab1c4566fa43100 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Tests/BoxCollision.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4c25947ae9ab1a4ab75d78dc822e30b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Tests/BoxCreation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9f2fffb05783ea445b6e0744eb76e530 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_CopyBufferShader: {fileID: 0} 8 | m_SortShader: {fileID: 0} 9 | m_RenderPipeSettingsPath: 10 | m_FixedTimeStep: 0.016666668 11 | m_MaxDeltaTime: 0.05 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullCollision.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0a2788ad000347e4cad1345fa4d50ac0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 82733f1583d0b6441a908b05f3668064 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullIterators.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9a7c8423ee3f6114d9d07680fd5c24c8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullOperations.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2e05134574f342142a8fc0bc53167aeb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullValidation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c82adf53cad9eaa4590d7e57a513e565 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/NativeHalfEdge.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ffe134f01be328e4b91bfcc2a2f16554 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/NativeManifold.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a8a0b7ee08aa7a943b2e671d78cc77e5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/NativePlane.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2bb5c920785a5d44a781a13fc93d973 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullDrawingUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae73ccd9bb732574db254b8db6da3a86 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullIntersection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ecac3df2f6beb3442b20ab6e3ab127a3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/NativeFace.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Unity.Mathematics; 3 | 4 | namespace Vella.UnityNativeHull 5 | { 6 | [DebuggerDisplay("NativeFace: Edge={Edge}")] 7 | public struct NativeFace 8 | { 9 | /// 10 | /// Index of the starting edge on this face. 11 | /// 12 | public int Edge; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 1024 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_AmbisonicDecoderPlugin: 16 | m_DisableAudio: 0 17 | m_VirtualizeEffects: 1 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | UnityNativeCollision/[Ll]ibrary/ 2 | UnityNativeCollision/[Tt]emp/ 3 | UnityNativeCollision/[Oo]bj/ 4 | UnityNativeCollision/[Bb]uild/ 5 | UnityNativeCollision/.vs/ 6 | 7 | # Autogenerated VS/MD solution and project files 8 | *.csproj 9 | *.unityproj 10 | *.sln 11 | *.suo 12 | *.tmp 13 | *.user 14 | *.userprefs 15 | *.pidb 16 | *.booproj 17 | 18 | # Unity3D generated meta files 19 | *.pidb.meta 20 | 21 | # Unity3D Generated File On Crash Reports 22 | sysinfo.txt 23 | 24 | UnityProject/\.vs/ 25 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/Vella.Common.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vella.Common", 3 | "references": [ 4 | "GUID:b92ff8b696eb46a4b90382b319e963fe", 5 | "GUID:e0cd26848372d4e5c891c569017e11f1", 6 | "GUID:d8b63aba1907145bea998dd612889d6b" 7 | ], 8 | "optionalUnityReferences": [], 9 | "includePlatforms": [], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": true, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [], 16 | "versionDefines": [] 17 | } -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/Vella.UnityNativeHull.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vella.NativeHull", 3 | "references": [ 4 | "GUID:d8b63aba1907145bea998dd612889d6b", 5 | "GUID:b92ff8b696eb46a4b90382b319e963fe", 6 | "GUID:e0cd26848372d4e5c891c569017e11f1", 7 | "GUID:b46976b8a773ae341bbd9ca990e20dfb" 8 | ], 9 | "optionalUnityReferences": [], 10 | "includePlatforms": [], 11 | "excludePlatforms": [], 12 | "allowUnsafeCode": true, 13 | "overrideReferences": false, 14 | "precompiledReferences": [], 15 | "autoReferenced": true, 16 | "defineConstraints": [], 17 | "versionDefines": [] 18 | } -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Tests/Vella.UnityNativeHull.Tests.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vella.NativeHull.Tests", 3 | "references": [ 4 | "GUID:d8b63aba1907145bea998dd612889d6b", 5 | "GUID:56d587dec131a3d49b5ef08d8a57d219", 6 | "GUID:b46976b8a773ae341bbd9ca990e20dfb" 7 | ], 8 | "optionalUnityReferences": [ 9 | "TestAssemblies" 10 | ], 11 | "includePlatforms": [ 12 | "Editor" 13 | ], 14 | "excludePlatforms": [], 15 | "allowUnsafeCode": true, 16 | "overrideReferences": false, 17 | "precompiledReferences": [], 18 | "autoReferenced": true, 19 | "defineConstraints": [], 20 | "versionDefines": [] 21 | } -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/NativeArrayExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Unity.Collections; 7 | using Unity.Collections.LowLevel.Unsafe; 8 | 9 | namespace Vella.Common 10 | { 11 | public static class NativeArrayExtensions 12 | { 13 | public static unsafe ref T AsRef(this NativeArray arr, int index) where T : unmanaged 14 | { 15 | return ref ((T*)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(arr))[index]; 16 | } 17 | 18 | 19 | public static T[] ToArray(this NativeArray arr, int length) where T : unmanaged 20 | { 21 | var dst = new T[length]; 22 | NativeArray.Copy(arr, dst, length); 23 | return dst; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | m_ExternalVersionControlSupport: Hidden Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 2 10 | m_DefaultBehaviorMode: 0 11 | m_PrefabRegularEnvironment: {fileID: 0} 12 | m_PrefabUIEnvironment: {fileID: 0} 13 | m_SpritePackerMode: 0 14 | m_SpritePackerPaddingPower: 1 15 | m_EtcTextureCompressorBehavior: 1 16 | m_EtcTextureFastCompressor: 1 17 | m_EtcTextureNormalCompressor: 2 18 | m_EtcTextureBestCompressor: 4 19 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp 20 | m_ProjectGenerationRootNamespace: 21 | m_CollabEditorSettings: 22 | inProgressEnabled: 1 23 | m_EnableTextureStreamingInEditMode: 1 24 | m_EnableTextureStreamingInPlayMode: 1 25 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 1 7 | m_Enabled: 1 8 | m_TestMode: 0 9 | m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events 10 | m_EventUrl: https://cdp.cloud.unity3d.com/v1/events 11 | m_ConfigUrl: https://config.uca.cloud.unity3d.com 12 | m_TestInitMode: 0 13 | CrashReportingSettings: 14 | m_EventUrl: https://perf-events.cloud.unity3d.com 15 | m_Enabled: 0 16 | m_LogBufferSize: 10 17 | m_CaptureEditorExceptions: 1 18 | UnityPurchasingSettings: 19 | m_Enabled: 0 20 | m_TestMode: 0 21 | UnityAnalyticsSettings: 22 | m_Enabled: 0 23 | m_TestMode: 0 24 | m_InitializeOnStartup: 1 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/NativeHalfEdge.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Unity.Mathematics; 3 | 4 | namespace Vella.UnityNativeHull 5 | { 6 | [DebuggerDisplay("NativeHalfEdge: Origin={Origin}, Face={Face}, Twin={Twin}, [Prev{Prev} Next={Next}]")] 7 | public struct NativeHalfEdge 8 | { 9 | /// 10 | /// The previous edge index in face loop 11 | /// 12 | public int Prev; 13 | 14 | /// 15 | /// The next edge index in face loop 16 | /// 17 | public int Next; 18 | 19 | /// 20 | /// The edge on the other side of this edge (in a different face loop) 21 | /// 22 | public int Twin; 23 | 24 | /// 25 | /// The face index of this face loop 26 | /// 27 | public int Face; 28 | 29 | /// 30 | /// The index of the vertex at the start of this edge. 31 | /// 32 | public int Origin; 33 | }; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2019 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/NativeArray2D.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Unity.Collections.LowLevel.Unsafe; 4 | using Unity.Collections; 5 | using System.Collections; 6 | 7 | namespace Vella.Common 8 | { 9 | public struct NativeArray2D : IDisposable, IEnumerable where T : unmanaged 10 | { 11 | public NativeArray Internal; 12 | private readonly int _yLength; 13 | private readonly int _xLength; 14 | 15 | public NativeArray2D(int x, int y, Allocator allocator, NativeArrayOptions options = NativeArrayOptions.ClearMemory) 16 | { 17 | Internal = new NativeArray(x * y, allocator); 18 | _yLength = y; 19 | _xLength = x; 20 | } 21 | 22 | public unsafe ref T this[int i] => ref Internal.AsRef(i); 23 | 24 | public ref T this[int x, int y] => ref this[(x * _yLength) + y]; 25 | 26 | public int XLength => _xLength; 27 | 28 | public int YLength => _yLength; 29 | 30 | public int Length => Internal.Length; 31 | 32 | public void Dispose() => Internal.Dispose(); 33 | 34 | public IEnumerator GetEnumerator() => Internal.GetEnumerator(); 35 | 36 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 37 | } 38 | } -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/BvhTestShape.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using Unity.Mathematics; 4 | using Vella.Common; 5 | using Vella.UnityNativeHull; 6 | 7 | [DebuggerDisplay("TestShape: Id={Id}")] 8 | public struct TestShape : IBoundingHierarchyNode, IEquatable, IComparable 9 | { 10 | public int Id; 11 | 12 | public RigidTransform Transform; 13 | public NativeHull Hull; 14 | 15 | public BoundingBox BoundingBox; 16 | public BoundingSphere BoundingSphere; 17 | 18 | public bool HasChanged => true; 19 | 20 | public float3 Position => Transform.pos; 21 | 22 | public float Radius => BoundingSphere.radius; 23 | 24 | public bool Equals(TestShape other) 25 | { 26 | return Id == other.Id; 27 | } 28 | 29 | public override bool Equals(object obj) 30 | { 31 | return obj is TestShape shape && shape.Equals(this); 32 | } 33 | 34 | public int CompareTo(TestShape other) 35 | { 36 | return Id.CompareTo(other.Id); 37 | } 38 | 39 | public override int GetHashCode() 40 | { 41 | return Id; 42 | } 43 | 44 | public void OnUpdate() 45 | { 46 | 47 | } 48 | 49 | public void OnTransformChanged() 50 | { 51 | 52 | } 53 | 54 | } 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 11 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 0 23 | m_ReuseCollisionCallbacks: 1 24 | m_ClothInterCollisionSettingsToggle: 0 25 | m_ContactPairsMode: 0 26 | m_BroadphaseType: 0 27 | m_WorldBounds: 28 | m_Center: {x: 0, y: 0, z: 0} 29 | m_Extent: {x: 250, y: 250, z: 250} 30 | m_WorldSubdivisions: 8 31 | m_FrictionType: 0 32 | m_EnableEnhancedDeterminism: 0 33 | m_EnableUnifiedHeightmaps: 1 34 | m_DefaultMaxAngluarSpeed: 7 35 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/StructConversion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity.Collections.LowLevel.Unsafe; 3 | 4 | namespace Vella.Common 5 | { 6 | public interface IConvertible where T : struct { } 7 | 8 | public static class StructConversion 9 | { 10 | public static unsafe void Convert(TInput input, out TOutput output) 11 | where TInput : struct, IConvertible 12 | where TOutput : struct, IConvertible 13 | { 14 | if (UnsafeUtility.SizeOf() != UnsafeUtility.SizeOf()) 15 | { 16 | throw new InvalidCastException(string.Format("Cannot convert type of '{0}' because their size is different: '{1}' and '{2}' respectively", 17 | input, UnsafeUtility.SizeOf(), UnsafeUtility.SizeOf())); 18 | } 19 | 20 | UnsafeUtility.CopyPtrToStructure(UnsafeUtility.AddressOf(ref input), out output); 21 | } 22 | 23 | public static unsafe TOutput Convert(TInput input) 24 | where TInput : struct, IConvertible 25 | where TOutput : struct, IConvertible 26 | { 27 | if (UnsafeUtility.SizeOf() != UnsafeUtility.SizeOf()) 28 | { 29 | throw new InvalidCastException(string.Format("Cannot convert type of '{0}' because their size is different: '{1}' and '{2}' respectively", 30 | input, UnsafeUtility.SizeOf(), UnsafeUtility.SizeOf())); 31 | } 32 | UnsafeUtility.CopyPtrToStructure(UnsafeUtility.AddressOf(ref input), out TOutput output); 33 | return output; 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityNativeCollision # 2 | 3 | This project is an experimental C# implementation of polyhedron SAT collision and intersection for the Unity game engine. It's specifically designed to be compatible with Unity's Burst Compiler for performance. 4 | 5 | ##### Acknowledgments: 6 | The math is ported to C# from the C++ BounceLite project by Irlan Robson (zLib License) and adapted for Unity's new Math library and Burst Compiler requirments: https://github.com/irlanrobson/bounce_lite 7 | 8 | The SAT implementation is originally based on the 2013 GDC presentation by Dirk Gregorius and his forum posts about Valve's Rubikon physics engine: 9 | * https://www.gdcvault.com/play/1017646/Physics-for-Game-Programmers-The 10 | * https://www.gamedev.net/forums/topic/692141-collision-detection-why-gjk/?do=findComment&comment=5356490 11 | * http://www.gamedev.net/topic/667499-3d-sat-problem/ 12 | 13 | ##### Features: 14 | 15 | * Generation of native half-edge mesh from Unity Meshes. 16 | * Fast convex polyhedron face/edge boolean collision detection. 17 | * Polyhedron intersection manifold generation (via Sutherland-Hodgman clipping) 18 | * Burst compiled jobs for single and batch collision operations. 19 | * Experimental bounding volume hierarchy. 20 | * NativeBuffer collection able to run off stackalloc. 21 | 22 | 23 | 24 | Note: Project was created with Unity 2019.2, older versions may not work. 25 | 26 | ##### Performance: 27 | 28 | 29 | 30 | ##### Contact Visualization: 31 | 32 | View a fast version of the contact for physics calcluations. This mode a processes a minimal set of geometry, just enough to move colliding objects apart. Versus the full intersection mode, which needs to clip every face for visual/mesh creation purposes. 33 | 34 | 35 | -------------------------------------------------------------------------------- /UnityNativeCollision/Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.ads": "2.0.8", 4 | "com.unity.analytics": "3.2.2", 5 | "com.unity.burst": "0.2.4-preview.41", 6 | "com.unity.collab-proxy": "1.2.15", 7 | "com.unity.collections": "0.0.9-preview.11", 8 | "com.unity.mathematics": "0.0.12-preview.19", 9 | "com.unity.package-manager-ui": "2.1.1", 10 | "com.unity.probuilder": "4.0.3", 11 | "com.unity.purchasing": "2.0.1", 12 | "com.unity.textmeshpro": "1.3.0", 13 | "com.unity.timeline": "1.0.0", 14 | "com.unity.modules.ai": "1.0.0", 15 | "com.unity.modules.animation": "1.0.0", 16 | "com.unity.modules.assetbundle": "1.0.0", 17 | "com.unity.modules.audio": "1.0.0", 18 | "com.unity.modules.cloth": "1.0.0", 19 | "com.unity.modules.director": "1.0.0", 20 | "com.unity.modules.imageconversion": "1.0.0", 21 | "com.unity.modules.imgui": "1.0.0", 22 | "com.unity.modules.jsonserialize": "1.0.0", 23 | "com.unity.modules.particlesystem": "1.0.0", 24 | "com.unity.modules.physics": "1.0.0", 25 | "com.unity.modules.physics2d": "1.0.0", 26 | "com.unity.modules.screencapture": "1.0.0", 27 | "com.unity.modules.terrain": "1.0.0", 28 | "com.unity.modules.terrainphysics": "1.0.0", 29 | "com.unity.modules.tilemap": "1.0.0", 30 | "com.unity.modules.ui": "1.0.0", 31 | "com.unity.modules.uielements": "1.0.0", 32 | "com.unity.modules.umbra": "1.0.0", 33 | "com.unity.modules.unityanalytics": "1.0.0", 34 | "com.unity.modules.unitywebrequest": "1.0.0", 35 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 36 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 37 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 38 | "com.unity.modules.unitywebrequestwww": "1.0.0", 39 | "com.unity.modules.vehicles": "1.0.0", 40 | "com.unity.modules.video": "1.0.0", 41 | "com.unity.modules.vr": "1.0.0", 42 | "com.unity.modules.wind": "1.0.0", 43 | "com.unity.modules.xr": "1.0.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullIterators.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Unity.Mathematics; 4 | using System.Collections; 5 | 6 | namespace Vella.UnityNativeHull 7 | { 8 | /// 9 | /// Loops through all edges in a hull or a specific hull face. 10 | /// Note: this can be used with foreach statements within Burst compiled code. 11 | /// 12 | public ref struct EdgeEnumerator 13 | { 14 | private int _offset; 15 | private int _edgeIndex; 16 | private int _currentIndex; 17 | private NativeHull _hull; 18 | 19 | public EdgeEnumerator(NativeHull hull) : this() 20 | { 21 | _hull = hull; 22 | _offset = -1; 23 | _currentIndex = -1; 24 | } 25 | 26 | public EdgeEnumerator(NativeHull hull, int faceIndex) : this() 27 | { 28 | _hull = hull; 29 | _offset = hull.GetFace(faceIndex).Edge; 30 | _currentIndex = -1; 31 | } 32 | 33 | public ref NativeHalfEdge Current => ref _hull.GetEdgeRef(_edgeIndex); 34 | 35 | public bool MoveNext() 36 | { 37 | _currentIndex++; 38 | 39 | if (_edgeIndex >= _hull.EdgeCount-1) 40 | { 41 | return false; 42 | } 43 | else if (_offset == -1) 44 | { 45 | _edgeIndex = _currentIndex; 46 | } 47 | else if (_currentIndex == 0) 48 | { 49 | _edgeIndex = _offset; 50 | } 51 | else 52 | { 53 | ref var edge = ref _hull.GetEdgeRef(_edgeIndex); 54 | if (edge.Next == _offset) 55 | { 56 | return false; 57 | } 58 | _edgeIndex = edge.Next; 59 | } 60 | return true; 61 | } 62 | 63 | public EdgeEnumerator GetEnumerator() => this; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/BoundingSphere.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity.Mathematics; 3 | 4 | namespace Vella.Common 5 | { 6 | public struct BoundingSphere : IEquatable 7 | { 8 | public float3 center; 9 | public float radius; 10 | 11 | public BoundingSphere(float3 _center, float _radius) 12 | { 13 | center = _center; 14 | radius = _radius; 15 | } 16 | 17 | public bool Equals(BoundingSphere other) 18 | { 19 | return this.center.x == other.center.x 20 | && this.center.y == other.center.y 21 | && this.center.z == other.center.z 22 | && this.radius == other.radius; 23 | } 24 | 25 | public bool IntersectsSphere(BoundingSphere other) 26 | { 27 | float addedR = this.radius + other.radius; 28 | float addedRSq = addedR * addedR; 29 | float distSq = math.lengthsq(other.center - this.center); 30 | return addedRSq >= distSq; 31 | } 32 | 33 | //public bool IntersectsRay(ref SSRay worldSpaceRay, out float distanceAlongRay) 34 | //{ 35 | // float distanceToSphereOrigin = OpenTKHelper.DistanceToLine( 36 | // worldSpaceRay, this.center, out distanceAlongRay); 37 | // return distanceToSphereOrigin <= this.radius; 38 | //} 39 | 40 | public bool IntersectsAABB(BoundingBox aabb) 41 | { 42 | return aabb.IntersectsSphere(this); 43 | } 44 | 45 | public BoundingBox ToAABB() 46 | { 47 | float3 rvec = new float3(radius); 48 | return new BoundingBox(center - rvec, center + rvec); 49 | } 50 | 51 | public static BoundingSphere FromAABB(BoundingBox box) 52 | { 53 | BoundingSphere result; 54 | result.center = (box.Min + box.Max) * .5f; 55 | result.radius = math.distance(result.center, box.Max); 56 | return result; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_JobOptions: 23 | serializedVersion: 2 24 | useMultithreading: 0 25 | useConsistencySorting: 0 26 | m_InterpolationPosesPerJob: 100 27 | m_NewContactsPerJob: 30 28 | m_CollideContactsPerJob: 100 29 | m_ClearFlagsPerJob: 200 30 | m_ClearBodyForcesPerJob: 200 31 | m_SyncDiscreteFixturesPerJob: 50 32 | m_SyncContinuousFixturesPerJob: 50 33 | m_FindNearestContactsPerJob: 100 34 | m_UpdateTriggerContactsPerJob: 100 35 | m_IslandSolverCostThreshold: 100 36 | m_IslandSolverBodyCostScale: 1 37 | m_IslandSolverContactCostScale: 10 38 | m_IslandSolverJointCostScale: 10 39 | m_IslandSolverBodiesPerJob: 50 40 | m_IslandSolverContactsPerJob: 50 41 | m_AutoSimulation: 1 42 | m_QueriesHitTriggers: 1 43 | m_QueriesStartInColliders: 1 44 | m_CallbacksOnDisable: 1 45 | m_ReuseCollisionCallbacks: 1 46 | m_AutoSyncTransforms: 0 47 | m_AlwaysShowColliders: 0 48 | m_ShowColliderSleep: 1 49 | m_ShowColliderContacts: 0 50 | m_ShowColliderAABB: 0 51 | m_ContactArrowScale: 0.2 52 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 53 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 54 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 55 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 56 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 57 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/MathUtility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Unity.Collections.LowLevel.Unsafe; 5 | using Unity.Mathematics; 6 | using UnityEngine; 7 | using Vella.Common; 8 | 9 | namespace Vella.Common 10 | { 11 | public static class MathUtility 12 | { 13 | /// 14 | /// Find point on a line with start/end positions 15 | /// 16 | public static float3 ProjectPointOnLineSegment(float3 linePoint1, float3 linePoint2, float3 point) 17 | { 18 | float3 vector = linePoint2 - linePoint1; 19 | float3 projectedPoint = ProjectPointOnLine(linePoint1, math.normalize(vector), point); 20 | int side = PointOnWhichSideOfLineSegment(linePoint1, linePoint2, projectedPoint); 21 | switch (side) 22 | { 23 | case 0: 24 | return projectedPoint; 25 | case 1: 26 | return linePoint1; 27 | case 2: 28 | return linePoint2; 29 | } 30 | return default; 31 | } 32 | 33 | /// 34 | /// Find point on infinate line (result is not clipped to a line segment) 35 | /// 36 | public static float3 ProjectPointOnLine(float3 linePoint, float3 lineVec, float3 point) 37 | { 38 | return linePoint + lineVec * math.dot(point - linePoint, lineVec); 39 | } 40 | 41 | 42 | /// 43 | /// This function finds out on which side of a line segment the point is located. 44 | /// 45 | public static int PointOnWhichSideOfLineSegment(float3 linePoint1, float3 linePoint2, float3 point) 46 | { 47 | //Returns 0 if point is on the line segment. 48 | //Returns 1 if point is outside of the line segment and located on the side of linePoint1. 49 | //Returns 2 if point is outside of the line segment and located on the side of linePoint2. 50 | 51 | float3 lineVec = linePoint2 - linePoint1; 52 | float3 pointVec = point - linePoint1; 53 | return math.dot(pointVec, lineVec) <= 0 ? 1 : math.length(pointVec) <= math.length(lineVec) ? 0 : 2; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Translucent.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Translucent 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.97086746, g: 1, b: 0.6367924, a: 0.4745098} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 12 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} 39 | - {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0} 40 | - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} 41 | m_PreloadedShaders: [] 42 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 43 | type: 0} 44 | m_CustomRenderPipeline: {fileID: 0} 45 | m_TransparencySortMode: 0 46 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 47 | m_DefaultRenderingPath: 1 48 | m_DefaultMobileRenderingPath: 1 49 | m_TierSettings: [] 50 | m_LightmapStripping: 0 51 | m_FogStripping: 0 52 | m_InstancingStripping: 0 53 | m_LightmapKeepPlain: 1 54 | m_LightmapKeepDirCombined: 1 55 | m_LightmapKeepDynamicPlain: 1 56 | m_LightmapKeepDynamicDirCombined: 1 57 | m_LightmapKeepShadowMask: 1 58 | m_LightmapKeepSubtractive: 1 59 | m_FogKeepLinear: 1 60 | m_FogKeepExp: 1 61 | m_FogKeepExp2: 1 62 | m_AlbedoSwatchInfos: [] 63 | m_LightsUseLinearIntensity: 0 64 | m_LightsUseColorTemperature: 0 65 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/NativeManifold.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using Unity.Collections; 4 | using Unity.Mathematics; 5 | using Vella.Common; 6 | 7 | namespace Vella.UnityNativeHull 8 | { 9 | 10 | 11 | public unsafe struct NativeManifold : IDisposable 12 | { 13 | public const int MaxPoints = 24; 14 | public float3 Normal; //A -> B. 15 | 16 | private int _maxIndex; 17 | 18 | private NativeBuffer _points; 19 | 20 | public ContactPoint[] ToArray() => _points.ToArray(Length); 21 | 22 | public ContactPoint this[int i] => _points.GetItem(i); 23 | 24 | public int Length => _maxIndex + 1; 25 | 26 | public bool IsCreated => _points.IsCreated; 27 | 28 | public NativeManifold(Allocator allocator) 29 | { 30 | _points = NativeBuffer.Create(MaxPoints, Allocator.Persistent); 31 | _maxIndex = -1; 32 | Normal = 0; 33 | } 34 | 35 | public void Add(float3 position, float distance, ContactID id) 36 | { 37 | Add(new ContactPoint 38 | { 39 | Id = id, 40 | Position = position, 41 | Distance = distance, 42 | }); 43 | } 44 | 45 | public void Add(ContactPoint cp) 46 | { 47 | if (_maxIndex >= MaxPoints) 48 | return; 49 | 50 | _points.SetItem(++_maxIndex, cp); 51 | } 52 | 53 | public void Dispose() 54 | { 55 | if (_points.IsCreated) 56 | { 57 | _points.Dispose(); 58 | } 59 | } 60 | } 61 | 62 | public struct ContactPoint 63 | { 64 | public ContactID Id; 65 | 66 | /// 67 | /// The contact point, at the point in time when the shapes first collide. 68 | /// (center of the line between points on each shape). 69 | /// 70 | public float3 Position; 71 | 72 | public float NormalImpulse; 73 | public float3 Tangent1; 74 | public float3 Tangent2; 75 | public float TangentImpulse1; 76 | public float TangentImpulse2; 77 | public float Distance; 78 | 79 | public float3 Penetration; 80 | 81 | /// 82 | /// Closest position clamped to the edge 83 | /// 84 | public float3 PositionOnTarget; 85 | 86 | /// 87 | /// Closest position clamped to the edge 88 | /// 89 | public float3 PositionOnSource; 90 | } 91 | 92 | //[StructLayout(LayoutKind.Explicit)] 93 | public struct ContactID 94 | { 95 | //[FieldOffset(0)] 96 | public FeaturePair FeaturePair; 97 | //[FieldOffset(0)] 98 | public int Key; 99 | } 100 | 101 | public struct FeaturePair 102 | { 103 | public int InEdge1; 104 | public int OutEdge1; 105 | public int InEdge2; 106 | public int OutEdge2; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/NativePlane.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Unity.Mathematics; 3 | using UnityEngine; 4 | using static Unity.Mathematics.math; 5 | 6 | namespace Vella.UnityNativeHull 7 | { 8 | [DebuggerDisplay("NativePlane: {Normal}, {Offset}")] 9 | public unsafe struct NativePlane 10 | { 11 | /// 12 | /// Direction of the plane from hull origin 13 | /// 14 | public float3 Normal; 15 | 16 | /// 17 | /// Distance of the plane from hull origin. 18 | /// 19 | public float Offset; 20 | 21 | public float3 Position => Normal * Offset; 22 | 23 | public NativePlane(float3 normal, float offset) 24 | { 25 | Normal = normal; 26 | Offset = offset; 27 | } 28 | 29 | public NativePlane(float3 a, float3 b, float3 c) 30 | { 31 | Normal = normalize(cross(b - a, c - a)); 32 | Offset = dot(Normal, a); 33 | } 34 | 35 | public float Distance(float3 point) 36 | { 37 | return dot(Normal, point) - Offset; 38 | } 39 | 40 | public float3 ClosestPoint(float3 point) 41 | { 42 | return point - Distance(point) * normalize(Normal); 43 | } 44 | 45 | public (float3 Position, float3 Rotation) Transform(RigidTransform t) 46 | { 47 | float3 tRot = mul(t.rot, Normal); 48 | return (t.pos + tRot * Offset, tRot); 49 | } 50 | 51 | public static NativePlane operator *(float4x4 m, NativePlane plane) 52 | { 53 | float3 tPos = transform(m, plane.Normal * plane.Offset); 54 | float3 tRot = rotate(m, plane.Normal); 55 | return new NativePlane(tRot, dot(tRot, tPos)); 56 | } 57 | 58 | public static NativePlane operator *(RigidTransform t, NativePlane plane) 59 | { 60 | float3 normal = mul(t.rot, plane.Normal); 61 | return new NativePlane(normal, plane.Offset + dot(normal, t.pos)); 62 | } 63 | 64 | /// 65 | /// Is a point on the positive side of the plane 66 | /// 67 | public bool IsPositiveSide(float3 point) 68 | { 69 | return dot(Normal, point) + Offset > 0.0; 70 | } 71 | 72 | /// 73 | /// If two points on the same side of the plane 74 | /// 75 | public bool SameSide(float3 a, float3 b) 76 | { 77 | float distanceToPoint1 = Distance(a); 78 | float distanceToPoint2 = Distance(b); 79 | return distanceToPoint1 > 0.0 && distanceToPoint2 > 0.0 || distanceToPoint1 <= 0.0 && distanceToPoint2 <= 0.0; 80 | } 81 | 82 | public bool Raycast(Ray ray, out float enter) 83 | { 84 | float a = dot(ray.direction, Normal); 85 | float num = -dot(ray.origin, Normal) - Offset; 86 | if (Mathf.Approximately(a, 0.0f)) 87 | { 88 | enter = 0.0f; 89 | return false; 90 | } 91 | enter = num / a; 92 | return enter > 0.0; 93 | } 94 | 95 | public Plane Flipped => new Plane(-Normal, -Offset); 96 | }; 97 | } -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Tests/BoxCreation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using NUnit.Framework; 5 | using Unity.Mathematics; 6 | using UnityEngine; 7 | using UnityEngine.TestTools; 8 | using Vella.Common; 9 | using Vella.UnityNativeHull; 10 | 11 | public class BoxCreation 12 | { 13 | public const int BoxSize = 1; 14 | 15 | public static NativeHull CreateBox() => HullFactory.CreateBox(BoxSize); 16 | 17 | [Test] 18 | public unsafe void Box_IsCreated() 19 | { 20 | using (var box = HullFactory.CreateBox(BoxSize)) 21 | { 22 | Assert.IsTrue(box.IsCreated); 23 | Assert.IsFalse(box.IsDisposed); 24 | 25 | Assert.IsTrue((IntPtr)box.Faces != IntPtr.Zero); 26 | Assert.IsTrue((IntPtr)box.Vertices != IntPtr.Zero); 27 | Assert.IsTrue((IntPtr)box.Planes != IntPtr.Zero); 28 | Assert.IsTrue((IntPtr)box.Faces != IntPtr.Zero); 29 | Assert.IsTrue((IntPtr)box.Edges != IntPtr.Zero); 30 | } 31 | } 32 | 33 | [Test] 34 | public void Box_Vertices() 35 | { 36 | var validUnitBoxVertices = new HashSet 37 | { 38 | new float3(0.5f, 0.5f, -0.5f), 39 | new float3(-0.5f, 0.5f, -0.5f), 40 | new float3(-0.5f, -0.5f, -0.5f), 41 | new float3(0.5f, -0.5f, -0.5f), 42 | new float3(0.5f, 0.5f, 0.5f), 43 | new float3(-0.5f, 0.5f, 0.5f), 44 | new float3(-0.5f, -0.5f, 0.5f), 45 | new float3(0.5f, -0.5f, 0.5f) 46 | }; 47 | 48 | using (var box = CreateBox()) 49 | { 50 | Assert.IsTrue(box.VertexCount == 8); 51 | 52 | for (int i = 0; i < box.VertexCount; i++) 53 | { 54 | var vertex = box.GetVertex(i); 55 | 56 | Assert.IsTrue(validUnitBoxVertices.Contains(vertex), 57 | "All vertices should be in one of eight specific positions"); 58 | 59 | validUnitBoxVertices.Remove(vertex); 60 | } 61 | } 62 | } 63 | 64 | [Test] 65 | public void Box_Planes() 66 | { 67 | var validAABBNormals = new HashSet 68 | { 69 | Vector3.up, Vector3.down, 70 | Vector3.left, Vector3.right, 71 | Vector3.forward, Vector3.back, 72 | }; 73 | 74 | var validPlaneOffset = BoxSize * 0.5f; 75 | 76 | using (var box = CreateBox()) 77 | { 78 | Assert.IsTrue(box.FaceCount == 6); 79 | 80 | for (int i = 0; i < box.FaceCount; i++) 81 | { 82 | var plane = box.GetPlane(i); 83 | 84 | Assert.IsTrue(validAABBNormals.Contains(plane.Normal), 85 | "The plane normal of an Axis-Aligned box should be a base direction"); 86 | 87 | Assert.IsTrue(plane.Offset == validPlaneOffset, 88 | "The plane offset from the centroid should be half the box size"); 89 | } 90 | } 91 | } 92 | 93 | [Test] 94 | public void Box_Edges() 95 | { 96 | using (var box = CreateBox()) 97 | { 98 | Assert.IsTrue(box.EdgeCount == 24); 99 | 100 | for (int i = 0; i < box.EdgeCount; i++) 101 | { 102 | HullValidation.ValidateEdge(box, i); 103 | } 104 | } 105 | } 106 | 107 | [Test] 108 | public void Box_Faces() 109 | { 110 | using (var box = CreateBox()) 111 | { 112 | Assert.IsTrue(box.FaceCount == 6); 113 | 114 | for (int i = 0; i < box.FaceCount; i++) 115 | { 116 | HullValidation.ValidateFace(box, i); 117 | } 118 | } 119 | } 120 | 121 | 122 | 123 | } 124 | 125 | 126 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/NativePairBuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Diagnostics; 5 | using System.Net.Http.Headers; 6 | using Unity.Collections; 7 | using Unity.Collections.LowLevel.Unsafe; 8 | 9 | namespace Vella.Common 10 | { 11 | /// 12 | /// Wrapper on NativeBuffer allowing two objects to be stored sequentially per row 13 | /// 14 | [NativeContainer] 15 | [DebuggerDisplay("Length = {Length}")] 16 | [DebuggerTypeProxy(typeof(NativeBufferDebugView<>))] 17 | public struct NativePairBuffer : IDisposable where THead : unmanaged, IEquatable, IComparable where T : struct, IEquatable, IComparable 18 | { 19 | private NativeBuffer _buffer; 20 | private readonly int _headSize; 21 | 22 | public struct Pair 23 | { 24 | public THead Header; 25 | public T Value; 26 | } 27 | 28 | public unsafe NativePairBuffer(void* ptr, int elementCount) 29 | { 30 | _headSize = UnsafeUtility.SizeOf(); 31 | _buffer = new NativeBuffer(ptr, elementCount); 32 | } 33 | 34 | public void CopyFrom(NativePairBuffer source) 35 | { 36 | _buffer.CopyFrom(source._buffer); 37 | } 38 | 39 | public NativePairBuffer(int length, Allocator allocator, NativeArrayOptions options = NativeArrayOptions.ClearMemory) 40 | { 41 | _headSize = UnsafeUtility.SizeOf(); 42 | _buffer = new NativeBuffer(length, allocator, options); 43 | } 44 | 45 | public ref Pair this[int i] => ref _buffer[i]; 46 | 47 | public ref THead GetItemHeader(int i) => ref _buffer.AsRef(i); 48 | 49 | public ref T GetItemValue(int i) => ref _buffer.AsRef(i, _headSize); 50 | 51 | public int Add(THead header, T item) => _buffer.Add(new Pair 52 | { 53 | Header = header, 54 | Value = item, 55 | }); 56 | 57 | public bool RemoveAt(int index) => _buffer.RemoveAt(index); 58 | 59 | public void RemoveAtSwapBack(int index) => _buffer.RemoveAtSwapBack(index); 60 | 61 | public unsafe void Remove(TU* elementPtr) where TU : unmanaged => _buffer.Remove(elementPtr); 62 | 63 | public Pair Pop() => _buffer.Pop(); 64 | 65 | public int IndexOf(T item) => _buffer.IndexOf(item); 66 | 67 | public int IndexOf(THead item) => _buffer.IndexOf(item, _headSize); 68 | 69 | public bool Contains(T item) => IndexOf(item) != -1; 70 | 71 | public bool Contains(THead item) => IndexOf(item) != -1; 72 | 73 | public void Reverse() => _buffer.Reverse(); 74 | 75 | public int Capacity => _buffer.Length; 76 | 77 | public int CapacityBytes => _buffer.CapacityBytes; 78 | 79 | public int Length => _buffer.Length; 80 | 81 | public bool IsCreated => _buffer.IsCreated; 82 | 83 | public void Clear() => _buffer.Clear(); 84 | 85 | public void SetLength(int itemCount) => _buffer.SetLength(itemCount); 86 | 87 | public Pair[] ToArray() => _buffer.ToArray(); 88 | 89 | public void Dispose() => _buffer.Dispose(); 90 | 91 | //public void Sort(IComparer comparer = null) => _buffer.Sort(comparer); 92 | 93 | //public void SortDescending(IComparer comparer = null) => _buffer.Sort(comparer); 94 | 95 | //public void Sort(IComparer comparer, TParam param) where TParam : unmanaged => _buffer.Sort(comparer, param); 96 | 97 | //public void SortDescending(IComparer comparer, TParam param) where TParam : unmanaged => _buffer.Sort(comparer, param); 98 | 99 | public NativeBuffer.NativeBufferEnumerator GetEnumerator() => new NativeBuffer.NativeBufferEnumerator(ref _buffer); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullValidation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using Unity.Mathematics; 7 | using UnityEngine; 8 | using Vella.Common; 9 | using Vella.UnityNativeHull; 10 | using Debug = UnityEngine.Debug; 11 | 12 | public class HullValidation 13 | { 14 | [Conditional("UNITY_EDITOR")] 15 | public unsafe static void ValidateHull(NativeHull hull) 16 | { 17 | Debug.Assert(hull.IsCreated); 18 | Debug.Assert(!hull.IsDisposed); 19 | 20 | Debug.Assert((IntPtr)hull.Faces != IntPtr.Zero); 21 | Debug.Assert((IntPtr)hull.Vertices != IntPtr.Zero); 22 | Debug.Assert((IntPtr)hull.Planes != IntPtr.Zero); 23 | Debug.Assert((IntPtr)hull.Faces != IntPtr.Zero); 24 | Debug.Assert((IntPtr)hull.Edges != IntPtr.Zero); 25 | 26 | for (int i = 0; i < hull.FaceCount; i++) 27 | { 28 | ValidateFace(hull, i); 29 | } 30 | 31 | CheckAllVerticesAreUsed(hull); 32 | CheckForInvalidUnusedEdges(hull); 33 | } 34 | 35 | [Conditional("UNITY_EDITOR")] 36 | public static unsafe void CheckAllVerticesAreUsed(NativeHull hull) 37 | { 38 | for (int i = 0; i < hull.VertexCount; i++) 39 | { 40 | bool isUsed = false; 41 | for (int j = 0; j < hull.EdgeCount; j++) 42 | { 43 | NativeHalfEdge edge = hull.GetEdge(j); 44 | if (edge.Origin == i) 45 | { 46 | isUsed = true; 47 | break; 48 | } 49 | } 50 | 51 | Debug.Assert(isUsed, 52 | "All vertices should be used by an edge"); 53 | } 54 | } 55 | 56 | [Conditional("UNITY_EDITOR")] 57 | public static void CheckForInvalidUnusedEdges(NativeHull hull) 58 | { 59 | for (int j = 0; j < hull.EdgeCount; j++) 60 | { 61 | ValidateEdge(hull, j); 62 | } 63 | } 64 | 65 | [Conditional("UNITY_EDITOR")] 66 | public static void ValidateFace(NativeHull hull, int faceIndex) 67 | { 68 | if (faceIndex < 0) 69 | throw new ArgumentOutOfRangeException(nameof(faceIndex)); 70 | 71 | NativeFace face = hull.GetFace(faceIndex); 72 | 73 | Debug.Assert(face.Edge >= 0, 74 | "All faces should point to a starting edge index"); 75 | 76 | Debug.Assert(face.Edge < hull.EdgeCount, 77 | "A face references an out of range edge index"); 78 | 79 | NativeHalfEdge startEdge = hull.GetEdge(face.Edge); 80 | NativeHalfEdge current = startEdge; 81 | 82 | int currentIndex = face.Edge; 83 | var edgeCount = 0; 84 | 85 | do 86 | { 87 | var next = hull.GetEdge(current.Next); 88 | 89 | Debug.Assert(faceIndex == current.Face, 90 | "All edges in a face loop should point to the same face"); 91 | 92 | Debug.Assert(currentIndex == next.Prev, 93 | "Next and previous edges in a face loop should point to each other"); 94 | 95 | ValidateEdge(hull, currentIndex); 96 | 97 | if (++edgeCount >= hull.EdgeCount) 98 | { 99 | Debug.Assert(true, "Infinite loop in face edges"); 100 | break; 101 | } 102 | 103 | currentIndex = current.Next; 104 | current = next; 105 | } 106 | while (current.Origin != startEdge.Origin); 107 | 108 | Debug.Assert(edgeCount > 1, 109 | "Faces should have more than one edge"); 110 | } 111 | 112 | [Conditional("UNITY_EDITOR")] 113 | public static void ValidateEdge(NativeHull hull, int edgeIndex) 114 | { 115 | if (edgeIndex < 0) 116 | throw new ArgumentOutOfRangeException(nameof(edgeIndex)); 117 | 118 | var edge = hull.GetEdge(edgeIndex); 119 | 120 | if (edge.Twin == -1 || edge.Prev == -1 || edge.Next == -1) 121 | { 122 | Debug.LogError($"Edge {edgeIndex} has an out of range index for twin, prev or next"); 123 | 124 | // Avoid exceptions so our debug visualizations can aid in debugging the issue. 125 | return; 126 | } 127 | 128 | var twin = hull.GetEdge(edge.Twin); 129 | 130 | Debug.Assert(edgeIndex == twin.Twin, 131 | "The twin of the edge twin must be the edge itself"); 132 | 133 | Debug.Assert(math.abs(edge.Twin - edgeIndex) == 1, 134 | "An edge/twin combination should be indexed one directly after the other."); 135 | 136 | Debug.Assert(edgeIndex == hull.GetEdge(edge.Prev).Next, 137 | "The previous edge should point to the next edge"); 138 | 139 | Debug.Assert(edgeIndex == hull.GetEdge(edge.Next).Prev, 140 | "The next edge should point to the previous edge"); 141 | 142 | Debug.Assert(edge.Origin != twin.Origin, 143 | "Edges and their twin should not point to the same vertex"); 144 | 145 | Debug.Assert(edge.Face >= 0, 146 | "All edges should have a face index"); 147 | 148 | Debug.Assert(edge.Face < hull.FaceCount, 149 | "An edge references an out of range face index"); 150 | 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullOperations.cs: -------------------------------------------------------------------------------- 1 | using Unity.Mathematics; 2 | using Unity.Collections; 3 | using Unity.Burst; 4 | using Vella.Common; 5 | 6 | namespace Vella.UnityNativeHull 7 | { 8 | 9 | public struct BatchCollisionInput 10 | { 11 | public int Id; 12 | public RigidTransform Transform; 13 | public NativeHull Hull; 14 | } 15 | 16 | public struct BatchCollisionResult 17 | { 18 | public BatchCollisionInput A; 19 | public BatchCollisionInput B; 20 | } 21 | 22 | public static class HullOperations 23 | { 24 | [BurstCompile] 25 | public struct IsColliding : IBurstFunction 26 | { 27 | 28 | public bool Execute(RigidTransform t1, NativeHull hull1, RigidTransform t2, NativeHull hull2) 29 | { 30 | return HullCollision.IsColliding(t1, hull1, t2, hull2); 31 | } 32 | 33 | public static bool Invoke(RigidTransform t1, NativeHull hull1, RigidTransform t2, NativeHull hull2) 34 | { 35 | return BurstFunction.Run(Instance, t1, hull1, t2, hull2); 36 | } 37 | 38 | public static IsColliding Instance { get; } = new IsColliding(); 39 | } 40 | 41 | [BurstCompile] 42 | public struct ContainsPoint : IBurstFunction 43 | { 44 | public bool Execute(RigidTransform t1, NativeHull hull1, float3 point) 45 | { 46 | return HullCollision.Contains(t1, hull1, point); 47 | } 48 | 49 | public static bool Invoke(RigidTransform t1, NativeHull hull1, float3 point) 50 | { 51 | return BurstFunction.Run(Instance, t1, hull1, point); 52 | } 53 | 54 | public static ContainsPoint Instance { get; } = new ContainsPoint(); 55 | } 56 | 57 | [BurstCompile] 58 | public struct ClosestPoint : IBurstFunction 59 | { 60 | public float3 Execute(RigidTransform t1, NativeHull hull1, float3 point) 61 | { 62 | return HullCollision.ClosestPoint(t1, hull1, point); 63 | } 64 | 65 | public static float3 Invoke(RigidTransform t1, NativeHull hull1, float3 point) 66 | { 67 | return BurstFunction.Run(Instance, t1, hull1, point); 68 | } 69 | 70 | public static ClosestPoint Instance { get; } = new ClosestPoint(); 71 | } 72 | 73 | [BurstCompile] 74 | public struct TryGetContact : IBurstRefAction 75 | { 76 | public void Execute(ref NativeManifold manifold, RigidTransform t1, NativeHull hull1, RigidTransform t2, NativeHull hull2) 77 | { 78 | HullIntersection.NativeHullHullContact(ref manifold, t1, hull1, t2, hull2); 79 | } 80 | 81 | public static bool Invoke(out NativeManifold result, RigidTransform t1, NativeHull hull1, RigidTransform t2, NativeHull hull2) 82 | { 83 | // Burst Jobs can only allocate as 'temp' 84 | result = new NativeManifold(Allocator.Persistent); 85 | 86 | BurstRefAction.Run(Instance, ref result, t1, hull1, t2, hull2); 87 | return result.Length > 0; 88 | } 89 | 90 | public static TryGetContact Instance { get; } = new TryGetContact(); 91 | } 92 | 93 | [BurstCompile] 94 | public struct CollisionBatch : IBurstFunction, NativeList, bool> 95 | { 96 | public bool Execute(NativeArray hulls, NativeList results) 97 | { 98 | var isCollision = false; 99 | for (int i = 0; i < hulls.Length; ++i) 100 | { 101 | for (int j = i + 1; j < hulls.Length; j++) 102 | { 103 | var a = hulls[i]; 104 | var b = hulls[j]; 105 | 106 | if (HullCollision.IsColliding(a.Transform, a.Hull, b.Transform, b.Hull)) 107 | { 108 | isCollision = true; 109 | results.Add(new BatchCollisionResult 110 | { 111 | A = a, 112 | B = b, 113 | }); 114 | } 115 | } 116 | } 117 | return isCollision; 118 | } 119 | 120 | public static bool Invoke(NativeArray hulls, NativeList results) 121 | { 122 | return BurstFunction, NativeList, bool>.Run(Instance, hulls, results); 123 | } 124 | 125 | public static CollisionBatch Instance { get; } = new CollisionBatch(); 126 | } 127 | 128 | } 129 | } -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/BoundingBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using Unity.Mathematics; 5 | 6 | namespace Vella.Common 7 | { 8 | [DebuggerDisplay("AABB: {Min},{Max}")] 9 | public struct BoundingBox : IEquatable 10 | { 11 | public float3 Min; 12 | public float3 Max; 13 | 14 | public BoundingBox(float min = float.PositiveInfinity, float max = float.NegativeInfinity) 15 | { 16 | Min = new float3(min); 17 | Max = new float3(max); 18 | } 19 | 20 | public BoundingBox(float3 min, float3 max) 21 | { 22 | Min = min; 23 | Max = max; 24 | } 25 | 26 | public void Combine(ref BoundingBox other) 27 | { 28 | Min = math.min(Min, other.Min); 29 | Max = math.max(Max, other.Max); 30 | } 31 | 32 | public bool IntersectsSphere(float3 origin, float radius) 33 | { 34 | return (!(origin.x + radius < Min.x)) && 35 | (!(origin.y + radius < Min.y)) && 36 | (!(origin.z + radius < Min.z)) && 37 | (!(origin.x - radius > Max.x)) && 38 | (!(origin.y - radius > Max.y)) && 39 | (!(origin.z - radius > Max.z)); 40 | } 41 | 42 | public bool IntersectsSphere(BoundingSphere sphere) 43 | { 44 | return IntersectsSphere(sphere.center, sphere.radius); 45 | } 46 | 47 | public bool IntersectsAABB(BoundingBox box) 48 | { 49 | return ((Max.x > box.Min.x) && (Min.x < box.Max.x) && 50 | (Max.y > box.Min.y) && (Min.y < box.Max.y) && 51 | (Max.z > box.Min.z) && (Min.z < box.Max.z)); 52 | } 53 | 54 | public bool Equals(BoundingBox other) 55 | { 56 | return 57 | (Min.x == other.Min.x) && 58 | (Min.y == other.Min.y) && 59 | (Min.z == other.Min.z) && 60 | (Max.x == other.Max.x) && 61 | (Max.y == other.Max.y) && 62 | (Max.z == other.Max.z); 63 | } 64 | 65 | public void UpdateMin(float3 localMin) 66 | { 67 | Min = math.min(Min, localMin); 68 | } 69 | 70 | public void UpdateMax(float3 localMax) 71 | { 72 | Max = math.max(Max, localMax); 73 | } 74 | 75 | public float3 Center() 76 | { 77 | return (Min + Max) / 2f; 78 | } 79 | 80 | public float3 Size() 81 | { 82 | return Max - Min; 83 | } 84 | 85 | public BoundingSphere ToSphere() 86 | { 87 | float r = math.length(Size() + 0.001f) / 2f; 88 | return new BoundingSphere(Center(), r); 89 | } 90 | 91 | public void Encapsulate(float3 b) 92 | { 93 | UpdateMin(b); 94 | UpdateMax(b); 95 | } 96 | 97 | public void ExpandToFit(BoundingBox b) 98 | { 99 | if (b.Min.x < Min.x) { Min.x = b.Min.x; } 100 | if (b.Min.y < Min.y) { Min.y = b.Min.y; } 101 | if (b.Min.z < Min.z) { Min.z = b.Min.z; } 102 | 103 | if (b.Max.x > Max.x) { Max.x = b.Max.x; } 104 | if (b.Max.y > Max.y) { Max.y = b.Max.y; } 105 | if (b.Max.z > Max.z) { Max.z = b.Max.z; } 106 | } 107 | 108 | public BoundingBox ExpandedBy(BoundingBox b) 109 | { 110 | BoundingBox newbox = this; 111 | if (b.Min.x < newbox.Min.x) { newbox.Min.x = b.Min.x; } 112 | if (b.Min.y < newbox.Min.y) { newbox.Min.y = b.Min.y; } 113 | if (b.Min.z < newbox.Min.z) { newbox.Min.z = b.Min.z; } 114 | if (b.Max.x > newbox.Max.x) { newbox.Max.x = b.Max.x; } 115 | if (b.Max.y > newbox.Max.y) { newbox.Max.y = b.Max.y; } 116 | if (b.Max.z > newbox.Max.z) { newbox.Max.z = b.Max.z; } 117 | return newbox; 118 | } 119 | 120 | public void ExpandBy(BoundingBox b) 121 | { 122 | this = ExpandedBy(b); 123 | } 124 | 125 | public static BoundingBox FromSphere(float3 pos, float radius) 126 | { 127 | BoundingBox box; 128 | box.Min.x = pos.x - radius; 129 | box.Max.x = pos.x + radius; 130 | box.Min.y = pos.y - radius; 131 | box.Max.y = pos.y + radius; 132 | box.Min.z = pos.z - radius; 133 | box.Max.z = pos.z + radius; 134 | return box; 135 | } 136 | 137 | private static readonly float4[] c_homogenousCorners = { 138 | new float4(-1f, -1f, -1f, 1f), 139 | new float4(-1f, 1f, -1f, 1f), 140 | new float4(1f, 1f, -1f, 1f), 141 | new float4(1f, -1f, -1f, 1f), 142 | new float4(-1f, -1f, 1f, 1f), 143 | new float4(-1f, 1f, 1f, 1f), 144 | new float4(1f, 1f, 1f, 1f), 145 | new float4(1f, -1f, 1f, 1f), 146 | }; 147 | 148 | public static BoundingBox FromFrustum(ref float4x4 axisTransform, ref float4x4 modelViewProj) 149 | { 150 | BoundingBox ret = new BoundingBox(float.PositiveInfinity, float.NegativeInfinity); 151 | float4x4 inverse = math.inverse(modelViewProj); 152 | for (int i = 0; i < c_homogenousCorners.Length; ++i) 153 | { 154 | float4 corner = math.mul(c_homogenousCorners[i], inverse); 155 | float3 transfPt = math.transform(axisTransform, corner.xyz / corner.w); 156 | ret.UpdateMin(transfPt); 157 | ret.UpdateMax(transfPt); 158 | } 159 | return ret; 160 | } 161 | 162 | } 163 | } -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/NativeHull.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Unity.Collections.LowLevel.Unsafe; 5 | using Unity.Mathematics; 6 | using UnityEngine; 7 | using Vella.Common; 8 | 9 | namespace Vella.UnityNativeHull 10 | { 11 | public unsafe struct NativeHull : IDisposable 12 | { 13 | public int VertexCount; 14 | public int FaceCount; 15 | public int EdgeCount; 16 | 17 | // Native array is currently not Blittable because of DisposeSentinel being a class. 18 | // Which means you cannot place inside a NativeArray, which batch operations require. 19 | 20 | public NativeArrayNoLeakDetection VerticesNative; 21 | public NativeArrayNoLeakDetection FacesNative; 22 | public NativeArrayNoLeakDetection PlanesNative; 23 | public NativeArrayNoLeakDetection EdgesNative; 24 | 25 | //public NativeArray verticesNative; 26 | //public NativeArray facesNative; 27 | //public NativeArray facesPlanesNative; 28 | //public NativeArray edgesNative; 29 | 30 | [NativeDisableUnsafePtrRestriction] 31 | public float3* Vertices; 32 | 33 | [NativeDisableUnsafePtrRestriction] 34 | public NativeFace* Faces; 35 | 36 | [NativeDisableUnsafePtrRestriction] 37 | public NativePlane* Planes; 38 | 39 | [NativeDisableUnsafePtrRestriction] 40 | public NativeHalfEdge* Edges; 41 | 42 | private int _isCreated; 43 | private int _isDisposed; 44 | 45 | public bool IsCreated 46 | { 47 | get => _isCreated == 1; 48 | set => _isCreated = value ? 1 : 0; 49 | } 50 | 51 | public bool IsDisposed 52 | { 53 | get => _isDisposed == 1; 54 | set => _isDisposed = value ? 1 : 0; 55 | } 56 | 57 | public bool IsValid => IsCreated && !IsDisposed; 58 | 59 | public void Dispose() 60 | { 61 | if (_isDisposed == 0) 62 | { 63 | _isDisposed = 1; 64 | 65 | if (VerticesNative.IsCreated) 66 | VerticesNative.Dispose(); 67 | 68 | if (FacesNative.IsCreated) 69 | FacesNative.Dispose(); 70 | 71 | if (PlanesNative.IsCreated) 72 | PlanesNative.Dispose(); 73 | 74 | if (EdgesNative.IsCreated) 75 | EdgesNative.Dispose(); 76 | 77 | Vertices = null; 78 | Faces = null; 79 | Planes = null; 80 | Edges = null; 81 | } 82 | 83 | } 84 | 85 | public unsafe float3 GetVertex(int index) => VerticesNative[index]; 86 | public unsafe ref float3 GetVertexRef(int index) => ref *(Vertices + index); 87 | public unsafe float3* GetVertexPtr(int index) => Vertices + index; 88 | 89 | public unsafe NativeHalfEdge GetEdge(int index) => EdgesNative[index]; 90 | public unsafe ref NativeHalfEdge GetEdgeRef(int index) => ref *(Edges + index); 91 | public unsafe NativeHalfEdge* GetEdgePtr(int index) => Edges + index; 92 | 93 | public unsafe NativeFace GetFace(int index) => FacesNative[index]; 94 | public unsafe ref NativeFace GetFaceRef(int index) => ref *(Faces + index); 95 | public unsafe NativeFace* GetFacePtr(int index) => Faces + index; 96 | 97 | public unsafe NativePlane GetPlane(int index) => PlanesNative[index]; 98 | public unsafe ref NativePlane GetPlaneRef(int index) => ref *(Planes + index); 99 | public unsafe NativePlane* GetPlanePtr(int index) => Planes + index; 100 | 101 | public unsafe float3 GetSupport(float3 direction) 102 | { 103 | return Vertices[GetSupportIndex(direction)]; 104 | } 105 | 106 | public unsafe int GetSupportIndex(float3 direction) 107 | { 108 | int index = 0; 109 | float max = math.dot(direction, Vertices[index]); 110 | for (int i = 1; i < VertexCount; ++i) 111 | { 112 | float dot = math.dot(direction, Vertices[i]); 113 | if (dot > max) 114 | { 115 | index = i; 116 | max = dot; 117 | } 118 | } 119 | return index; 120 | } 121 | 122 | } 123 | 124 | public static class NativeHullExtensions 125 | { 126 | public static EdgeEnumerator GetEdges(this NativeHull hull) 127 | { 128 | return new EdgeEnumerator(hull); 129 | } 130 | 131 | public static EdgeEnumerator GetEdges(this NativeHull hull, int faceIndex) 132 | { 133 | return new EdgeEnumerator(hull, faceIndex); 134 | } 135 | 136 | public static IList GetVertices(this NativeHull hull, int faceIndex) 137 | { 138 | var result = new List(); 139 | foreach(var edge in GetEdges(hull, faceIndex)) 140 | { 141 | result.Add(hull.GetVertex(edge.Origin)); 142 | } 143 | return result; 144 | } 145 | 146 | public static float3 CalculateFaceCentroid(this NativeHull hull, NativeFace face) 147 | { 148 | float3 centroid = 0; 149 | int edgeCount = 0; 150 | ref NativeHalfEdge start = ref hull.GetEdgeRef(face.Edge); 151 | ref NativeHalfEdge current = ref start; 152 | do 153 | { 154 | edgeCount++; 155 | centroid += hull.GetVertex(current.Origin); 156 | current = ref hull.GetEdgeRef(current.Next); 157 | } 158 | while (current.Origin != start.Origin); 159 | return centroid / edgeCount; 160 | } 161 | 162 | } 163 | 164 | } 165 | 166 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Tests/BoxCollision.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using NUnit.Framework; 3 | using Unity.Mathematics; 4 | using UnityEngine; 5 | using UnityEngine.TestTools; 6 | using Vella.Common; 7 | using Vella.UnityNativeHull; 8 | 9 | public class BoxCollision 10 | { 11 | public const int BoxSize = 1; 12 | 13 | public static NativeHull CreateBox() => HullFactory.CreateBox(BoxSize); 14 | 15 | [Test] 16 | public void Box_CornerOnCorner() 17 | { 18 | using (var box = CreateBox()) 19 | { 20 | var insideUnitRangePosition = new float3(0.99f, 0.99f, 0.99f); 21 | var outsideUnitRangePosition = new float3(1.01f, 1.01f, 1.01f); 22 | 23 | var insideUnitRange = new RigidTransform(float3x3.identity, insideUnitRangePosition); 24 | var outsideUnitRange = new RigidTransform(float3x3.identity, outsideUnitRangePosition); 25 | 26 | Assert.IsTrue(HullCollision.IsColliding(insideUnitRange, box, RigidTransform.identity, box)); 27 | Assert.IsFalse(HullCollision.IsColliding(outsideUnitRange, box, RigidTransform.identity, box)); 28 | } 29 | } 30 | 31 | [Test] 32 | public void Box_FaceOnFace() 33 | { 34 | using (var box = CreateBox()) 35 | { 36 | var testTransform = new RigidTransform(); 37 | 38 | testTransform.pos = Vector3.down * 0.99f; 39 | Assert.IsTrue(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 40 | 41 | testTransform.pos = Vector3.down * 1.01f; 42 | Assert.IsFalse(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 43 | 44 | testTransform.pos = Vector3.up * 0.99f; 45 | Assert.IsTrue(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 46 | 47 | testTransform.pos = Vector3.up * 1.01f; 48 | Assert.IsFalse(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 49 | 50 | testTransform.pos = Vector3.back * 0.99f; 51 | Assert.IsTrue(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 52 | 53 | testTransform.pos = Vector3.back * 1.01f; 54 | Assert.IsFalse(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 55 | 56 | testTransform.pos = Vector3.forward * 0.99f; 57 | Assert.IsTrue(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 58 | 59 | testTransform.pos = Vector3.forward * 1.01f; 60 | Assert.IsFalse(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 61 | 62 | testTransform.pos = Vector3.right * 0.99f; 63 | Assert.IsTrue(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 64 | 65 | testTransform.pos = Vector3.right * 1.01f; 66 | Assert.IsFalse(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 67 | 68 | testTransform.pos = Vector3.left * 0.99f; 69 | Assert.IsTrue(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 70 | 71 | testTransform.pos = Vector3.left * 1.01f; 72 | Assert.IsFalse(HullCollision.IsColliding(testTransform, box, RigidTransform.identity, box)); 73 | } 74 | } 75 | 76 | [Test] 77 | public void Box_PointOnFace() 78 | { 79 | using (var box = CreateBox()) 80 | { 81 | HullDrawingUtility.DrawBasicHull(box, RigidTransform.identity, Color.black, 100); 82 | 83 | var rotateEveryAxis45 = Quaternion.Euler((float3)45); 84 | 85 | // up and rotated position 86 | var insideUnitBox = new RigidTransform(rotateEveryAxis45, new float3(0.2f, 1.34f, 0.1f)); 87 | var outsideUnitBox = new RigidTransform(rotateEveryAxis45, new float3(0.2f, 1.38f, 0.1f)); 88 | 89 | Assert.IsTrue(HullCollision.IsColliding(insideUnitBox, box, RigidTransform.identity, box)); 90 | Assert.IsFalse(HullCollision.IsColliding(outsideUnitBox, box, RigidTransform.identity, box)); 91 | 92 | HullDrawingUtility.DrawBasicHull(box, insideUnitBox, Color.blue, 100); 93 | HullDrawingUtility.DrawBasicHull(box, outsideUnitBox, Color.black, 100); 94 | 95 | // down and rotated position 96 | insideUnitBox = new RigidTransform(rotateEveryAxis45, new float3(0.2f, -1.34f, 0.1f)); 97 | outsideUnitBox = new RigidTransform(rotateEveryAxis45, new float3(0.2f, -1.38f, 0.1f)); 98 | 99 | Assert.IsTrue(HullCollision.IsColliding(insideUnitBox, box, RigidTransform.identity, box)); 100 | Assert.IsFalse(HullCollision.IsColliding(outsideUnitBox, box, RigidTransform.identity, box)); 101 | 102 | HullDrawingUtility.DrawBasicHull(box, insideUnitBox, Color.blue, 100); 103 | HullDrawingUtility.DrawBasicHull(box, outsideUnitBox, Color.black, 100); 104 | } 105 | } 106 | 107 | [Test] 108 | public void Box_EdgeOnEdge() 109 | { 110 | using (var box = CreateBox()) 111 | { 112 | HullDrawingUtility.DrawBasicHull(box, RigidTransform.identity, Color.black, 100); 113 | 114 | var rotateEveryAxis45 = Quaternion.Euler((float3)45); 115 | var insideUnitBox = new RigidTransform(rotateEveryAxis45, new float3(0.2f, 1.1f, -0.80f)); 116 | var outsideUnitBox = new RigidTransform(rotateEveryAxis45, new float3(0.184f, 1.123f, -0.816f)); 117 | 118 | Assert.IsTrue(HullCollision.IsColliding(insideUnitBox, box, RigidTransform.identity, box)); 119 | Assert.IsFalse(HullCollision.IsColliding(outsideUnitBox, box, RigidTransform.identity, box)); 120 | 121 | HullDrawingUtility.DrawBasicHull(box, insideUnitBox, Color.blue, 100); 122 | HullDrawingUtility.DrawBasicHull(box, outsideUnitBox, Color.black, 100); 123 | 124 | } 125 | } 126 | 127 | [Test] 128 | public void Box_EdgeSeparation() 129 | { 130 | using (var box = CreateBox()) 131 | { 132 | // These two boxes are positioned so that both face SAT checks would show no separation, 133 | // a working SAT edge test is required to catch the false positive. 134 | 135 | var boxTransformA = new RigidTransform(Quaternion.Euler(-24.357f, -4.779f, -32.115f), new float3(-0.089f, -0.821f, -2.233f)); 136 | var boxTransformB = new RigidTransform(Quaternion.Euler(55.943f, 21.207f, 47.057f), new float3(-0.207f, -0.06f, -1.256f)); 137 | 138 | Assert.IsFalse(HullCollision.IsColliding(boxTransformA, box, boxTransformB, box)); 139 | 140 | HullDrawingUtility.DrawBasicHull(box, boxTransformA, Color.blue, 100); 141 | HullDrawingUtility.DrawBasicHull(box, boxTransformB, Color.black, 100); 142 | } 143 | } 144 | 145 | 146 | } 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 5 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Very Low 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | blendWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | streamingMipmapsActive: 0 33 | streamingMipmapsAddAllCameras: 1 34 | streamingMipmapsMemoryBudget: 512 35 | streamingMipmapsRenderersPerFrame: 512 36 | streamingMipmapsMaxLevelReduction: 2 37 | streamingMipmapsMaxFileIORequests: 1024 38 | particleRaycastBudget: 4 39 | asyncUploadTimeSlice: 2 40 | asyncUploadBufferSize: 16 41 | asyncUploadPersistentBuffer: 1 42 | resolutionScalingFixedDPIFactor: 1 43 | excludedTargetPlatforms: [] 44 | - serializedVersion: 2 45 | name: Low 46 | pixelLightCount: 0 47 | shadows: 0 48 | shadowResolution: 0 49 | shadowProjection: 1 50 | shadowCascades: 1 51 | shadowDistance: 20 52 | shadowNearPlaneOffset: 3 53 | shadowCascade2Split: 0.33333334 54 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 55 | shadowmaskMode: 0 56 | blendWeights: 2 57 | textureQuality: 0 58 | anisotropicTextures: 0 59 | antiAliasing: 0 60 | softParticles: 0 61 | softVegetation: 0 62 | realtimeReflectionProbes: 0 63 | billboardsFaceCameraPosition: 0 64 | vSyncCount: 0 65 | lodBias: 0.4 66 | maximumLODLevel: 0 67 | streamingMipmapsActive: 0 68 | streamingMipmapsAddAllCameras: 1 69 | streamingMipmapsMemoryBudget: 512 70 | streamingMipmapsRenderersPerFrame: 512 71 | streamingMipmapsMaxLevelReduction: 2 72 | streamingMipmapsMaxFileIORequests: 1024 73 | particleRaycastBudget: 16 74 | asyncUploadTimeSlice: 2 75 | asyncUploadBufferSize: 16 76 | asyncUploadPersistentBuffer: 1 77 | resolutionScalingFixedDPIFactor: 1 78 | excludedTargetPlatforms: [] 79 | - serializedVersion: 2 80 | name: Medium 81 | pixelLightCount: 1 82 | shadows: 1 83 | shadowResolution: 0 84 | shadowProjection: 1 85 | shadowCascades: 1 86 | shadowDistance: 20 87 | shadowNearPlaneOffset: 3 88 | shadowCascade2Split: 0.33333334 89 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 90 | shadowmaskMode: 0 91 | blendWeights: 2 92 | textureQuality: 0 93 | anisotropicTextures: 1 94 | antiAliasing: 0 95 | softParticles: 0 96 | softVegetation: 0 97 | realtimeReflectionProbes: 0 98 | billboardsFaceCameraPosition: 0 99 | vSyncCount: 1 100 | lodBias: 0.7 101 | maximumLODLevel: 0 102 | streamingMipmapsActive: 0 103 | streamingMipmapsAddAllCameras: 1 104 | streamingMipmapsMemoryBudget: 512 105 | streamingMipmapsRenderersPerFrame: 512 106 | streamingMipmapsMaxLevelReduction: 2 107 | streamingMipmapsMaxFileIORequests: 1024 108 | particleRaycastBudget: 64 109 | asyncUploadTimeSlice: 2 110 | asyncUploadBufferSize: 16 111 | asyncUploadPersistentBuffer: 1 112 | resolutionScalingFixedDPIFactor: 1 113 | excludedTargetPlatforms: [] 114 | - serializedVersion: 2 115 | name: High 116 | pixelLightCount: 2 117 | shadows: 2 118 | shadowResolution: 1 119 | shadowProjection: 1 120 | shadowCascades: 2 121 | shadowDistance: 40 122 | shadowNearPlaneOffset: 3 123 | shadowCascade2Split: 0.33333334 124 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 125 | shadowmaskMode: 1 126 | blendWeights: 2 127 | textureQuality: 0 128 | anisotropicTextures: 1 129 | antiAliasing: 0 130 | softParticles: 0 131 | softVegetation: 1 132 | realtimeReflectionProbes: 1 133 | billboardsFaceCameraPosition: 1 134 | vSyncCount: 1 135 | lodBias: 1 136 | maximumLODLevel: 0 137 | streamingMipmapsActive: 0 138 | streamingMipmapsAddAllCameras: 1 139 | streamingMipmapsMemoryBudget: 512 140 | streamingMipmapsRenderersPerFrame: 512 141 | streamingMipmapsMaxLevelReduction: 2 142 | streamingMipmapsMaxFileIORequests: 1024 143 | particleRaycastBudget: 256 144 | asyncUploadTimeSlice: 2 145 | asyncUploadBufferSize: 16 146 | asyncUploadPersistentBuffer: 1 147 | resolutionScalingFixedDPIFactor: 1 148 | excludedTargetPlatforms: [] 149 | - serializedVersion: 2 150 | name: Very High 151 | pixelLightCount: 3 152 | shadows: 2 153 | shadowResolution: 2 154 | shadowProjection: 1 155 | shadowCascades: 2 156 | shadowDistance: 70 157 | shadowNearPlaneOffset: 3 158 | shadowCascade2Split: 0.33333334 159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 160 | shadowmaskMode: 1 161 | blendWeights: 4 162 | textureQuality: 0 163 | anisotropicTextures: 2 164 | antiAliasing: 2 165 | softParticles: 1 166 | softVegetation: 1 167 | realtimeReflectionProbes: 1 168 | billboardsFaceCameraPosition: 1 169 | vSyncCount: 1 170 | lodBias: 1.5 171 | maximumLODLevel: 0 172 | streamingMipmapsActive: 0 173 | streamingMipmapsAddAllCameras: 1 174 | streamingMipmapsMemoryBudget: 512 175 | streamingMipmapsRenderersPerFrame: 512 176 | streamingMipmapsMaxLevelReduction: 2 177 | streamingMipmapsMaxFileIORequests: 1024 178 | particleRaycastBudget: 1024 179 | asyncUploadTimeSlice: 2 180 | asyncUploadBufferSize: 16 181 | asyncUploadPersistentBuffer: 1 182 | resolutionScalingFixedDPIFactor: 1 183 | excludedTargetPlatforms: [] 184 | - serializedVersion: 2 185 | name: Ultra 186 | pixelLightCount: 4 187 | shadows: 2 188 | shadowResolution: 2 189 | shadowProjection: 1 190 | shadowCascades: 4 191 | shadowDistance: 150 192 | shadowNearPlaneOffset: 3 193 | shadowCascade2Split: 0.33333334 194 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 195 | shadowmaskMode: 1 196 | blendWeights: 4 197 | textureQuality: 0 198 | anisotropicTextures: 2 199 | antiAliasing: 2 200 | softParticles: 1 201 | softVegetation: 1 202 | realtimeReflectionProbes: 1 203 | billboardsFaceCameraPosition: 1 204 | vSyncCount: 1 205 | lodBias: 2 206 | maximumLODLevel: 0 207 | streamingMipmapsActive: 0 208 | streamingMipmapsAddAllCameras: 1 209 | streamingMipmapsMemoryBudget: 512 210 | streamingMipmapsRenderersPerFrame: 512 211 | streamingMipmapsMaxLevelReduction: 2 212 | streamingMipmapsMaxFileIORequests: 1024 213 | particleRaycastBudget: 4096 214 | asyncUploadTimeSlice: 2 215 | asyncUploadBufferSize: 16 216 | asyncUploadPersistentBuffer: 1 217 | resolutionScalingFixedDPIFactor: 1 218 | excludedTargetPlatforms: [] 219 | m_PerPlatformDefaultQuality: 220 | Android: 2 221 | Lumin: 5 222 | Nintendo 3DS: 5 223 | Nintendo Switch: 5 224 | PS4: 5 225 | PSP2: 2 226 | Standalone: 5 227 | WebGL: 3 228 | Windows Store Apps: 5 229 | XboxOne: 5 230 | iPhone: 2 231 | tvOS: 2 232 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/BvhTester.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Unity.Mathematics; 3 | using UnityEngine; 4 | using System.Linq; 5 | using System; 6 | using Unity.Collections.LowLevel.Unsafe; 7 | using Vella.Common; 8 | using Vella.UnityNativeHull; 9 | using BoundingSphere = Vella.Common.BoundingSphere; 10 | using Debug = UnityEngine.Debug; 11 | #if UNITY_EDITOR 12 | using UnityEditor; 13 | #endif 14 | 15 | [ExecuteInEditMode] 16 | public class BvhTester : MonoBehaviour 17 | { 18 | public List Transforms; 19 | 20 | private Dictionary _currentShapes; 21 | 22 | private NativeBoundingHierarchy _bvh; 23 | 24 | public bool ShouldRemoveClones { get; set; } = false; 25 | 26 | void Update() 27 | { 28 | CheckInputForChanges(Transforms); 29 | 30 | UpdateChangedTransforms(); 31 | 32 | DrawBvh(); 33 | 34 | ProcessEditorActions(); 35 | } 36 | 37 | private void ProcessEditorActions() 38 | { 39 | if (ShouldRemoveClones) 40 | { 41 | ShouldRemoveClones = false; 42 | RemoveClones(); 43 | 44 | } 45 | } 46 | 47 | private void CheckInputForChanges(IList transforms) 48 | { 49 | if (transforms.Count != _currentShapes?.Count || transforms.Any(t => !_currentShapes.ContainsKey(t.GetInstanceID()))) 50 | { 51 | RebuildBvh(); 52 | } 53 | } 54 | 55 | private void RebuildBvh() 56 | { 57 | EnsureDestroyed(); 58 | 59 | _bvh?.Dispose(); 60 | _bvh = new NativeBoundingHierarchy(); 61 | _currentShapes = new Dictionary(); 62 | 63 | foreach (var t in Transforms.Where(t => t != null)) 64 | { 65 | var shape = CreateShape(t); 66 | var key = t.GetInstanceID(); 67 | _currentShapes.Add(key, (shape, t.gameObject)); 68 | _bvh.Add(shape); 69 | } 70 | 71 | Debug.Log("Rebuild Complete"); 72 | } 73 | 74 | private void DrawBvh() 75 | { 76 | _bvh.TraverseNodes(node => 77 | { 78 | DebugDrawer.DrawWireCube(node.Box.Center(), node.Box.Size(), UnityColors.LightSlateGray.ToOpacity(0.6f)); 79 | return true; 80 | }); 81 | } 82 | 83 | private void UpdateChangedTransforms() 84 | { 85 | foreach (var t in Transforms) 86 | { 87 | if (t == null) 88 | continue; 89 | 90 | var id = t.GetInstanceID(); 91 | 92 | for (int i = 0; i < _bvh.Buckets.Length; i++) 93 | { 94 | ref NativeBuffer bucket = ref _bvh.Buckets[i]; 95 | if (!bucket.IsCreated) 96 | continue; 97 | 98 | for (int j = 0; j < bucket.Length; j++) 99 | { 100 | ref TestShape shape = ref bucket[j]; 101 | if (shape.Id == id) 102 | { 103 | if (t.hasChanged && (Vector3)shape.Transform.pos != t.position) 104 | { 105 | shape.Transform = new RigidTransform(t.rotation, t.position); 106 | 107 | shape.OnTransformChanged(); 108 | 109 | _bvh.QueueForOptimize(shape); 110 | } 111 | shape.OnUpdate(); 112 | } 113 | } 114 | } 115 | } 116 | _bvh.Optimize(); 117 | } 118 | 119 | private TestShape CreateShape(Transform t) 120 | { 121 | var c = t.GetComponent(); 122 | if (c == null) 123 | throw new ArgumentException("BvHTester requires GameObjects to have a collider"); 124 | 125 | var bounds = new BoundingBox(c.bounds.min,c.bounds.max); 126 | var sphere = BoundingSphere.FromAABB(bounds); 127 | return new TestShape 128 | { 129 | BoundingBox = bounds, 130 | BoundingSphere = sphere, 131 | Id = t.GetInstanceID(), 132 | Transform = new RigidTransform(t.rotation, t.position), 133 | }; 134 | 135 | } 136 | 137 | private NativeHull CreateHull(Transform v) 138 | { 139 | var collider = v.GetComponent(); 140 | if (collider is BoxCollider boxCollider) 141 | { 142 | return HullFactory.CreateBox(boxCollider.size); 143 | } 144 | if(collider is MeshCollider meshCollider) 145 | { 146 | return HullFactory.CreateFromMesh(meshCollider.sharedMesh); 147 | } 148 | var mf = v.GetComponent(); 149 | if(mf != null && mf.sharedMesh != null) 150 | { 151 | return HullFactory.CreateFromMesh(mf.sharedMesh); 152 | } 153 | throw new InvalidOperationException($"Unable to create a hull from the GameObject '{v?.name}'"); 154 | } 155 | 156 | void OnEnable() 157 | { 158 | #if UNITY_EDITOR 159 | EditorApplication.playModeStateChanged += EditorApplication_playModeStateChanged; 160 | #endif 161 | } 162 | 163 | #if UNITY_EDITOR 164 | private void EditorApplication_playModeStateChanged(PlayModeStateChange state) 165 | { 166 | switch (state) 167 | { 168 | case PlayModeStateChange.ExitingEditMode: 169 | case PlayModeStateChange.ExitingPlayMode: 170 | EnsureDestroyed(); 171 | break; 172 | } 173 | } 174 | #endif 175 | 176 | void OnDestroy() => EnsureDestroyed(); 177 | void OnDisable() => EnsureDestroyed(); 178 | 179 | 180 | private void EnsureDestroyed() 181 | { 182 | _bvh?.Dispose(); 183 | } 184 | 185 | public void AddRandomGameObject() 186 | { 187 | var first = Transforms.FirstOrDefault(); 188 | if (first != null) 189 | { 190 | var go = Instantiate(first.gameObject); 191 | go.transform.position = UnityEngine.Random.insideUnitSphere * 10f; 192 | Transforms.Add(go.transform); 193 | var id = go.transform.GetInstanceID(); 194 | var shape = CreateShape(go.transform); 195 | _currentShapes.Add(id, (shape, go)); 196 | _bvh.Add(shape); 197 | } 198 | } 199 | 200 | //public void RemoveSingle() 201 | //{ 202 | // var first = Transforms.FirstOrDefault(t => t != null && t.name.ToLowerInvariant().Contains("clone")); 203 | // if (first != null) 204 | // { 205 | // Transforms.Remove(first); 206 | // DestroyImmediate(first.gameObject); 207 | // } 208 | //} 209 | 210 | public void RemoveClones() 211 | { 212 | foreach (var t in FindObjectsOfType().Where(t => t != null).ToList()) 213 | { 214 | if (t.name.ToLowerInvariant().Contains("clone")) 215 | { 216 | RemoveShape(t.GetInstanceID()); 217 | Transforms.Remove(t); 218 | DestroyImmediate(t.gameObject); 219 | } 220 | } 221 | } 222 | 223 | public void RemoveShape(int id) 224 | { 225 | if (_currentShapes.TryGetValue(id, out (TestShape Shape, GameObject Go) pair)) 226 | { 227 | Debug.Log($"Removing {pair.Go.name} from bvh"); 228 | _bvh.Remove(pair.Shape); 229 | _currentShapes.Remove(id); 230 | } 231 | } 232 | } 233 | 234 | #if UNITY_EDITOR 235 | 236 | [CustomEditor(typeof(BvhTester))] 237 | [CanEditMultipleObjects] 238 | public class BvhTesterEditor : Editor 239 | { 240 | public override void OnInspectorGUI() 241 | { 242 | DrawDefaultInspector(); 243 | 244 | foreach (var targ in targets.Cast()) 245 | { 246 | if (GUILayout.Button("Add Clone")) 247 | { 248 | targ.AddRandomGameObject(); 249 | } 250 | else if (GUILayout.Button("Remove Clones")) 251 | { 252 | targ.RemoveClones(); 253 | } 254 | SceneView.RepaintAll(); 255 | } 256 | } 257 | } 258 | 259 | #endif 260 | 261 | 262 | -------------------------------------------------------------------------------- /UnityNativeCollision/ProjectSettings/ProBuilderSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "m_Dictionary": { 3 | "m_DictionaryValues": [ 4 | { 5 | "type": "UnityEngine.ProBuilder.LogLevel, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 6 | "key": "log.level", 7 | "value": "{\"m_Value\":3}" 8 | }, 9 | { 10 | "type": "UnityEngine.ProBuilder.LogOutput, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 11 | "key": "log.output", 12 | "value": "{\"m_Value\":1}" 13 | }, 14 | { 15 | "type": "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 16 | "key": "log.path", 17 | "value": "{\"m_Value\":\"ProBuilderLog.txt\"}" 18 | }, 19 | { 20 | "type": "UnityEngine.ProBuilder.SemVer, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 21 | "key": "about.identifier", 22 | "value": "{\"m_Value\":{\"m_Major\":4,\"m_Minor\":0,\"m_Patch\":3,\"m_Build\":-1,\"m_Type\":\"\",\"m_Metadata\":\"\",\"m_Date\":\"2019/01/25\"}}" 23 | }, 24 | { 25 | "type": "UnityEngine.ProBuilder.SemVer, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 26 | "key": "preferences.version", 27 | "value": "{\"m_Value\":{\"m_Major\":4,\"m_Minor\":0,\"m_Patch\":3,\"m_Build\":-1,\"m_Type\":\"\",\"m_Metadata\":\"\",\"m_Date\":\"2019/01/25\"}}" 28 | }, 29 | { 30 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 31 | "key": "entity.detailVisible", 32 | "value": "{\"m_Value\":true}" 33 | }, 34 | { 35 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 36 | "key": "entity.moverVisible", 37 | "value": "{\"m_Value\":true}" 38 | }, 39 | { 40 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 41 | "key": "experimental.meshesAreAssets", 42 | "value": "{\"m_Value\":false}" 43 | }, 44 | { 45 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 46 | "key": "editor.toolbarIconGUI", 47 | "value": "{\"m_Value\":false}" 48 | }, 49 | { 50 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 51 | "key": "lightmapping.autoUnwrapLightmapUV", 52 | "value": "{\"m_Value\":true}" 53 | }, 54 | { 55 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 56 | "key": "editor.autoRecalculateCollisions", 57 | "value": "{\"m_Value\":false}" 58 | }, 59 | { 60 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 61 | "key": "UnityEngine.ProBuilder.ProBuilderEditor-isUtilityWindow", 62 | "value": "{\"m_Value\":false}" 63 | }, 64 | { 65 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 66 | "key": "editor.backFaceSelectEnabled", 67 | "value": "{\"m_Value\":false}" 68 | }, 69 | { 70 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 71 | "key": "editor.showSceneInfo", 72 | "value": "{\"m_Value\":false}" 73 | }, 74 | { 75 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 76 | "key": "mesh.newShapesSnapToGrid", 77 | "value": "{\"m_Value\":true}" 78 | }, 79 | { 80 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 81 | "key": "mesh.meshColliderIsConvex", 82 | "value": "{\"m_Value\":false}" 83 | }, 84 | { 85 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 86 | "key": "editor.closeWindowAfterShapeCreation", 87 | "value": "{\"m_Value\":false}" 88 | }, 89 | { 90 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 91 | "key": "editor.showEditorNotifications", 92 | "value": "{\"m_Value\":false}" 93 | }, 94 | { 95 | "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 96 | "key": "FillHole.selectEntirePath", 97 | "value": "{\"m_Value\":true}" 98 | }, 99 | { 100 | "type": "UnityEngine.ProBuilder.SelectionModifierBehavior, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 101 | "key": "editor.rectSelectModifier", 102 | "value": "{\"m_Value\":2}" 103 | }, 104 | { 105 | "type": "UnityEngine.ProBuilder.RectSelectMode, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 106 | "key": "editor.dragSelectRectMode", 107 | "value": "{\"m_Value\":0}" 108 | }, 109 | { 110 | "type": "UnityEngine.ProBuilder.Shortcut[], Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 111 | "key": "editor.sceneViewShortcuts", 112 | "value": "{}" 113 | }, 114 | { 115 | "type": "UnityEngine.ProBuilder.SelectMode, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 116 | "key": "editor.selectMode", 117 | "value": "{\"m_Value\":1}" 118 | }, 119 | { 120 | "type": "UnityEngine.ProBuilder.PivotLocation, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 121 | "key": "mesh.newShapePivotLocation", 122 | "value": "{\"m_Value\":1}" 123 | }, 124 | { 125 | "type": "UnityEngine.Rendering.ShadowCastingMode, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 126 | "key": "mesh.shadowCastingMode", 127 | "value": "{\"m_Value\":1}" 128 | }, 129 | { 130 | "type": "UnityEngine.Material, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 131 | "key": "mesh.userMaterial", 132 | "value": "{\"m_Value\":{\"instanceID\":0}}" 133 | }, 134 | { 135 | "type": "UnityEditor.StaticEditorFlags, UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 136 | "key": "mesh.defaultStaticEditorFlags", 137 | "value": "{\"m_Value\":0}" 138 | }, 139 | { 140 | "type": "UnityEngine.ProBuilder.ColliderType, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 141 | "key": "mesh.newShapeColliderType", 142 | "value": "{\"m_Value\":2}" 143 | }, 144 | { 145 | "type": "UnityEngine.ProBuilder.UnwrapParameters, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 146 | "key": "lightmapping.defaultLightmapUnwrapParameters", 147 | "value": "{\"m_Value\":{\"m_HardAngle\":88.0,\"m_PackMargin\":20.0,\"m_AngleError\":8.0,\"m_AreaError\":15.0}}" 148 | } 149 | ] 150 | } 151 | } -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullDrawingUtility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Unity.Mathematics; 5 | using UnityEngine; 6 | using Vella.Common; 7 | 8 | #if UNITY_EDITOR 9 | using UnityEditor; 10 | #endif 11 | 12 | namespace Vella.UnityNativeHull 13 | { 14 | [Flags] 15 | public enum DebugHullFlags 16 | { 17 | None = 0, 18 | Unused = 2, 19 | EdgeLinks = 4, 20 | PlaneNormals = 8, 21 | FaceWinding = 16, 22 | ExplodeFaces = 32, 23 | Indices = 64, 24 | Outline = 128, 25 | All = ~0, 26 | } 27 | 28 | #if UNITY_EDITOR 29 | /// 30 | /// Flags enum dropdown GUI for selecting properties in the inspector 31 | /// 32 | [CustomPropertyDrawer(typeof(DebugHullFlags))] 33 | public class NavMeshAreasDrawer : PropertyDrawer 34 | { 35 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 36 | { 37 | label = EditorGUI.BeginProperty(position, label, property); 38 | var oldValue = (Enum)fieldInfo.GetValue(property.serializedObject.targetObject); 39 | var newValue = EditorGUI.EnumFlagsField(position, label, oldValue); 40 | if (!newValue.Equals(oldValue)) 41 | { 42 | property.intValue = (int)Convert.ChangeType(newValue, fieldInfo.FieldType); 43 | } 44 | EditorGUI.EndProperty(); 45 | } 46 | } 47 | #endif 48 | 49 | public class HullDrawingUtility 50 | { 51 | public static void DrawBasicHull(NativeHull hull1, RigidTransform t, Color? color = null, int duration = 1) 52 | { 53 | if (!hull1.IsValid) 54 | throw new ArgumentException("Hull is not valid", nameof(hull1)); 55 | 56 | if (!color.HasValue) 57 | { 58 | color = UnityColors.Blue; 59 | } 60 | foreach (var edge in hull1.GetEdges()) 61 | { 62 | var a = math.transform(t, hull1.GetVertex(edge.Origin)); 63 | var b = math.transform(t, hull1.GetVertex(hull1.GetEdge(edge.Twin).Origin)); 64 | Debug.DrawLine(a, b, color.Value); 65 | } 66 | } 67 | 68 | public static void DrawDebugHull(NativeHull hull, RigidTransform t, DebugHullFlags options = DebugHullFlags.All, Color BaseColor = default) 69 | { 70 | if (!hull.IsValid) 71 | throw new ArgumentException("Hull is not valid", nameof(hull)); 72 | 73 | if (options == DebugHullFlags.None) 74 | return; 75 | 76 | if (BaseColor == default) 77 | BaseColor = Color.yellow; 78 | 79 | float faceExplosionDistance = (options & DebugHullFlags.ExplodeFaces) != 0 ? 0.3f : 0; 80 | 81 | // Iterate each twin pair at the same time. 82 | for (int j = 0; j < hull.EdgeCount; j = j + 2) 83 | { 84 | var edge = hull.GetEdge(j); 85 | var twin = hull.GetEdge(j + 1); 86 | 87 | var edgePlane = edge.Face != -1 ? hull.GetPlane(edge.Face) : new NativePlane(); 88 | var twinPlane = twin.Face != -1 ? hull.GetPlane(twin.Face) : new NativePlane(); 89 | 90 | var rotatedEdgeNormal = math.rotate(t, edgePlane.Normal); 91 | var rotatedTwinNormal = math.rotate(t, twinPlane.Normal); 92 | 93 | var edgeVertex1 = math.transform(t, hull.GetVertex(edge.Origin)); 94 | var twinVertex1 = math.transform(t, hull.GetVertex(twin.Origin)); 95 | var edgeVertex2 = math.transform(t, hull.GetVertex(edge.Origin)); 96 | var twinVertex2 = math.transform(t, hull.GetVertex(twin.Origin)); 97 | 98 | if ((options & DebugHullFlags.Outline) != 0) 99 | { 100 | Debug.DrawLine(edgeVertex1 + rotatedEdgeNormal * faceExplosionDistance, twinVertex1 + rotatedEdgeNormal * faceExplosionDistance, BaseColor); 101 | Debug.DrawLine(edgeVertex2 + rotatedTwinNormal * faceExplosionDistance, twinVertex2 + rotatedTwinNormal * faceExplosionDistance, BaseColor); 102 | } 103 | 104 | if ((options & DebugHullFlags.EdgeLinks) != 0) 105 | { 106 | Debug.DrawLine((edgeVertex1 + twinVertex1) / 2 + rotatedEdgeNormal * faceExplosionDistance, (edgeVertex2 + twinVertex2) / 2 + rotatedTwinNormal * faceExplosionDistance, Color.gray); 107 | } 108 | } 109 | 110 | if ((options & DebugHullFlags.PlaneNormals) != 0) 111 | { 112 | for (int i = 0; i < hull.FaceCount; i++) 113 | { 114 | var centroid = math.transform(t, hull.CalculateFaceCentroid(hull.GetFace(i))); 115 | var normal = math.rotate(t, hull.GetPlane(i).Normal); 116 | DebugDrawer.DrawArrow(centroid, normal * 0.2f, BaseColor); 117 | } 118 | } 119 | 120 | if ((options & DebugHullFlags.Indices) != 0) 121 | { 122 | var dupeCheck = new HashSet(); 123 | for (int i = 0; i < hull.VertexCount; i++) 124 | { 125 | // Offset the label if multiple verts are on the same position. 126 | var v = math.transform(t, hull.GetVertex(i)); 127 | var offset = dupeCheck.Contains(v) ? (float3)Vector3.forward * 0.05f : 0; 128 | 129 | DebugDrawer.DrawLabel(v + offset, i.ToString()); 130 | dupeCheck.Add(v); 131 | } 132 | } 133 | 134 | if ((options & DebugHullFlags.FaceWinding) != 0) 135 | { 136 | for (int i = 0; i < hull.FaceCount; i++) 137 | { 138 | var face = hull.GetFace(i); 139 | var plane = hull.GetPlane(i); 140 | var tPlane = t * plane; 141 | var edge = hull.GetEdge(face.Edge); 142 | var startOrigin = edge.Origin; 143 | 144 | do 145 | { 146 | var nextEdge = hull.GetEdge(edge.Next); 147 | var startVert = math.transform(t, hull.GetVertex(edge.Origin)); 148 | var endVert = math.transform(t, hull.GetVertex(nextEdge.Origin)); 149 | 150 | var center = (endVert + startVert) / 2; 151 | var dir = math.normalize(endVert - startVert); 152 | 153 | var insetDir = math.normalize(math.cross(tPlane.Normal, dir)); 154 | 155 | if ((options & DebugHullFlags.ExplodeFaces) != 0) 156 | { 157 | DebugDrawer.DrawArrow(center + tPlane.Normal * faceExplosionDistance, dir * 0.2f, Color.black); 158 | } 159 | else 160 | { 161 | DebugDrawer.DrawArrow(center + tPlane.Normal * faceExplosionDistance + insetDir * 0.1f, dir * 0.2f, Color.black); 162 | } 163 | 164 | edge = nextEdge; 165 | 166 | } while (edge.Origin != startOrigin); 167 | } 168 | } 169 | } 170 | 171 | public static void DrawEdge(int i, RigidTransform t1, NativeHull hull1, Color? color = null) 172 | { 173 | if(i > 0 && i < hull1.EdgeCount-1) 174 | { 175 | ref var localEdge = ref hull1.GetEdgeRef(i); 176 | ref var twinEdge = ref hull1.GetEdgeRef(localEdge.Twin); 177 | 178 | if (localEdge.Origin < 0 || localEdge.Origin >= hull1.VertexCount) 179 | { 180 | //Debug.LogError($"Invalid edge vertex Index {localEdge.Origin}"); 181 | return; 182 | } 183 | 184 | if (twinEdge.Origin < 0 || twinEdge.Origin >= hull1.VertexCount) 185 | { 186 | //Debug.LogError($"Invalid twin vertex Index {localEdge.Twin}"); 187 | return; 188 | } 189 | 190 | 191 | var v1 = math.transform(t1, hull1.GetVertex(localEdge.Origin)); 192 | var v2 = math.transform(t1, hull1.GetVertex(twinEdge.Origin)); 193 | 194 | DebugDrawer.DrawLine(v1, v2, color ?? DebugDrawer.DefaultColor); 195 | } 196 | } 197 | 198 | public static void DrawFaceWithOutline(int faceIndex, RigidTransform t, NativeHull hull, Color fillColor, Color? outlineColor = null) 199 | { 200 | var verts = hull.GetVertices(faceIndex).Select(cp => (Vector3)cp).ToArray(); 201 | var tVerts = new List(); 202 | for (int i = 0; i < verts.Length; i++) 203 | { 204 | var v = math.transform(t, verts[i]); 205 | tVerts.Add(v); 206 | var nextIndex = i + 1 < verts.Length ? i + 1 : 0; 207 | var next = math.transform(t, verts[nextIndex]); 208 | Debug.DrawLine(v, next, outlineColor ?? fillColor); 209 | } 210 | DebugDrawer.DrawAAConvexPolygon(tVerts.ToArray(), fillColor); 211 | } 212 | 213 | public static void DebugDrawManifold(NativeManifold manifold, Color color = default) 214 | { 215 | if (!manifold.IsCreated || manifold.Length == 0) 216 | return; 217 | 218 | if (color == default) 219 | color = UnityColors.Blue.ToOpacity(0.3f); 220 | 221 | for (int i = 0; i < manifold.Length; i++) 222 | { 223 | var start = manifold[i]; 224 | if (manifold.Length >= 2) 225 | { 226 | var end = i > 0 ? manifold[i - 1] : manifold[manifold.Length - 1]; 227 | Debug.DrawLine(start.Position, end.Position, color); 228 | } 229 | DebugDrawer.DrawSphere(start.Position, 0.02f, color.ToOpacity(0.8f)); 230 | } 231 | DebugDrawer.DrawAAConvexPolygon(manifold.ToArray().Select(cp => (Vector3)cp.Position).ToArray(), color); 232 | } 233 | 234 | } 235 | 236 | 237 | } 238 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.UnityNativeHull/Runtime/HullCollision.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is provided 'as-is', without any express or implied 3 | * warranty. In no event will the authors be held liable for any damages 4 | * arising from the use of this software. 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely, subject to the following restrictions: 8 | * 1. The origin of this software must not be misrepresented; you must not 9 | * claim that you wrote the original software. If you use this software 10 | * in a product, an acknowledgment in the product documentation would be 11 | * appreciated but is not required. 12 | * 2. Altered source versions must be plainly marked as such, and must not be 13 | * misrepresented as being the original software. 14 | * 3. This notice may not be removed or altered from any source distribution. 15 | * https://en.wikipedia.org/wiki/Zlib_License 16 | */ 17 | 18 | /* Acknowledgments: 19 | * This work is derived from BounceLite by Irlan Robson (zLib License): 20 | * https://github.com/irlanrobson/bounce_lite 21 | * The optimized SAT and clipping is based on the 2013 GDC presentation by Dirk Gregorius 22 | * and his forum posts about Valve's Rubikon physics engine: 23 | * https://www.gdcvault.com/play/1017646/Physics-for-Game-Programmers-The 24 | * https://www.gamedev.net/forums/topic/692141-collision-detection-why-gjk/?do=findComment&comment=5356490 25 | * http://www.gamedev.net/topic/667499-3d-sat-problem/ 26 | */ 27 | 28 | using System; 29 | using System.Linq; 30 | using Unity.Collections; 31 | using Unity.Mathematics; 32 | using UnityEngine; 33 | using Vella.Common; 34 | using Debug = UnityEngine.Debug; 35 | 36 | namespace Vella.UnityNativeHull 37 | { 38 | public struct FaceQueryResult 39 | { 40 | public int Index; 41 | public float Distance; 42 | }; 43 | 44 | public struct EdgeQueryResult 45 | { 46 | public int Index1; 47 | public int Index2; 48 | public float Distance; 49 | }; 50 | 51 | public struct CollisionInfo 52 | { 53 | public bool IsColliding; 54 | public FaceQueryResult Face1; 55 | public FaceQueryResult Face2; 56 | public EdgeQueryResult Edge; 57 | } 58 | 59 | public class HullCollision 60 | { 61 | public static bool IsColliding(RigidTransform transform1, NativeHull hull1, RigidTransform transform2, NativeHull hull2) 62 | { 63 | FaceQueryResult faceQuery; 64 | 65 | QueryFaceDistance(out faceQuery, transform1, hull1, transform2, hull2); 66 | if (faceQuery.Distance > 0) 67 | return false; 68 | 69 | QueryFaceDistance(out faceQuery, transform2, hull2, transform1, hull1); 70 | if (faceQuery.Distance > 0) 71 | return false; 72 | 73 | QueryEdgeDistance(out EdgeQueryResult edgeQuery, transform1, hull1, transform2, hull2); 74 | if (edgeQuery.Distance > 0) 75 | return false; 76 | 77 | return true; 78 | } 79 | 80 | public static CollisionInfo GetDebugCollisionInfo(RigidTransform transform1, NativeHull hull1, RigidTransform transform2, NativeHull hull2) 81 | { 82 | CollisionInfo result = default; 83 | QueryFaceDistance(out result.Face1, transform1, hull1, transform2, hull2); 84 | QueryFaceDistance(out result.Face2, transform2, hull2, transform1, hull1); 85 | QueryEdgeDistance(out result.Edge, transform1, hull1, transform2, hull2); 86 | result.IsColliding = result.Face1.Distance < 0 && result.Face2.Distance < 0 && result.Edge.Distance < 0; 87 | return result; 88 | } 89 | 90 | public static unsafe void QueryFaceDistance(out FaceQueryResult result, RigidTransform transform1, NativeHull hull1, RigidTransform transform2, NativeHull hull2) 91 | { 92 | // Perform computations in the local space of the second hull. 93 | RigidTransform transform = math.mul(math.inverse(transform2), transform1); 94 | 95 | result.Distance = -float.MaxValue; 96 | result.Index = -1; 97 | 98 | for (int i = 0; i < hull1.FaceCount; ++i) 99 | { 100 | NativePlane plane = transform * hull1.GetPlane(i); 101 | float3 support = hull2.GetSupport(-plane.Normal); 102 | float distance = plane.Distance(support); 103 | 104 | if (distance > result.Distance) 105 | { 106 | result.Distance = distance; 107 | result.Index = i; 108 | } 109 | } 110 | } 111 | 112 | public static unsafe void QueryEdgeDistance(out EdgeQueryResult result, RigidTransform transform1, NativeHull hull1, RigidTransform transform2, NativeHull hull2) 113 | { 114 | // Perform computations in the local space of the second hull. 115 | RigidTransform transform = math.mul(math.inverse(transform2), transform1); 116 | 117 | float3 C1 = transform.pos; 118 | 119 | result.Distance = -float.MaxValue; 120 | result.Index1 = -1; 121 | result.Index2 = -1; 122 | 123 | for (int i = 0; i < hull1.EdgeCount; i += 2) 124 | { 125 | NativeHalfEdge* edge1 = hull1.GetEdgePtr(i); 126 | NativeHalfEdge* twin1 = hull1.GetEdgePtr(i + 1); 127 | 128 | Debug.Assert(edge1->Twin == i + 1 && twin1->Twin == i); 129 | 130 | float3 P1 = math.transform(transform, hull1.GetVertex(edge1->Origin)); 131 | float3 Q1 = math.transform(transform, hull1.GetVertex(twin1->Origin)); 132 | float3 E1 = Q1 - P1; 133 | 134 | float3 U1 = math.rotate(transform, hull1.GetPlane(edge1->Face).Normal); 135 | float3 V1 = math.rotate(transform, hull1.GetPlane(twin1->Face).Normal); 136 | 137 | for (int j = 0; j < hull2.EdgeCount; j += 2) 138 | { 139 | NativeHalfEdge* edge2 = hull2.GetEdgePtr(j); 140 | NativeHalfEdge* twin2 = hull2.GetEdgePtr(j + 1); 141 | 142 | Debug.Assert(edge2->Twin == j + 1 && twin2->Twin == j); 143 | 144 | float3 P2 = hull2.GetVertex(edge2->Origin); 145 | float3 Q2 = hull2.GetVertex(twin2->Origin); 146 | float3 E2 = Q2 - P2; 147 | 148 | float3 U2 = hull2.GetPlane(edge2->Face).Normal; 149 | float3 V2 = hull2.GetPlane(twin2->Face).Normal; 150 | 151 | if (IsMinkowskiFace(U1, V1, -E1, -U2, -V2, -E2)) 152 | { 153 | float distance = Project(P1, E1, P2, E2, C1); 154 | if (distance > result.Distance) 155 | { 156 | result.Index1 = i; 157 | result.Index2 = j; 158 | result.Distance = distance; 159 | } 160 | } 161 | } 162 | } 163 | } 164 | 165 | 166 | public static bool IsMinkowskiFace(float3 A, float3 B, float3 B_x_A, float3 C, float3 D, float3 D_x_C) 167 | { 168 | // If an edge pair doesn't build a face on the MD then it isn't a supporting edge. 169 | 170 | // Test if arcs AB and CD intersect on the unit sphere 171 | float CBA = math.dot(C, B_x_A); 172 | float DBA = math.dot(D, B_x_A); 173 | float ADC = math.dot(A, D_x_C); 174 | float BDC = math.dot(B, D_x_C); 175 | 176 | return CBA * DBA < 0 && 177 | ADC * BDC < 0 && 178 | CBA * BDC > 0; 179 | } 180 | 181 | public static float Project(float3 P1, float3 E1, float3 P2, float3 E2, float3 C1) 182 | { 183 | // The given edge pair must create a face on the MD. 184 | 185 | // Compute search direction. 186 | float3 E1_x_E2 = math.cross(E1, E2); 187 | 188 | // Skip if the edges are significantly parallel to each other. 189 | float kTol = 0.005f; 190 | float L = math.length(E1_x_E2); 191 | if (L < kTol * math.sqrt(math.lengthsq(E1) * math.lengthsq(E2))) 192 | { 193 | return -float.MaxValue; 194 | } 195 | 196 | // Assure the normal points from hull1 to hull2. 197 | float3 N = (1 / L) * E1_x_E2; 198 | if (math.dot(N, P1 - C1) < 0) 199 | { 200 | N = -N; 201 | } 202 | 203 | // Return the signed distance. 204 | return math.dot(N, P2 - P1); 205 | } 206 | 207 | /// 208 | /// Determines if a world point is contained within a hull 209 | /// 210 | public static bool Contains(RigidTransform t, NativeHull hull, float3 point) 211 | { 212 | float maxDistance = -float.MaxValue; 213 | for (int i = 0; i < hull.FaceCount; ++i) 214 | { 215 | NativePlane plane = t * hull.GetPlane(i); 216 | float d = plane.Distance(point); 217 | if (d > maxDistance) 218 | { 219 | maxDistance = d; 220 | } 221 | } 222 | return maxDistance < 0; 223 | } 224 | 225 | /// 226 | /// Finds the point on the surface of a hull closest to a world point. 227 | /// 228 | public static float3 ClosestPoint(RigidTransform t, NativeHull hull, float3 point) 229 | { 230 | float distance = -float.MaxValue; 231 | int closestFaceIndex = -1; 232 | NativePlane closestPlane = default; 233 | 234 | // Find the closest face plane. 235 | for (int i = 0; i < hull.FaceCount; ++i) 236 | { 237 | NativePlane plane = t * hull.GetPlane(i); 238 | float d = plane.Distance(point); 239 | if (d > distance) 240 | { 241 | distance = d; 242 | closestFaceIndex = i; 243 | closestPlane = plane; 244 | } 245 | } 246 | 247 | var closestPlanePoint = closestPlane.ClosestPoint(point); 248 | if (distance > 0) 249 | { 250 | // Use a point along the closest edge if the plane point would be outside the face bounds. 251 | ref NativeFace face = ref hull.GetFaceRef(closestFaceIndex); 252 | ref NativeHalfEdge start = ref hull.GetEdgeRef(face.Edge); 253 | ref NativeHalfEdge current = ref start; 254 | do 255 | { 256 | var v1 = math.transform(t, hull.GetVertex(current.Origin)); 257 | var v2 = math.transform(t, hull.GetVertex(hull.GetEdge(current.Twin).Origin)); 258 | 259 | var signedDistance = math.dot(math.cross(v2, v1), closestPlanePoint); 260 | if (signedDistance < 0) 261 | { 262 | return MathUtility.ProjectPointOnLineSegment(v1, v2, point); 263 | } 264 | current = ref hull.GetEdgeRef(current.Next); 265 | } 266 | while (current.Origin != start.Origin); 267 | } 268 | return closestPlanePoint; 269 | } 270 | } 271 | 272 | } -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/BurstFunction.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections.LowLevel.Unsafe; 3 | using Unity.Jobs; 4 | 5 | namespace Vella.Common 6 | { 7 | public interface IBurstOperation 8 | { 9 | 10 | } 11 | 12 | public interface IBurstFunction : IBurstOperation 13 | { 14 | TResult Execute(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); 15 | } 16 | 17 | public interface IBurstFunction : IBurstOperation 18 | { 19 | TResult Execute(T1 arg1, T2 arg2, T3 arg3, T4 arg4); 20 | } 21 | 22 | public interface IBurstFunction : IBurstOperation 23 | { 24 | TResult Execute(T1 arg1, T2 arg2, T3 arg3); 25 | } 26 | 27 | public interface IBurstFunction : IBurstOperation 28 | { 29 | TResult Execute(T1 arg1, T2 arg2); 30 | } 31 | 32 | public interface IBurstFunction : IBurstOperation 33 | { 34 | TResult Execute(T1 arg1); 35 | } 36 | 37 | public interface IBurstFunction : IBurstOperation 38 | { 39 | TResult Execute(); 40 | } 41 | 42 | [BurstCompile] 43 | public struct BurstFunction : IJob 44 | where TFunc : struct, IBurstFunction 45 | where T1 : struct 46 | where T2 : struct 47 | where T3 : struct 48 | where T4 : struct 49 | where T5 : struct 50 | where TResult : struct 51 | { 52 | [NativeDisableUnsafePtrRestriction] 53 | public unsafe void* FunctionPtr; 54 | [NativeDisableUnsafePtrRestriction] 55 | public unsafe void* Argument1Ptr; 56 | [NativeDisableUnsafePtrRestriction] 57 | public unsafe void* Argument2Ptr; 58 | [NativeDisableUnsafePtrRestriction] 59 | public unsafe void* Argument3Ptr; 60 | [NativeDisableUnsafePtrRestriction] 61 | public unsafe void* Argument4Ptr; 62 | [NativeDisableUnsafePtrRestriction] 63 | public unsafe void* Argument5Ptr; 64 | [NativeDisableUnsafePtrRestriction] 65 | public unsafe void* ResultPtr; 66 | 67 | public unsafe void Execute() 68 | { 69 | UnsafeUtility.CopyPtrToStructure(ResultPtr, out TResult result); 70 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 71 | UnsafeUtility.CopyPtrToStructure(Argument1Ptr, out T1 arg1); 72 | UnsafeUtility.CopyPtrToStructure(Argument2Ptr, out T2 arg2); 73 | UnsafeUtility.CopyPtrToStructure(Argument3Ptr, out T3 arg3); 74 | UnsafeUtility.CopyPtrToStructure(Argument4Ptr, out T4 arg4); 75 | UnsafeUtility.CopyPtrToStructure(Argument5Ptr, out T5 arg5); 76 | 77 | result = func.Execute(arg1, arg2, arg3, arg4, arg5); 78 | UnsafeUtility.CopyStructureToPtr(ref result, ResultPtr); 79 | } 80 | 81 | public static unsafe TResult Run(TFunc func, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) 82 | { 83 | TResult result = default; 84 | new BurstFunction 85 | { 86 | ResultPtr = UnsafeUtility.AddressOf(ref result), 87 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 88 | Argument1Ptr = UnsafeUtility.AddressOf(ref arg1), 89 | Argument2Ptr = UnsafeUtility.AddressOf(ref arg2), 90 | Argument3Ptr = UnsafeUtility.AddressOf(ref arg3), 91 | Argument4Ptr = UnsafeUtility.AddressOf(ref arg4), 92 | Argument5Ptr = UnsafeUtility.AddressOf(ref arg5), 93 | 94 | }.Run(); 95 | return result; 96 | } 97 | } 98 | 99 | [BurstCompile] 100 | public struct BurstFunction : IJob 101 | where TFunc : struct, IBurstFunction 102 | where T1 : struct 103 | where T2 : struct 104 | where T3 : struct 105 | where T4 : struct 106 | where TResult : struct 107 | { 108 | [NativeDisableUnsafePtrRestriction] 109 | public unsafe void* FunctionPtr; 110 | [NativeDisableUnsafePtrRestriction] 111 | public unsafe void* Argument1Ptr; 112 | [NativeDisableUnsafePtrRestriction] 113 | public unsafe void* Argument2Ptr; 114 | [NativeDisableUnsafePtrRestriction] 115 | public unsafe void* Argument3Ptr; 116 | [NativeDisableUnsafePtrRestriction] 117 | public unsafe void* Argument4Ptr; 118 | [NativeDisableUnsafePtrRestriction] 119 | public unsafe void* ResultPtr; 120 | 121 | public unsafe void Execute() 122 | { 123 | UnsafeUtility.CopyPtrToStructure(ResultPtr, out TResult result); 124 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 125 | UnsafeUtility.CopyPtrToStructure(Argument1Ptr, out T1 arg1); 126 | UnsafeUtility.CopyPtrToStructure(Argument2Ptr, out T2 arg2); 127 | UnsafeUtility.CopyPtrToStructure(Argument3Ptr, out T3 arg3); 128 | UnsafeUtility.CopyPtrToStructure(Argument4Ptr, out T4 arg4); 129 | 130 | result = func.Execute(arg1, arg2, arg3, arg4); 131 | UnsafeUtility.CopyStructureToPtr(ref result, ResultPtr); 132 | } 133 | 134 | public static unsafe TResult Run(TFunc func, T1 arg1, T2 arg2, T3 arg3, T4 arg4) 135 | { 136 | TResult result = default; 137 | new BurstFunction 138 | { 139 | ResultPtr = UnsafeUtility.AddressOf(ref result), 140 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 141 | Argument1Ptr = UnsafeUtility.AddressOf(ref arg1), 142 | Argument2Ptr = UnsafeUtility.AddressOf(ref arg2), 143 | Argument3Ptr = UnsafeUtility.AddressOf(ref arg3), 144 | Argument4Ptr = UnsafeUtility.AddressOf(ref arg4), 145 | 146 | }.Run(); 147 | return result; 148 | } 149 | } 150 | 151 | [BurstCompile] 152 | public struct BurstFunction : IJob 153 | where TFunc : struct, IBurstFunction 154 | where T1 : struct 155 | where T2 : struct 156 | where T3 : struct 157 | where TResult : struct 158 | { 159 | [NativeDisableUnsafePtrRestriction] 160 | public unsafe void* FunctionPtr; 161 | [NativeDisableUnsafePtrRestriction] 162 | public unsafe void* Argument1Ptr; 163 | [NativeDisableUnsafePtrRestriction] 164 | public unsafe void* Argument2Ptr; 165 | [NativeDisableUnsafePtrRestriction] 166 | public unsafe void* Argument3Ptr; 167 | [NativeDisableUnsafePtrRestriction] 168 | public unsafe void* ResultPtr; 169 | 170 | public unsafe void Execute() 171 | { 172 | UnsafeUtility.CopyPtrToStructure(ResultPtr, out TResult result); 173 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 174 | UnsafeUtility.CopyPtrToStructure(Argument1Ptr, out T1 arg1); 175 | UnsafeUtility.CopyPtrToStructure(Argument2Ptr, out T2 arg2); 176 | UnsafeUtility.CopyPtrToStructure(Argument3Ptr, out T3 arg3); 177 | 178 | result = func.Execute(arg1, arg2, arg3); 179 | UnsafeUtility.CopyStructureToPtr(ref result, ResultPtr); 180 | } 181 | 182 | public static unsafe TResult Run(TFunc func, T1 arg1, T2 arg2, T3 arg3) 183 | { 184 | TResult result = default; 185 | new BurstFunction 186 | { 187 | ResultPtr = UnsafeUtility.AddressOf(ref result), 188 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 189 | Argument1Ptr = UnsafeUtility.AddressOf(ref arg1), 190 | Argument2Ptr = UnsafeUtility.AddressOf(ref arg2), 191 | Argument3Ptr = UnsafeUtility.AddressOf(ref arg3), 192 | 193 | }.Run(); 194 | return result; 195 | } 196 | } 197 | 198 | [BurstCompile] 199 | public struct BurstFunction : IJob 200 | where TFunc : struct, IBurstFunction 201 | where T1 : struct 202 | where T2 : struct 203 | where TResult : struct 204 | { 205 | [NativeDisableUnsafePtrRestriction] 206 | public unsafe void* FunctionPtr; 207 | [NativeDisableUnsafePtrRestriction] 208 | public unsafe void* Argument1Ptr; 209 | [NativeDisableUnsafePtrRestriction] 210 | public unsafe void* Argument2Ptr; 211 | [NativeDisableUnsafePtrRestriction] 212 | public unsafe void* ResultPtr; 213 | 214 | public unsafe void Execute() 215 | { 216 | UnsafeUtility.CopyPtrToStructure(ResultPtr, out TResult result); 217 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 218 | UnsafeUtility.CopyPtrToStructure(Argument1Ptr, out T1 arg1); 219 | UnsafeUtility.CopyPtrToStructure(Argument2Ptr, out T2 arg2); 220 | 221 | result = func.Execute(arg1, arg2); 222 | UnsafeUtility.CopyStructureToPtr(ref result, ResultPtr); 223 | } 224 | 225 | public static unsafe TResult Run(TFunc func, T1 arg1, T2 arg2) 226 | { 227 | TResult result = default; 228 | new BurstFunction 229 | { 230 | ResultPtr = UnsafeUtility.AddressOf(ref result), 231 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 232 | Argument1Ptr = UnsafeUtility.AddressOf(ref arg1), 233 | Argument2Ptr = UnsafeUtility.AddressOf(ref arg2), 234 | 235 | }.Run(); 236 | return result; 237 | } 238 | } 239 | 240 | [BurstCompile] 241 | public struct BurstFunction : IJob 242 | where TFunc : struct, IBurstFunction 243 | where T1 : struct 244 | where TResult : struct 245 | { 246 | [NativeDisableUnsafePtrRestriction] 247 | public unsafe void* FunctionPtr; 248 | [NativeDisableUnsafePtrRestriction] 249 | public unsafe void* Argument1Ptr; 250 | [NativeDisableUnsafePtrRestriction] 251 | public unsafe void* ResultPtr; 252 | 253 | public unsafe void Execute() 254 | { 255 | UnsafeUtility.CopyPtrToStructure(ResultPtr, out TResult result); 256 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 257 | UnsafeUtility.CopyPtrToStructure(Argument1Ptr, out T1 arg1); 258 | 259 | result = func.Execute(arg1); 260 | UnsafeUtility.CopyStructureToPtr(ref result, ResultPtr); 261 | } 262 | 263 | public static unsafe TResult Run(TFunc func, T1 arg1) 264 | { 265 | TResult result = default; 266 | new BurstFunction 267 | { 268 | ResultPtr = UnsafeUtility.AddressOf(ref result), 269 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 270 | Argument1Ptr = UnsafeUtility.AddressOf(ref arg1), 271 | 272 | }.Run(); 273 | return result; 274 | } 275 | } 276 | 277 | [BurstCompile] 278 | public struct BurstFunction : IJob 279 | where TFunc : struct, IBurstFunction 280 | where TResult : struct 281 | { 282 | [NativeDisableUnsafePtrRestriction] 283 | public unsafe void* FunctionPtr; 284 | [NativeDisableUnsafePtrRestriction] 285 | public unsafe void* ResultPtr; 286 | 287 | public unsafe void Execute() 288 | { 289 | UnsafeUtility.CopyPtrToStructure(ResultPtr, out TResult result); 290 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 291 | 292 | result = func.Execute(); 293 | UnsafeUtility.CopyStructureToPtr(ref result, ResultPtr); 294 | } 295 | 296 | public static unsafe TResult Run(TFunc func) 297 | { 298 | TResult result = default; 299 | new BurstFunction 300 | { 301 | ResultPtr = UnsafeUtility.AddressOf(ref result), 302 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 303 | 304 | }.Run(); 305 | return result; 306 | } 307 | } 308 | } 309 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/BurstAction.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections.LowLevel.Unsafe; 3 | using Unity.Jobs; 4 | using System; 5 | using System.Reflection; 6 | using System.Runtime.CompilerServices; 7 | using UnityEngine.Bindings; 8 | 9 | namespace Vella.Common 10 | { 11 | 12 | public interface IBurstRefAction : IBurstOperation 13 | { 14 | void Execute(ref T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); 15 | } 16 | 17 | public interface IBurstAction : IBurstOperation 18 | { 19 | void Execute(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); 20 | } 21 | 22 | public interface IBurstAction : IBurstOperation 23 | { 24 | void Execute(T1 arg1, T2 arg2, T3 arg3, T4 arg4); 25 | } 26 | 27 | public interface IBurstAction : IBurstOperation 28 | { 29 | void Execute(T1 arg1, T2 arg2, T3 arg3); 30 | } 31 | 32 | public interface IBurstAction : IBurstOperation 33 | { 34 | void Execute(T1 arg1, T2 arg2); 35 | } 36 | 37 | public interface IBurstAction : IBurstOperation 38 | { 39 | void Execute(T1 arg1); 40 | } 41 | 42 | public interface IBurstAction : IBurstOperation 43 | { 44 | void Execute(); 45 | } 46 | 47 | [BurstCompile] 48 | public struct BurstRefAction : IJob 49 | where TFunc : struct, IBurstRefAction 50 | where T1 : unmanaged 51 | where T2 : struct 52 | where T3 : struct 53 | where T4 : struct 54 | where T5 : struct 55 | { 56 | [NativeDisableUnsafePtrRestriction] 57 | public unsafe void* FunctionPtr; 58 | [NativeDisableUnsafePtrRestriction] 59 | public unsafe T1* Argument1Ptr; 60 | [NativeDisableUnsafePtrRestriction] 61 | public unsafe void* Argument2Ptr; 62 | [NativeDisableUnsafePtrRestriction] 63 | public unsafe void* Argument3Ptr; 64 | [NativeDisableUnsafePtrRestriction] 65 | public unsafe void* Argument4Ptr; 66 | [NativeDisableUnsafePtrRestriction] 67 | public unsafe void* Argument5Ptr; 68 | 69 | public unsafe void Execute() 70 | { 71 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 72 | UnsafeUtility.CopyPtrToStructure(Argument2Ptr, out T2 arg2); 73 | UnsafeUtility.CopyPtrToStructure(Argument3Ptr, out T3 arg3); 74 | UnsafeUtility.CopyPtrToStructure(Argument4Ptr, out T4 arg4); 75 | UnsafeUtility.CopyPtrToStructure(Argument5Ptr, out T5 arg5); 76 | 77 | func.Execute(ref *Argument1Ptr, arg2, arg3, arg4, arg5); 78 | } 79 | 80 | public static unsafe void Run(TFunc func, ref T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) 81 | { 82 | new BurstRefAction 83 | { 84 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 85 | Argument1Ptr = (T1*)UnsafeUtility.AddressOf(ref arg1), 86 | Argument2Ptr = UnsafeUtility.AddressOf(ref arg2), 87 | Argument3Ptr = UnsafeUtility.AddressOf(ref arg3), 88 | Argument4Ptr = UnsafeUtility.AddressOf(ref arg4), 89 | Argument5Ptr = UnsafeUtility.AddressOf(ref arg5), 90 | 91 | }.Run(); 92 | } 93 | } 94 | 95 | [BurstCompile] 96 | public struct BurstAction : IJob 97 | where TFunc : struct, IBurstAction 98 | where T1 : struct 99 | where T2 : struct 100 | where T3 : struct 101 | where T4 : struct 102 | where T5 : struct 103 | { 104 | [NativeDisableUnsafePtrRestriction] 105 | public unsafe void* FunctionPtr; 106 | [NativeDisableUnsafePtrRestriction] 107 | public unsafe void* Argument1Ptr; 108 | [NativeDisableUnsafePtrRestriction] 109 | public unsafe void* Argument2Ptr; 110 | [NativeDisableUnsafePtrRestriction] 111 | public unsafe void* Argument3Ptr; 112 | [NativeDisableUnsafePtrRestriction] 113 | public unsafe void* Argument4Ptr; 114 | [NativeDisableUnsafePtrRestriction] 115 | public unsafe void* Argument5Ptr; 116 | 117 | public unsafe void Execute() 118 | { 119 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 120 | UnsafeUtility.CopyPtrToStructure(Argument1Ptr, out T1 arg1); 121 | UnsafeUtility.CopyPtrToStructure(Argument2Ptr, out T2 arg2); 122 | UnsafeUtility.CopyPtrToStructure(Argument3Ptr, out T3 arg3); 123 | UnsafeUtility.CopyPtrToStructure(Argument4Ptr, out T4 arg4); 124 | UnsafeUtility.CopyPtrToStructure(Argument5Ptr, out T5 arg5); 125 | func.Execute(arg1, arg2, arg3, arg4, arg5); 126 | } 127 | 128 | public static unsafe void Run(TFunc func, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) 129 | { 130 | new BurstAction 131 | { 132 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 133 | Argument1Ptr = UnsafeUtility.AddressOf(ref arg1), 134 | Argument2Ptr = UnsafeUtility.AddressOf(ref arg2), 135 | Argument3Ptr = UnsafeUtility.AddressOf(ref arg3), 136 | Argument4Ptr = UnsafeUtility.AddressOf(ref arg4), 137 | Argument5Ptr = UnsafeUtility.AddressOf(ref arg5), 138 | 139 | }.Run(); 140 | } 141 | } 142 | 143 | [BurstCompile] 144 | public struct BurstAction : IJob 145 | where TFunc : struct, IBurstAction 146 | where T1 : struct 147 | where T2 : struct 148 | where T3 : struct 149 | where T4 : struct 150 | { 151 | [NativeDisableUnsafePtrRestriction] 152 | public unsafe void* FunctionPtr; 153 | [NativeDisableUnsafePtrRestriction] 154 | public unsafe void* Argument1Ptr; 155 | [NativeDisableUnsafePtrRestriction] 156 | public unsafe void* Argument2Ptr; 157 | [NativeDisableUnsafePtrRestriction] 158 | public unsafe void* Argument3Ptr; 159 | [NativeDisableUnsafePtrRestriction] 160 | public unsafe void* Argument4Ptr; 161 | 162 | public unsafe void Execute() 163 | { 164 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 165 | UnsafeUtility.CopyPtrToStructure(Argument1Ptr, out T1 arg1); 166 | UnsafeUtility.CopyPtrToStructure(Argument2Ptr, out T2 arg2); 167 | UnsafeUtility.CopyPtrToStructure(Argument3Ptr, out T3 arg3); 168 | UnsafeUtility.CopyPtrToStructure(Argument4Ptr, out T4 arg4); 169 | func.Execute(arg1, arg2, arg3, arg4); 170 | } 171 | 172 | public static unsafe void Run(TFunc func, T1 arg1, T2 arg2, T3 arg3, T4 arg4) 173 | { 174 | new BurstAction 175 | { 176 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 177 | Argument1Ptr = UnsafeUtility.AddressOf(ref arg1), 178 | Argument2Ptr = UnsafeUtility.AddressOf(ref arg2), 179 | Argument3Ptr = UnsafeUtility.AddressOf(ref arg3), 180 | Argument4Ptr = UnsafeUtility.AddressOf(ref arg4), 181 | 182 | }.Run(); 183 | } 184 | } 185 | 186 | [BurstCompile] 187 | public struct BurstAction : IJob 188 | where TFunc : struct, IBurstAction 189 | where T1 : struct 190 | where T2 : struct 191 | where T3 : struct 192 | { 193 | [NativeDisableUnsafePtrRestriction] 194 | public unsafe void* FunctionPtr; 195 | [NativeDisableUnsafePtrRestriction] 196 | public unsafe void* Argument1Ptr; 197 | [NativeDisableUnsafePtrRestriction] 198 | public unsafe void* Argument2Ptr; 199 | [NativeDisableUnsafePtrRestriction] 200 | public unsafe void* Argument3Ptr; 201 | 202 | public unsafe void Execute() 203 | { 204 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 205 | UnsafeUtility.CopyPtrToStructure(Argument1Ptr, out T1 arg1); 206 | UnsafeUtility.CopyPtrToStructure(Argument2Ptr, out T2 arg2); 207 | UnsafeUtility.CopyPtrToStructure(Argument3Ptr, out T3 arg3); 208 | func.Execute(arg1, arg2, arg3); 209 | } 210 | 211 | public static unsafe void Run(TFunc func, T1 arg1, T2 arg2, T3 arg3) 212 | { 213 | new BurstAction 214 | { 215 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 216 | Argument1Ptr = UnsafeUtility.AddressOf(ref arg1), 217 | Argument2Ptr = UnsafeUtility.AddressOf(ref arg2), 218 | Argument3Ptr = UnsafeUtility.AddressOf(ref arg3), 219 | 220 | }.Run(); 221 | } 222 | } 223 | 224 | [BurstCompile] 225 | public struct BurstAction : IJob 226 | where TFunc : struct, IBurstAction 227 | where T1 : struct 228 | where T2 : struct 229 | { 230 | [NativeDisableUnsafePtrRestriction] 231 | public unsafe void* FunctionPtr; 232 | [NativeDisableUnsafePtrRestriction] 233 | public unsafe void* Argument1Ptr; 234 | [NativeDisableUnsafePtrRestriction] 235 | public unsafe void* Argument2Ptr; 236 | [NativeDisableUnsafePtrRestriction] 237 | public unsafe void* Argument3Ptr; 238 | 239 | public unsafe void Execute() 240 | { 241 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 242 | UnsafeUtility.CopyPtrToStructure(Argument1Ptr, out T1 arg1); 243 | UnsafeUtility.CopyPtrToStructure(Argument2Ptr, out T2 arg2); 244 | func.Execute(arg1, arg2); 245 | } 246 | 247 | public static unsafe void Run(TFunc func, T1 arg1, T2 arg2) 248 | { 249 | new BurstAction 250 | { 251 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 252 | Argument1Ptr = UnsafeUtility.AddressOf(ref arg1), 253 | Argument2Ptr = UnsafeUtility.AddressOf(ref arg2), 254 | 255 | }.Run(); 256 | } 257 | } 258 | 259 | [BurstCompile] 260 | public struct BurstAction : IJob 261 | where TFunc : struct, IBurstAction 262 | where T1 : struct 263 | { 264 | [NativeDisableUnsafePtrRestriction] 265 | public unsafe void* FunctionPtr; 266 | [NativeDisableUnsafePtrRestriction] 267 | public unsafe void* Argument1Ptr; 268 | [NativeDisableUnsafePtrRestriction] 269 | public unsafe void* Argument2Ptr; 270 | [NativeDisableUnsafePtrRestriction] 271 | public unsafe void* Argument3Ptr; 272 | 273 | public unsafe void Execute() 274 | { 275 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 276 | UnsafeUtility.CopyPtrToStructure(Argument1Ptr, out T1 arg1); 277 | func.Execute(arg1); 278 | } 279 | 280 | public static unsafe void Run(TFunc func, T1 arg1) 281 | { 282 | new BurstAction 283 | { 284 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 285 | Argument1Ptr = UnsafeUtility.AddressOf(ref arg1), 286 | 287 | }.Run(); 288 | } 289 | } 290 | 291 | [BurstCompile] 292 | public struct BurstAction : IJob 293 | where TFunc : struct, IBurstAction 294 | { 295 | [NativeDisableUnsafePtrRestriction] 296 | public unsafe void* FunctionPtr; 297 | 298 | public unsafe void Execute() 299 | { 300 | UnsafeUtility.CopyPtrToStructure(FunctionPtr, out TFunc func); 301 | func.Execute(); 302 | } 303 | 304 | public static unsafe void Run(TFunc func) 305 | { 306 | new BurstAction 307 | { 308 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 309 | 310 | }.Run(); 311 | } 312 | } 313 | 314 | [BurstCompile] 315 | public struct BurstRefAction : IJob where TFunc : unmanaged, IBurstAction 316 | { 317 | [NativeDisableUnsafePtrRestriction] 318 | public unsafe TFunc* FunctionPtr; 319 | 320 | public unsafe void Execute() 321 | { 322 | FunctionPtr->Execute(); 323 | } 324 | 325 | public static unsafe void Run(ref TFunc func) 326 | { 327 | new BurstAction 328 | { 329 | FunctionPtr = UnsafeUtility.AddressOf(ref func), 330 | 331 | }.Run(); 332 | } 333 | } 334 | 335 | } 336 | 337 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/HullTester.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Unity.Mathematics; 3 | using UnityEngine; 4 | using System.Linq; 5 | using System; 6 | using System.Diagnostics; 7 | using Unity.Collections; 8 | using Vella.Common; 9 | using Vella.UnityNativeHull; 10 | using BoundingSphere = Vella.Common.BoundingSphere; 11 | using Debug = UnityEngine.Debug; 12 | using Random = Unity.Mathematics.Random; 13 | 14 | #if UNITY_EDITOR 15 | using UnityEditor; 16 | #endif 17 | 18 | [ExecuteInEditMode] 19 | public class HullTester : MonoBehaviour 20 | { 21 | public List Transforms; 22 | 23 | public DebugHullFlags HullDrawingOptions = DebugHullFlags.Outline; 24 | 25 | [Header("Visualizations")] 26 | public bool DrawIsCollided; 27 | public bool DrawContact; 28 | public bool DrawIntersection; 29 | public bool DrawClosestFace; 30 | public bool DrawClosestPoint; 31 | 32 | [Header("Console Logging")] 33 | public bool LogCollisions; 34 | public bool LogClosestPoint; 35 | public bool LogContact; 36 | 37 | private Dictionary Hulls; 38 | private Dictionary GameObjects; 39 | 40 | void Update() 41 | { 42 | HandleTransformChanged(); 43 | HandleHullCollisions(); 44 | } 45 | 46 | private void HandleHullCollisions() 47 | { 48 | for (int i = 0; i < Transforms.Count; ++i) 49 | { 50 | var tA = Transforms[i]; 51 | if (tA == null) 52 | continue; 53 | 54 | var hullA = Hulls[tA.GetInstanceID()].Hull; 55 | var transformA = new RigidTransform(tA.rotation, tA.position); 56 | 57 | HullDrawingUtility.DrawDebugHull(hullA, transformA, HullDrawingOptions); 58 | 59 | if (LogClosestPoint) 60 | { 61 | var sw3 = System.Diagnostics.Stopwatch.StartNew(); 62 | var result3 = HullCollision.ClosestPoint(transformA, hullA, 0); 63 | sw3.Stop(); 64 | 65 | var sw4 = System.Diagnostics.Stopwatch.StartNew(); 66 | var result4 = HullOperations.ClosestPoint.Invoke(transformA, hullA, 0); 67 | sw4.Stop(); 68 | 69 | if (DrawClosestPoint) 70 | { 71 | DebugDrawer.DrawSphere(result4, 0.1f, Color.blue); 72 | DebugDrawer.DrawLine(result4, Vector3.zero, Color.blue); 73 | } 74 | 75 | Debug.Log($"ClosestPoint between '{tA.name}' and world zero took: {sw3.Elapsed.TotalMilliseconds:N4}ms (Normal), {sw4.Elapsed.TotalMilliseconds:N4}ms (Burst)"); 76 | } 77 | 78 | for (int j = i + 1; j < Transforms.Count; j++) 79 | { 80 | var tB = Transforms[j]; 81 | if (tB == null) 82 | continue; 83 | 84 | if (!tA.hasChanged && !tB.hasChanged) 85 | continue; 86 | 87 | var hullB = Hulls[tB.GetInstanceID()].Hull; 88 | var transformB = new RigidTransform(tB.rotation, tB.position); 89 | HullDrawingUtility.DrawDebugHull(hullB, transformB, HullDrawingOptions); 90 | 91 | DrawHullCollision(tA.gameObject, tB.gameObject, transformA, hullA, transformB, hullB); 92 | 93 | if (LogCollisions) 94 | { 95 | var sw1 = System.Diagnostics.Stopwatch.StartNew(); 96 | var result1 = HullCollision.IsColliding(transformA, hullA, transformB, hullB); 97 | sw1.Stop(); 98 | 99 | var sw2 = System.Diagnostics.Stopwatch.StartNew(); 100 | var result2 = HullOperations.IsColliding.Invoke(transformA, hullA, transformB, hullB); 101 | sw2.Stop(); 102 | 103 | Debug.Assert(result1 == result2); 104 | 105 | Debug.Log($"Collisions between '{tA.name}'/'{tB.name}' took: {sw1.Elapsed.TotalMilliseconds:N4}ms (Normal), {sw2.Elapsed.TotalMilliseconds:N4}ms (Burst)"); 106 | } 107 | } 108 | } 109 | 110 | if(LogCollisions) 111 | { 112 | TestBatchCollision(); 113 | } 114 | } 115 | 116 | private void TestBatchCollision() 117 | { 118 | var batchInput = Hulls.Select(t => new BatchCollisionInput 119 | { 120 | Id = t.Key, 121 | Transform = new RigidTransform(t.Value.Transform.rot, t.Value.Transform.pos), 122 | Hull = t.Value.Hull, 123 | 124 | }).ToArray(); 125 | 126 | using (var hulls = new NativeArray(batchInput, Allocator.TempJob)) 127 | using (var results = new NativeList(batchInput.Length, Allocator.TempJob)) 128 | { 129 | var sw3 = System.Diagnostics.Stopwatch.StartNew(); 130 | var collisions = HullOperations.CollisionBatch.Invoke(hulls, results); 131 | sw3.Stop(); 132 | 133 | Debug.Log($"Batch Collisions took {sw3.Elapsed.TotalMilliseconds:N4}ms ({results.Length} collisions from {hulls.Length} hulls)"); 134 | 135 | if (collisions) 136 | { 137 | foreach (var result in results.AsArray()) 138 | { 139 | Debug.Log($" > {GameObjects[result.A.Id].name} collided with {GameObjects[result.B.Id].name}"); 140 | } 141 | } 142 | } 143 | } 144 | 145 | public void DrawHullCollision(GameObject a, GameObject b, RigidTransform t1, NativeHull hull1, RigidTransform t2, NativeHull hull2) 146 | { 147 | 148 | var collision = HullCollision.GetDebugCollisionInfo(t1, hull1, t2, hull2); 149 | if (collision.IsColliding) 150 | { 151 | if (DrawIntersection) // Visualize all faces of the intersection 152 | { 153 | HullIntersection.DrawNativeHullHullIntersection(t1, hull1, t2, hull2); 154 | } 155 | 156 | if (DrawContact || LogContact) // Visualize the minimal contact calcluation for physics 157 | { 158 | //var manifold = HullOperations.GetContact.Invoke(t1, hull1, t2, hull2); 159 | 160 | var sw1 = System.Diagnostics.Stopwatch.StartNew(); 161 | var tmp = new NativeManifold(Allocator.Persistent); 162 | var normalResult = HullIntersection.NativeHullHullContact(ref tmp, t1, hull1, t2, hull2); 163 | sw1.Stop(); 164 | tmp.Dispose(); 165 | 166 | var sw2 = System.Diagnostics.Stopwatch.StartNew(); 167 | var burstResult = HullOperations.TryGetContact.Invoke(out NativeManifold manifold, t1, hull1, t2, hull2); 168 | sw2.Stop(); 169 | 170 | if(LogContact) 171 | { 172 | Debug.Log($"GetContact between '{a.name}'/'{b.name}' took: {sw1.Elapsed.TotalMilliseconds:N4}ms (Normal), {sw2.Elapsed.TotalMilliseconds:N4}ms (Burst)"); 173 | } 174 | 175 | if (DrawContact && burstResult) 176 | { 177 | // Do something with manifold 178 | 179 | HullDrawingUtility.DebugDrawManifold(manifold); 180 | 181 | //var points = manifold.Points; 182 | 183 | for (int i = 0; i < manifold.Length; i++) 184 | { 185 | var point = manifold[i]; 186 | DebugDrawer.DrawSphere(point.Position, 0.02f); 187 | DebugDrawer.DrawArrow(point.Position, manifold.Normal * 0.2f); 188 | 189 | var penentrationPoint = point.Position + manifold.Normal * point.Distance; 190 | DebugDrawer.DrawLabel(penentrationPoint, $"{point.Distance:N2}"); 191 | 192 | HullDrawingUtility.DrawEdge(point.Id.FeaturePair.InEdge1, t1, hull1); 193 | HullDrawingUtility.DrawEdge(point.Id.FeaturePair.OutEdge1, t1, hull1); 194 | HullDrawingUtility.DrawEdge(point.Id.FeaturePair.InEdge2, t1, hull1); 195 | HullDrawingUtility.DrawEdge(point.Id.FeaturePair.OutEdge2, t1, hull1); 196 | 197 | HullDrawingUtility.DrawEdge(point.Id.FeaturePair.InEdge1, t2, hull2); 198 | HullDrawingUtility.DrawEdge(point.Id.FeaturePair.OutEdge1, t2, hull2); 199 | HullDrawingUtility.DrawEdge(point.Id.FeaturePair.InEdge2, t2, hull2); 200 | HullDrawingUtility.DrawEdge(point.Id.FeaturePair.OutEdge2, t2, hull2); 201 | 202 | DebugDrawer.DrawDottedLine(point.Position, penentrationPoint); 203 | } 204 | 205 | manifold.Dispose(); 206 | } 207 | 208 | } 209 | 210 | if(DrawIsCollided) 211 | { 212 | DebugDrawer.DrawSphere(t1.pos, 0.1f, UnityColors.GhostDodgerBlue); 213 | DebugDrawer.DrawSphere(t2.pos, 0.1f, UnityColors.GhostDodgerBlue); 214 | } 215 | } 216 | 217 | if(DrawClosestFace) 218 | { 219 | var color1 = collision.Face1.Distance > 0 ? UnityColors.Red.ToOpacity(0.3f) : UnityColors.Yellow.ToOpacity(0.3f); 220 | HullDrawingUtility.DrawFaceWithOutline(collision.Face1.Index, t1, hull1, color1, UnityColors.Black); 221 | 222 | var color2 = collision.Face2.Distance > 0 ? UnityColors.Red.ToOpacity(0.3f) : UnityColors.Yellow.ToOpacity(0.3f); 223 | HullDrawingUtility.DrawFaceWithOutline(collision.Face2.Index, t2, hull2, color2, UnityColors.Black); 224 | } 225 | } 226 | 227 | private void HandleTransformChanged() 228 | { 229 | var transforms = Transforms.ToList().Distinct().Where(t => t.gameObject.activeSelf).ToList(); 230 | var newTransformFound = false; 231 | var transformCount = 0; 232 | 233 | if (Hulls != null) 234 | { 235 | for (var i = 0; i < transforms.Count; i++) 236 | { 237 | var t = transforms[i]; 238 | if (t == null) 239 | continue; 240 | 241 | transformCount++; 242 | 243 | var foundNewHull = !Hulls.ContainsKey(t.GetInstanceID()); 244 | if (foundNewHull) 245 | { 246 | newTransformFound = true; 247 | break; 248 | } 249 | } 250 | 251 | if (!newTransformFound && transformCount == Hulls.Count) 252 | return; 253 | } 254 | 255 | Debug.Log("Rebuilding Objects"); 256 | 257 | EnsureDestroyed(); 258 | 259 | Hulls = transforms.Where(t => t != null).ToDictionary(k => k.GetInstanceID(), CreateShape); 260 | GameObjects = transforms.Where(t => t != null).ToDictionary(k => k.GetInstanceID(), t => t.gameObject); 261 | 262 | SceneView.RepaintAll(); 263 | } 264 | 265 | private TestShape CreateShape(Transform t) 266 | { 267 | var bounds = new BoundingBox(); 268 | var hull = CreateHull(t); 269 | 270 | for (int i = 0; i < hull.VertexCount; i++) 271 | { 272 | var v = hull.GetVertex(i); 273 | bounds.Encapsulate(v); 274 | } 275 | 276 | var sphere = BoundingSphere.FromAABB(bounds); 277 | 278 | return new TestShape 279 | { 280 | BoundingBox = bounds, 281 | BoundingSphere = sphere, 282 | Id = t.GetInstanceID(), 283 | Transform = new RigidTransform(t.rotation, t.position), 284 | Hull = hull, 285 | }; 286 | } 287 | 288 | private NativeHull CreateHull(Transform v) 289 | { 290 | var collider = v.GetComponent(); 291 | if (collider is BoxCollider boxCollider) 292 | { 293 | return HullFactory.CreateBox(boxCollider.size); 294 | } 295 | if(collider is MeshCollider meshCollider) 296 | { 297 | return HullFactory.CreateFromMesh(meshCollider.sharedMesh); 298 | } 299 | var mf = v.GetComponent(); 300 | if(mf != null && mf.sharedMesh != null) 301 | { 302 | return HullFactory.CreateFromMesh(mf.sharedMesh); 303 | } 304 | throw new InvalidOperationException($"Unable to create a hull from the GameObject '{v?.name}'"); 305 | } 306 | 307 | void OnEnable() 308 | { 309 | #if UNITY_EDITOR 310 | EditorApplication.playModeStateChanged += EditorApplication_playModeStateChanged; 311 | #endif 312 | } 313 | 314 | #if UNITY_EDITOR 315 | private void EditorApplication_playModeStateChanged(PlayModeStateChange state) 316 | { 317 | switch (state) 318 | { 319 | case PlayModeStateChange.ExitingEditMode: 320 | case PlayModeStateChange.ExitingPlayMode: 321 | EnsureDestroyed(); 322 | break; 323 | } 324 | } 325 | #endif 326 | 327 | void OnDestroy() => EnsureDestroyed(); 328 | void OnDisable() => EnsureDestroyed(); 329 | 330 | private void EnsureDestroyed() 331 | { 332 | if (Hulls == null) 333 | return; 334 | 335 | foreach(var kvp in Hulls) 336 | { 337 | if (kvp.Value.Hull.IsValid) 338 | { 339 | kvp.Value.Hull.Dispose(); 340 | } 341 | } 342 | 343 | Hulls.Clear(); 344 | } 345 | 346 | } 347 | 348 | -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/UnityColors.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Vella.Common 4 | { 5 | public static class UnityColors 6 | { 7 | public static Color ToOpacity(this Color color, float alpha) 8 | { 9 | return new Color(color.r,color.g,color.b, alpha); 10 | } 11 | 12 | // Unity Default Colors 13 | public static Color Black { get; } = Color.black; 14 | public static Color Blue { get; } = Color.blue; 15 | public static Color Clear { get; } = Color.clear; 16 | public static Color Cyan { get; } = Color.cyan; 17 | public static Color Gray { get; } = Color.gray; 18 | public static Color Green { get; } = Color.green; 19 | public static Color Grey { get; } = Color.grey; 20 | public static Color Magenta { get; } = Color.magenta; 21 | public static Color Red { get; } = Color.red; 22 | public static Color White { get; } = Color.white; 23 | public static Color Yellow { get; } = Color.yellow; 24 | 25 | // Custom Colors (Note Unity uses a 0-1 scale instead of 0-255) 26 | public static Color GhostDodgerBlue { get; } = new Color(30 / 255f, 144 / 255f, 255 / 255f, 0.65f); 27 | public static Color DarkDodgerBlue { get; } = new Color(19 / 255f, 90 / 255f, 159 / 255f, 1f); 28 | 29 | // Standard Colors 30 | public static Color Transparent { get; } = FromArgb(16777215); 31 | public static Color AliceBlue { get; } = FromArgb(-984833); 32 | public static Color AntiqueWhite { get; } = FromArgb(-332841); 33 | public static Color Aqua { get; } = FromArgb(-16711681); 34 | public static Color Aquamarine { get; } = FromArgb(-8388652); 35 | public static Color Azure { get; } = FromArgb(-983041); 36 | public static Color Beige { get; } = FromArgb(-657956); 37 | public static Color Bisque { get; } = FromArgb(-6972); 38 | //public static Color Black { get; } = FromArgb(-16777216); 39 | public static Color BlanchedAlmond { get; } = FromArgb(-5171); 40 | //public static Color Blue { get; } = FromArgb(-16776961); 41 | public static Color BlueViolet { get; } = FromArgb(-7722014); 42 | //public static Color Brown { get; } = FromArgb(-5952982, ) 43 | public static Color BurlyWood { get; } = FromArgb(-2180985); 44 | public static Color CadetBlue { get; } = FromArgb(-10510688); 45 | public static Color Chartreuse { get; } = FromArgb(-8388864); 46 | public static Color Chocolate { get; } = FromArgb(-2987746); 47 | public static Color Coral { get; } = FromArgb(-32944); 48 | public static Color CornflowerBlue { get; } = FromArgb(-10185235); 49 | public static Color Cornsilk { get; } = FromArgb(-1828); 50 | public static Color Crimson { get; } = FromArgb(-2354116); 51 | //public static Color Cyan { get; } = FromArgb(-16711681); 52 | public static Color DarkBlue { get; } = FromArgb(-16777077); 53 | public static Color DarkCyan { get; } = FromArgb(-16741493); 54 | public static Color DarkGoldenrod { get; } = FromArgb(-4684277); 55 | public static Color DarkGray { get; } = FromArgb(-5658199); 56 | public static Color DarkGreen { get; } = FromArgb(-16751616); 57 | public static Color DarkKhaki { get; } = FromArgb(-4343957); 58 | public static Color DarkMagenta { get; } = FromArgb(-7667573); 59 | public static Color DarkOliveGreen { get; } = FromArgb(-11179217); 60 | public static Color DarkOrange { get; } = FromArgb(-29696); 61 | public static Color DarkOrchid { get; } = FromArgb(-6737204); 62 | public static Color DarkRed { get; } = FromArgb(-7667712); 63 | public static Color DarkSalmon { get; } = FromArgb(-1468806); 64 | public static Color DarkSeaGreen { get; } = FromArgb(-7357301); 65 | public static Color DarkSlateBlue { get; } = FromArgb(-12042869); 66 | public static Color DarkSlateGray { get; } = FromArgb(-13676721); 67 | public static Color DarkTurquoise { get; } = FromArgb(-16724271); 68 | public static Color DarkViolet { get; } = FromArgb(-7077677); 69 | public static Color DeepPink { get; } = FromArgb(-60269); 70 | public static Color DeepSkyBlue { get; } = FromArgb(-16728065); 71 | public static Color DimGray { get; } = FromArgb(-9868951); 72 | public static Color DodgerBlue { get; } = FromArgb(-14774017); 73 | public static Color Firebrick { get; } = FromArgb(-5103070); 74 | public static Color FloralWhite { get; } = FromArgb(-1296); 75 | public static Color ForestGreen { get; } = FromArgb(-14513374); 76 | public static Color Fuchsia { get; } = FromArgb(-65281); 77 | public static Color Gainsboro { get; } = FromArgb(-2302756); 78 | public static Color GhostWhite { get; } = FromArgb(-460545); 79 | public static Color Gold { get; } = FromArgb(-10496); 80 | public static Color Goldenrod { get; } = FromArgb(-2448096); 81 | //public static Color Gray { get; } = FromArgb(-8355712); 82 | //public static Color Green { get; } = FromArgb(-16744448); 83 | public static Color GreenYellow { get; } = FromArgb(-5374161); 84 | public static Color Honeydew { get; } = FromArgb(-983056); 85 | public static Color HotPink { get; } = FromArgb(-38476); 86 | public static Color IndianRed { get; } = FromArgb(-3318692); 87 | public static Color Indigo { get; } = FromArgb(-11861886); 88 | public static Color Ivory { get; } = FromArgb(-16); 89 | public static Color Khaki { get; } = FromArgb(-989556); 90 | public static Color Lavender { get; } = FromArgb(-1644806); 91 | public static Color LavenderBlush { get; } = FromArgb(-3851); 92 | public static Color LawnGreen { get; } = FromArgb(-8586240); 93 | public static Color LemonChiffon { get; } = FromArgb(-1331); 94 | public static Color LightBlue { get; } = FromArgb(-5383962); 95 | public static Color LightCoral { get; } = FromArgb(-1015680); 96 | public static Color LightCyan { get; } = FromArgb(-2031617); 97 | public static Color LightGoldenrodYellow { get; } = FromArgb(-329006); 98 | public static Color LightGray { get; } = FromArgb(-2894893); 99 | public static Color LightGreen { get; } = FromArgb(-7278960); 100 | public static Color LightPink { get; } = FromArgb(-18751); 101 | public static Color LightSalmon { get; } = FromArgb(-24454); 102 | public static Color LightSeaGreen { get; } = FromArgb(-14634326); 103 | public static Color LightSkyBlue { get; } = FromArgb(-7876870); 104 | public static Color LightSlateGray { get; } = FromArgb(-8943463); 105 | public static Color LightSteelBlue { get; } = FromArgb(-5192482); 106 | public static Color LightYellow { get; } = FromArgb(-32); 107 | public static Color Lime { get; } = FromArgb(-16711936); 108 | public static Color LimeGreen { get; } = FromArgb(-13447886); 109 | public static Color Linen { get; } = FromArgb(-331546); 110 | //public static Color Magenta { get; } = FromArgb(-65281); 111 | public static Color Maroon { get; } = FromArgb(-8388608); 112 | public static Color MediumAquamarine { get; } = FromArgb(-10039894); 113 | public static Color MediumBlue { get; } = FromArgb(-16777011); 114 | public static Color MediumOrchid { get; } = FromArgb(-4565549); 115 | public static Color MediumPurple { get; } = FromArgb(-7114533); 116 | public static Color MediumSeaGreen { get; } = FromArgb(-12799119); 117 | public static Color MediumSlateBlue { get; } = FromArgb(-8689426); 118 | public static Color MediumSpringGreen { get; } = FromArgb(-16713062); 119 | public static Color MediumTurquoise { get; } = FromArgb(-12004916); 120 | public static Color MediumVioletRed { get; } = FromArgb(-3730043); 121 | public static Color MidnightBlue { get; } = FromArgb(-15132304); 122 | public static Color MintCream { get; } = FromArgb(-655366); 123 | public static Color MistyRose { get; } = FromArgb(-6943); 124 | public static Color Moccasin { get; } = FromArgb(-6987); 125 | public static Color NavajoWhite { get; } = FromArgb(-8531); 126 | public static Color Navy { get; } = FromArgb(-16777088); 127 | public static Color OldLace { get; } = FromArgb(-133658); 128 | public static Color Olive { get; } = FromArgb(-8355840); 129 | public static Color OliveDrab { get; } = FromArgb(-9728477); 130 | public static Color Orange { get; } = FromArgb(-23296); 131 | public static Color OrangeRed { get; } = FromArgb(-47872); 132 | public static Color Orchid { get; } = FromArgb(-2461482); 133 | public static Color PaleGoldenrod { get; } = FromArgb(-1120086); 134 | public static Color PaleGreen { get; } = FromArgb(-6751336); 135 | public static Color PaleTurquoise { get; } = FromArgb(-5247250); 136 | public static Color PaleVioletRed { get; } = FromArgb(-2396013); 137 | public static Color PapayaWhip { get; } = FromArgb(-4139); 138 | public static Color PeachPuff { get; } = FromArgb(-9543); 139 | public static Color Peru { get; } = FromArgb(-3308225); 140 | public static Color Pink { get; } = FromArgb(-16181); 141 | public static Color Plum { get; } = FromArgb(-2252579); 142 | public static Color PowderBlue { get; } = FromArgb(-5185306); 143 | public static Color Purple { get; } = FromArgb(-8388480); 144 | //public static Color Red { get; } = FromArgb(-65536); 145 | public static Color RosyBrown { get; } = FromArgb(-4419697); 146 | public static Color RoyalBlue { get; } = FromArgb(-12490271); 147 | public static Color SaddleBrown { get; } = FromArgb(-7650029); 148 | public static Color Salmon { get; } = FromArgb(-360334); 149 | public static Color SandyBrown { get; } = FromArgb(-744352); 150 | public static Color SeaGreen { get; } = FromArgb(-13726889); 151 | public static Color SeaShell { get; } = FromArgb(-2578); 152 | public static Color Sienna { get; } = FromArgb(-6270419); 153 | public static Color Silver { get; } = FromArgb(-4144960); 154 | public static Color SkyBlue { get; } = FromArgb(-7876885); 155 | public static Color SlateBlue { get; } = FromArgb(-9807155); 156 | public static Color SlateGray { get; } = FromArgb(-9404272); 157 | public static Color Snow { get; } = FromArgb(-1286); 158 | public static Color SpringGreen { get; } = FromArgb(-16711809); 159 | public static Color SteelBlue { get; } = FromArgb(-12156236); 160 | public static Color Tan { get; } = FromArgb(-2968436); 161 | public static Color Teal { get; } = FromArgb(-16744320); 162 | public static Color Thistle { get; } = FromArgb(-2572328); 163 | public static Color Tomato { get; } = FromArgb(-40121); 164 | public static Color Turquoise { get; } = FromArgb(-12525360); 165 | public static Color Violet { get; } = FromArgb(-1146130); 166 | public static Color Wheat { get; } = FromArgb(-663885); 167 | //public static Color White { get; } = FromArgb(-1); 168 | public static Color WhiteSmoke { get; } = FromArgb(-657931); 169 | //public static Color Yellow { get; } = FromArgb(-256); 170 | public static Color YellowGreen { get; } = FromArgb(-6632142); 171 | 172 | 173 | 174 | private static long ToArgb(this Color color) 175 | { 176 | return (long)(uint)((byte)color.r * 255 << 16 | (byte)color.g * 255 << 8 | (byte)color.b * 255 | (byte)color.a * 255 << 24) & uint.MaxValue; 177 | } 178 | 179 | public static Color FromArgb(long argb) 180 | { 181 | var r = (byte)((ulong)(argb >> 16) & (ulong)byte.MaxValue); 182 | var g = (byte)((ulong)(argb >> 8) & (ulong)byte.MaxValue); 183 | var b = (byte)((ulong)argb & (ulong)byte.MaxValue); 184 | var a = (byte)((ulong)(argb >> 24) & (ulong)byte.MaxValue); 185 | return new Color(r / 255f, g / 255f, b / 255f, a / 255f); 186 | } 187 | 188 | //public static Color FromHex(string colorcode) 189 | //{ 190 | // return FromArgb(int.Parse(colorcode.Replace("#", ""), NumberStyles.HexNumber)); 191 | //} 192 | 193 | private static string ToHex(this Color color) 194 | { 195 | return "#" + color.a.ToString("X2") + color.r.ToString("X2") + color.g.ToString("X2") + color.b.ToString("X2"); 196 | } 197 | 198 | public static float GetBrightness(this Color color) 199 | { 200 | float num1 = (float)color.r * 255 / (float)byte.MaxValue; 201 | float num2 = (float)color.g * 255 / (float)byte.MaxValue; 202 | float num3 = (float)color.b * 255 / (float)byte.MaxValue; 203 | float num4 = num1; 204 | float num5 = num1; 205 | if ((double)num2 > (double)num4) 206 | num4 = num2; 207 | if ((double)num3 > (double)num4) 208 | num4 = num3; 209 | if ((double)num2 < (double)num5) 210 | num5 = num2; 211 | if ((double)num3 < (double)num5) 212 | num5 = num3; 213 | return (float)(((double)num4 + (double)num5) / 2.0); 214 | } 215 | 216 | public static float GetHue(this Color color) 217 | { 218 | if ((int)color.r == (int)color.g && (int)color.g == (int)color.b) 219 | return 0.0f; 220 | float num1 = (float)color.r * 255 / (float)byte.MaxValue; 221 | float num2 = (float)color.g * 255 / (float)byte.MaxValue; 222 | float num3 = (float)color.b * 255 / (float)byte.MaxValue; 223 | float num4 = 0.0f; 224 | float num5 = num1; 225 | float num6 = num1; 226 | if ((double)num2 > (double)num5) 227 | num5 = num2; 228 | if ((double)num3 > (double)num5) 229 | num5 = num3; 230 | if ((double)num2 < (double)num6) 231 | num6 = num2; 232 | if ((double)num3 < (double)num6) 233 | num6 = num3; 234 | float num7 = num5 - num6; 235 | if ((double)num1 == (double)num5) 236 | num4 = (num2 - num3) / num7; 237 | else if ((double)num2 == (double)num5) 238 | num4 = (float)(2.0 + ((double)num3 - (double)num1) / (double)num7); 239 | else if ((double)num3 == (double)num5) 240 | num4 = (float)(4.0 + ((double)num1 - (double)num2) / (double)num7); 241 | float num8 = num4 * 60f; 242 | if ((double)num8 < 0.0) 243 | num8 += 360f; 244 | return num8; 245 | } 246 | 247 | public static float GetSaturation(this Color color) 248 | { 249 | float num1 = (float)color.r * 255 / (float)byte.MaxValue; 250 | float num2 = (float)color.g * 255 / (float)byte.MaxValue; 251 | float num3 = (float)color.b * 255 / (float)byte.MaxValue; 252 | float num4 = 0.0f; 253 | float num5 = num1; 254 | float num6 = num1; 255 | if ((double)num2 > (double)num5) 256 | num5 = num2; 257 | if ((double)num3 > (double)num5) 258 | num5 = num3; 259 | if ((double)num2 < (double)num6) 260 | num6 = num2; 261 | if ((double)num3 < (double)num6) 262 | num6 = num3; 263 | if ((double)num5 != (double)num6) 264 | num4 = ((double)num5 + (double)num6) / 2.0 > 0.5 ? (float)(((double)num5 - (double)num6) / (2.0 - (double)num5 - (double)num6)) : (float)(((double)num5 - (double)num6) / ((double)num5 + (double)num6)); 265 | return num4; 266 | } 267 | } 268 | 269 | } -------------------------------------------------------------------------------- /UnityNativeCollision/Assets/Plugins/Vella.Common/NativeArrayNoLeakDetection.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: Unity.Collections.NativeArray2`1 3 | // Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null 4 | // MVID: 32BFBF54-11E9-4CC9-9520-34CE46722C3A 5 | // Assembly location: X:\UnityEditors\2019.1.0a14\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll 6 | 7 | using System; 8 | using System.Collections; 9 | using System.Collections.Generic; 10 | using System.Diagnostics; 11 | using System.Runtime.InteropServices; 12 | using Unity.Burst; 13 | using Unity.Collections; 14 | using Unity.Collections.LowLevel.Unsafe; 15 | using UnityEngine.Internal; 16 | 17 | namespace Vella.Common 18 | { 19 | /// 20 | /// A NativeArray2 exposes a buffer of native memory to managed code, making it possible to share data between managed and native without marshalling costs. 21 | /// 22 | [DebuggerTypeProxy(typeof(NativeArray2DebugView<>))] 23 | [NativeContainer] 24 | [DebuggerDisplay("Length = {Length}")] 25 | [NativeContainerSupportsDeallocateOnJobCompletion] 26 | [NativeContainerSupportsMinMaxWriteRestriction] 27 | [NativeContainerSupportsDeferredConvertListToArray] 28 | public struct NativeArrayNoLeakDetection : IDisposable, IEnumerable, IEquatable>, IEnumerable 29 | where T : struct 30 | { 31 | [NativeDisableUnsafePtrRestriction] 32 | internal unsafe void* m_Buffer; 33 | internal int m_Length; 34 | internal int m_MinIndex; 35 | internal int m_MaxIndex; 36 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 37 | internal AtomicSafetyHandle m_Safety; 38 | #endif 39 | 40 | //[NativeSetClassTypeToNullOnSchedule] 41 | //internal DisposeSentinel m_DisposeSentinel; 42 | 43 | internal Allocator m_AllocatorLabel; 44 | 45 | public unsafe NativeArrayNoLeakDetection(int length, Allocator allocator, NativeArrayOptions options = NativeArrayOptions.ClearMemory) 46 | { 47 | Allocate(length, allocator, out this); 48 | if ((options & NativeArrayOptions.ClearMemory) != NativeArrayOptions.ClearMemory) 49 | return; 50 | UnsafeUtility.MemClear(m_Buffer, (long)Length * (long)UnsafeUtility.SizeOf()); 51 | } 52 | 53 | public NativeArrayNoLeakDetection(T[] array, Allocator allocator) 54 | { 55 | if (array == null) 56 | throw new ArgumentNullException(nameof(array)); 57 | Allocate(array.Length, allocator, out this); 58 | Copy(array, this); 59 | } 60 | 61 | public NativeArrayNoLeakDetection(NativeArrayNoLeakDetection array, Allocator allocator) 62 | { 63 | Allocate(array.Length, allocator, out this); 64 | Copy(array, this); 65 | } 66 | 67 | private static unsafe void Allocate(int length, Allocator allocator, out NativeArrayNoLeakDetection array) 68 | { 69 | long size = (long)UnsafeUtility.SizeOf() * (long)length; 70 | if (allocator <= Allocator.None) 71 | throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); 72 | if (length < 0) 73 | throw new ArgumentOutOfRangeException(nameof(length), "Length must be >= 0"); 74 | IsBlittableAndThrow(); 75 | if (size > (long)int.MaxValue) 76 | throw new ArgumentOutOfRangeException(nameof(length), string.Format("Length * sizeof(T) cannot exceed {0} bytes", (object)int.MaxValue)); 77 | array.m_Buffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); 78 | array.m_Length = length; 79 | array.m_AllocatorLabel = allocator; 80 | array.m_MinIndex = 0; 81 | array.m_MaxIndex = length - 1; 82 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 83 | array.m_Safety = AtomicSafetyHandle.Create(); 84 | #endif 85 | //DisposeSentinel.Create(out array.m_Safety, out array.m_DisposeSentinel, 1, allocator); 86 | } 87 | 88 | public int Length 89 | { 90 | get 91 | { 92 | return m_Length; 93 | } 94 | } 95 | 96 | [BurstDiscard] 97 | internal static void IsBlittableAndThrow() 98 | { 99 | if (!UnsafeUtility.IsBlittable()) 100 | throw new InvalidOperationException(string.Format("{0} used in NativeArray2<{1}> must be blittable.", (object)typeof(T), (object)typeof(T))); 101 | } 102 | 103 | [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")] 104 | private unsafe void CheckElementReadAccess(int index) 105 | { 106 | if (index < m_MinIndex || index > m_MaxIndex) 107 | FailOutOfRangeError(index); 108 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 109 | AtomicSafetyHandle.CheckReadAndThrow(m_Safety); 110 | #endif 111 | } 112 | 113 | [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")] 114 | private unsafe void CheckElementWriteAccess(int index) 115 | { 116 | if (index < m_MinIndex || index > m_MaxIndex) 117 | FailOutOfRangeError(index); 118 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 119 | AtomicSafetyHandle.CheckWriteAndThrow(m_Safety); 120 | #endif 121 | } 122 | 123 | public unsafe T this[int index] 124 | { 125 | get 126 | { 127 | CheckElementReadAccess(index); 128 | return UnsafeUtility.ReadArrayElement(m_Buffer, index); 129 | } 130 | [WriteAccessRequired] 131 | set 132 | { 133 | CheckElementWriteAccess(index); 134 | UnsafeUtility.WriteArrayElement(m_Buffer, index, value); 135 | } 136 | } 137 | 138 | public unsafe bool IsCreated 139 | { 140 | get 141 | { 142 | return (IntPtr)m_Buffer != IntPtr.Zero; 143 | } 144 | } 145 | 146 | [WriteAccessRequired] 147 | public unsafe void Dispose() 148 | { 149 | if (!UnsafeUtility.IsValidAllocator(m_AllocatorLabel)) 150 | throw new InvalidOperationException("The NativeArray2 can not be Disposed because it was not allocated with a valid allocator."); 151 | 152 | // DisposeSentinel.Dispose(ref this.m_Safety, ref this.m_DisposeSentinel); 153 | 154 | UnsafeUtility.Free(m_Buffer, m_AllocatorLabel); 155 | m_Buffer = (void*)null; 156 | m_Length = 0; 157 | } 158 | 159 | [WriteAccessRequired] 160 | public void CopyFrom(T[] array) 161 | { 162 | Copy(array, this); 163 | } 164 | 165 | [WriteAccessRequired] 166 | public void CopyFrom(NativeArrayNoLeakDetection array) 167 | { 168 | Copy(array, this); 169 | } 170 | 171 | public void CopyTo(T[] array) 172 | { 173 | Copy(this, array); 174 | } 175 | 176 | public void CopyTo(NativeArrayNoLeakDetection array) 177 | { 178 | Copy(this, array); 179 | } 180 | 181 | public T[] ToArray() 182 | { 183 | T[] dst = new T[Length]; 184 | Copy(this, dst, Length); 185 | return dst; 186 | } 187 | 188 | private void FailOutOfRangeError(int index) 189 | { 190 | if (index < Length && (m_MinIndex != 0 || m_MaxIndex != Length - 1)) 191 | throw new IndexOutOfRangeException(string.Format("Index {0} is out of restricted IJobParallelFor range [{1}...{2}] in ReadWriteBuffer.\n", (object)index, (object)m_MinIndex, (object)m_MaxIndex) + "ReadWriteBuffers are restricted to only read & write the element at the job index. You can use double buffering strategies to avoid race conditions due to reading & writing in parallel to the same elements from a job."); 192 | throw new IndexOutOfRangeException(string.Format("Index {0} is out of range of '{1}' Length.", (object)index, (object)Length)); 193 | } 194 | 195 | public Enumerator GetEnumerator() 196 | { 197 | return new Enumerator(ref this); 198 | } 199 | 200 | IEnumerator IEnumerable.GetEnumerator() 201 | { 202 | return (IEnumerator)new Enumerator(ref this); 203 | } 204 | 205 | IEnumerator IEnumerable.GetEnumerator() 206 | { 207 | return (IEnumerator)GetEnumerator(); 208 | } 209 | 210 | public unsafe bool Equals(NativeArrayNoLeakDetection other) 211 | { 212 | return m_Buffer == other.m_Buffer && m_Length == other.m_Length; 213 | } 214 | 215 | public override bool Equals(object obj) 216 | { 217 | if (ReferenceEquals((object)null, obj)) 218 | return false; 219 | return obj is NativeArrayNoLeakDetection && Equals((NativeArrayNoLeakDetection)obj); 220 | } 221 | 222 | public override unsafe int GetHashCode() 223 | { 224 | return (int)m_Buffer * 397 ^ m_Length; 225 | } 226 | 227 | public static bool operator ==(NativeArrayNoLeakDetection left, NativeArrayNoLeakDetection right) 228 | { 229 | return left.Equals(right); 230 | } 231 | 232 | public static bool operator !=(NativeArrayNoLeakDetection left, NativeArrayNoLeakDetection right) 233 | { 234 | return !left.Equals(right); 235 | } 236 | 237 | public static void Copy(NativeArrayNoLeakDetection src, NativeArrayNoLeakDetection dst) 238 | { 239 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 240 | AtomicSafetyHandle.CheckReadAndThrow(src.m_Safety); 241 | AtomicSafetyHandle.CheckWriteAndThrow(dst.m_Safety); 242 | #endif 243 | if (src.Length != dst.Length) 244 | throw new ArgumentException("source and destination length must be the same"); 245 | Copy(src, 0, dst, 0, src.Length); 246 | } 247 | 248 | public static void Copy(T[] src, NativeArrayNoLeakDetection dst) 249 | { 250 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 251 | AtomicSafetyHandle.CheckWriteAndThrow(dst.m_Safety); 252 | #endif 253 | if (src.Length != dst.Length) 254 | throw new ArgumentException("source and destination length must be the same"); 255 | Copy(src, 0, dst, 0, src.Length); 256 | } 257 | 258 | public static void Copy(NativeArrayNoLeakDetection src, T[] dst) 259 | { 260 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 261 | AtomicSafetyHandle.CheckReadAndThrow(src.m_Safety); 262 | #endif 263 | if (src.Length != dst.Length) 264 | throw new ArgumentException("source and destination length must be the same"); 265 | Copy(src, 0, dst, 0, src.Length); 266 | } 267 | 268 | public static void Copy(NativeArrayNoLeakDetection src, NativeArrayNoLeakDetection dst, int length) 269 | { 270 | Copy(src, 0, dst, 0, length); 271 | } 272 | 273 | public static void Copy(T[] src, NativeArrayNoLeakDetection dst, int length) 274 | { 275 | Copy(src, 0, dst, 0, length); 276 | } 277 | 278 | public static void Copy(NativeArrayNoLeakDetection src, T[] dst, int length) 279 | { 280 | Copy(src, 0, dst, 0, length); 281 | } 282 | 283 | public static unsafe void Copy( 284 | NativeArrayNoLeakDetection src, 285 | int srcIndex, 286 | NativeArrayNoLeakDetection dst, 287 | int dstIndex, 288 | int length) 289 | { 290 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 291 | AtomicSafetyHandle.CheckReadAndThrow(src.m_Safety); 292 | AtomicSafetyHandle.CheckWriteAndThrow(dst.m_Safety); 293 | #endif 294 | if (length < 0) 295 | throw new ArgumentOutOfRangeException(nameof(length), "length must be equal or greater than zero."); 296 | if (srcIndex < 0 || srcIndex > src.Length || srcIndex == src.Length && src.Length > 0) 297 | throw new ArgumentOutOfRangeException(nameof(srcIndex), "srcIndex is outside the range of valid indexes for the source NativeArray2."); 298 | if (dstIndex < 0 || dstIndex > dst.Length || dstIndex == dst.Length && dst.Length > 0) 299 | throw new ArgumentOutOfRangeException(nameof(dstIndex), "dstIndex is outside the range of valid indexes for the destination NativeArray2."); 300 | if (srcIndex + length > src.Length) 301 | throw new ArgumentException("length is greater than the number of elements from srcIndex to the end of the source NativeArray2.", nameof(length)); 302 | if (dstIndex + length > dst.Length) 303 | throw new ArgumentException("length is greater than the number of elements from dstIndex to the end of the destination NativeArray2.", nameof(length)); 304 | UnsafeUtility.MemCpy((void*)((IntPtr)dst.m_Buffer + (dstIndex * UnsafeUtility.SizeOf())), (void*)((IntPtr)src.m_Buffer + (srcIndex * UnsafeUtility.SizeOf())), (long)(length * UnsafeUtility.SizeOf())); 305 | } 306 | 307 | public static unsafe void Copy( 308 | T[] src, 309 | int srcIndex, 310 | NativeArrayNoLeakDetection dst, 311 | int dstIndex, 312 | int length) 313 | { 314 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 315 | AtomicSafetyHandle.CheckWriteAndThrow(dst.m_Safety); 316 | #endif 317 | if (src == null) 318 | throw new ArgumentNullException(nameof(src)); 319 | if (length < 0) 320 | throw new ArgumentOutOfRangeException(nameof(length), "length must be equal or greater than zero."); 321 | if (srcIndex < 0 || srcIndex > src.Length || srcIndex == src.Length && src.Length > 0) 322 | throw new ArgumentOutOfRangeException(nameof(srcIndex), "srcIndex is outside the range of valid indexes for the source array."); 323 | if (dstIndex < 0 || dstIndex > dst.Length || dstIndex == dst.Length && dst.Length > 0) 324 | throw new ArgumentOutOfRangeException(nameof(dstIndex), "dstIndex is outside the range of valid indexes for the destination NativeArray2."); 325 | if (srcIndex + length > src.Length) 326 | throw new ArgumentException("length is greater than the number of elements from srcIndex to the end of the source array.", nameof(length)); 327 | if (dstIndex + length > dst.Length) 328 | throw new ArgumentException("length is greater than the number of elements from dstIndex to the end of the destination NativeArray2.", nameof(length)); 329 | GCHandle gcHandle = GCHandle.Alloc((object)src, GCHandleType.Pinned); 330 | IntPtr num = gcHandle.AddrOfPinnedObject(); 331 | UnsafeUtility.MemCpy((void*)((IntPtr)dst.m_Buffer + (dstIndex * UnsafeUtility.SizeOf())), (void*)(num + (srcIndex * UnsafeUtility.SizeOf())), (long)(length * UnsafeUtility.SizeOf())); 332 | gcHandle.Free(); 333 | } 334 | 335 | public static unsafe void Copy( 336 | NativeArrayNoLeakDetection src, 337 | int srcIndex, 338 | T[] dst, 339 | int dstIndex, 340 | int length) 341 | { 342 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 343 | AtomicSafetyHandle.CheckReadAndThrow(src.m_Safety); 344 | #endif 345 | if (dst == null) 346 | throw new ArgumentNullException(nameof(dst)); 347 | if (length < 0) 348 | throw new ArgumentOutOfRangeException(nameof(length), "length must be equal or greater than zero."); 349 | if (srcIndex < 0 || srcIndex > src.Length || srcIndex == src.Length && src.Length > 0) 350 | throw new ArgumentOutOfRangeException(nameof(srcIndex), "srcIndex is outside the range of valid indexes for the source NativeArray2."); 351 | if (dstIndex < 0 || dstIndex > dst.Length || dstIndex == dst.Length && dst.Length > 0) 352 | throw new ArgumentOutOfRangeException(nameof(dstIndex), "dstIndex is outside the range of valid indexes for the destination array."); 353 | if (srcIndex + length > src.Length) 354 | throw new ArgumentException("length is greater than the number of elements from srcIndex to the end of the source NativeArray2.", nameof(length)); 355 | if (dstIndex + length > dst.Length) 356 | throw new ArgumentException("length is greater than the number of elements from dstIndex to the end of the destination array.", nameof(length)); 357 | GCHandle gcHandle = GCHandle.Alloc((object)dst, GCHandleType.Pinned); 358 | UnsafeUtility.MemCpy((void*)((IntPtr)(void*)gcHandle.AddrOfPinnedObject() + (dstIndex * UnsafeUtility.SizeOf())), (void*)((IntPtr)src.m_Buffer + (srcIndex * UnsafeUtility.SizeOf())), (long)(length * UnsafeUtility.SizeOf())); 359 | gcHandle.Free(); 360 | } 361 | 362 | [ExcludeFromDocs] 363 | public struct Enumerator : IEnumerator, IEnumerator, IDisposable 364 | { 365 | private NativeArrayNoLeakDetection m_Array; 366 | private int m_Index; 367 | 368 | public Enumerator(ref NativeArrayNoLeakDetection array) 369 | { 370 | m_Array = array; 371 | m_Index = -1; 372 | } 373 | 374 | public void Dispose() 375 | { 376 | } 377 | 378 | public bool MoveNext() 379 | { 380 | ++m_Index; 381 | return m_Index < m_Array.Length; 382 | } 383 | 384 | public void Reset() 385 | { 386 | m_Index = -1; 387 | } 388 | 389 | public T Current 390 | { 391 | get 392 | { 393 | return m_Array[m_Index]; 394 | } 395 | } 396 | 397 | object IEnumerator.Current 398 | { 399 | get 400 | { 401 | return (object)Current; 402 | } 403 | } 404 | } 405 | 406 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 407 | public AtomicSafetyHandle GetAtomicSafetyHandle(NativeArray array) 408 | { 409 | return m_Safety; 410 | } 411 | #endif 412 | 413 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 414 | public void SetAtomicSafetyHandle(ref NativeArray array, AtomicSafetyHandle safety) 415 | { 416 | m_Safety = safety; 417 | } 418 | #endif 419 | 420 | public unsafe void* GetUnsafePtr() 421 | { 422 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 423 | AtomicSafetyHandle.CheckWriteAndThrow(m_Safety); 424 | #endif 425 | return m_Buffer; 426 | } 427 | 428 | public unsafe void* GetUnsafeReadOnlyPtr() 429 | { 430 | #if ENABLE_UNITY_COLLECTIONS_CHECKS 431 | AtomicSafetyHandle.CheckReadAndThrow(m_Safety); 432 | #endif 433 | return m_Buffer; 434 | } 435 | 436 | public unsafe void* GetUnsafeBufferPointerWithoutChecks() 437 | { 438 | return m_Buffer; 439 | } 440 | 441 | } 442 | 443 | internal sealed class NativeArray2DebugView where T : struct 444 | { 445 | private NativeArrayNoLeakDetection m_Array; 446 | 447 | public NativeArray2DebugView(NativeArrayNoLeakDetection array) 448 | { 449 | m_Array = array; 450 | } 451 | 452 | public T[] Items 453 | { 454 | get 455 | { 456 | return m_Array.ToArray(); 457 | } 458 | } 459 | } 460 | } 461 | --------------------------------------------------------------------------------