com.wallstop-studios.unity-helpers 2.0.0-rc81.9 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +1 -1
- package/.gitattributes +1 -1
- package/.githooks/pre-commit +31 -5
- package/.githooks/pre-push +50 -0
- package/.github/dependabot.yml +24 -2
- package/.github/scripts/check-markdown-links.ps1 +77 -0
- package/.github/scripts/check_markdown_links.py +89 -0
- package/.github/scripts/check_markdown_url_encoding.py +74 -0
- package/.github/scripts/validate_markdown_links.py +194 -0
- package/.github/workflows/csharpier-autofix.yml +152 -0
- package/.github/workflows/format-on-demand.yml +305 -0
- package/.github/workflows/lint-doc-links.yml +8 -5
- package/.github/workflows/markdown-json.yml +6 -2
- package/.github/workflows/npm-publish.yml +1 -1
- package/.github/workflows/prettier-autofix.yml +195 -0
- package/.github/workflows/update-dotnet-tools.yml +80 -0
- package/.github/workflows/yaml-format-lint.yml +41 -0
- package/.lychee.toml +4 -4
- package/.markdownlint.jsonc +21 -0
- package/.pre-commit-config.yaml +11 -3
- package/.yamllint.yaml +31 -0
- package/AGENTS.md +5 -1
- package/Docs/CHANGELOG.md +11 -0
- package/Docs/CONTRIBUTING.md +49 -0
- package/Docs/CONTRIBUTING.md.meta +7 -0
- package/{EDITOR_TOOLS_GUIDE.md → Docs/EDITOR_TOOLS_GUIDE.md} +4 -0
- package/Docs/EFFECTS_SYSTEM.md +1316 -0
- package/{EFFECTS_SYSTEM_TUTORIAL.md → Docs/EFFECTS_SYSTEM_TUTORIAL.md} +1 -1
- package/{GETTING_STARTED.md → Docs/GETTING_STARTED.md} +50 -64
- package/{GLOSSARY.md → Docs/GLOSSARY.md} +4 -4
- package/Docs/HELPER_UTILITIES.md +885 -0
- package/Docs/HELPER_UTILITIES.md.meta +7 -0
- package/{INDEX.md → Docs/INDEX.md} +107 -62
- package/Docs/MATH_AND_EXTENSIONS.md +1039 -0
- package/{RANDOM_PERFORMANCE.md → Docs/RANDOM_PERFORMANCE.md} +15 -15
- package/{RELATIONAL_COMPONENTS.md → Docs/RELATIONAL_COMPONENTS.md} +111 -84
- package/{SERIALIZATION.md → Docs/SERIALIZATION.md} +15 -0
- package/{SPATIAL_TREES_2D_GUIDE.md → Docs/SPATIAL_TREES_2D_GUIDE.md} +2 -2
- package/{SPATIAL_TREES_3D_GUIDE.md → Docs/SPATIAL_TREES_3D_GUIDE.md} +1 -1
- package/Docs/SPATIAL_TREE_2D_PERFORMANCE.md +241 -0
- package/Docs/SPATIAL_TREE_3D_PERFORMANCE.md +243 -0
- package/{THIRD_PARTY_NOTICES.md → Docs/THIRD_PARTY_NOTICES.md} +1 -1
- package/Docs/UTILITY_COMPONENTS.md +906 -0
- package/Docs/UTILITY_COMPONENTS.md.meta +7 -0
- package/Docs/VISUAL_COMPONENTS.md +337 -0
- package/Docs/VISUAL_COMPONENTS.md.meta +7 -0
- package/Editor/AnimationEventEditor.cs +337 -160
- package/Editor/Core/Helper/AnimationEventHelpers.cs +178 -152
- package/Editor/CustomEditors/PersistentDirectoryGUI.cs +20 -11
- package/Editor/CustomEditors/TexturePlatformOverrideEntryDrawer.cs +11 -2
- package/Editor/FitTextureSizeWindow.cs +43 -19
- package/Editor/PersistentDirectorySettings.cs +64 -12
- package/Editor/PrefabChecker.cs +72 -5
- package/Editor/Sprites/AnimationCopier.cs +131 -55
- package/Editor/Sprites/AnimationCreator.cs +63 -22
- package/Editor/Sprites/AnimationViewerWindow.cs +42 -6
- package/Editor/Sprites/TexturePlatformNameHelper.cs +50 -39
- package/Editor/Sprites/TextureResizerWizard.cs +23 -1
- package/Editor/Sprites/TextureSettingsApplierWindow.cs +148 -85
- package/Editor/Tools/ImageBlurTool.cs +81 -10
- package/Editor/Utils/EditorUi.cs +1 -1
- package/Editor/Utils/ScriptableObjectSingletonCreator.cs +1 -1
- package/README.md +428 -2433
- package/Runtime/AssemblyInfo.cs +4 -0
- package/Runtime/Core/Attributes/NotNullAttribute.cs +1 -3
- package/Runtime/Core/Attributes/RelationalComponentAssigner.cs +50 -5
- package/Runtime/Core/DataStructure/CyclicBuffer.cs +0 -1
- package/Runtime/Core/DataStructure/KDTree3D.cs +1 -1
- package/Runtime/Core/DataStructure/OctTree3D.cs +1 -1
- package/Runtime/Core/Extension/AsyncOperationExtensions.cs +122 -0
- package/Runtime/Core/Extension/RandomExtensions.cs +68 -0
- package/Runtime/Core/Extension/WallstopStudiosLogger.cs +16 -0
- package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +4 -1
- package/Runtime/Core/Helper/ReflectionHelpers.cs +21 -10
- package/Runtime/Core/Helper/SpriteHelpers.cs +3 -1
- package/Runtime/Core/Helper/UnityMainThreadDispatcher.cs +45 -1
- package/Runtime/Core/Serialization/JsonConverters/GameObjectConverter.cs +13 -5
- package/Runtime/Core/Serialization/JsonConverters/ResolutionConverter.cs +1 -1
- package/Runtime/Core/Serialization/JsonConverters/TypeConverter.cs +1 -1
- package/Runtime/Core/Serialization/ProtobufUnitySurrogates.cs +24 -29
- package/Runtime/Core/Serialization/Serializer.cs +101 -0
- package/Runtime/Integrations/Reflex/AssemblyInfo.cs +7 -0
- package/Runtime/Integrations/Reflex/AssemblyInfo.cs.meta +11 -0
- package/Runtime/Integrations/Reflex/ContainerRelationalExtensions.cs +198 -0
- package/Runtime/Integrations/Reflex/ContainerRelationalExtensions.cs.meta +11 -0
- package/Runtime/Integrations/Reflex/RelationalComponentsInstaller.cs +86 -0
- package/Runtime/Integrations/Reflex/RelationalComponentsInstaller.cs.meta +11 -0
- package/Runtime/Integrations/Reflex/RelationalReflexSceneBootstrapper.cs +316 -0
- package/Runtime/Integrations/Reflex/RelationalReflexSceneBootstrapper.cs.meta +11 -0
- package/Runtime/Integrations/Reflex/RelationalSceneAssignmentOptions.cs +86 -0
- package/Runtime/Integrations/Reflex/RelationalSceneAssignmentOptions.cs.meta +11 -0
- package/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Integration.Reflex.asmdef +20 -0
- package/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Integration.Reflex.asmdef.meta +7 -0
- package/Runtime/Integrations/Reflex.meta +8 -0
- package/Runtime/Integrations/VContainer/AssemblyInfo.cs +9 -0
- package/Runtime/Integrations/VContainer/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Integrations/VContainer/ObjectResolverRelationalExtensions.cs +96 -0
- package/Runtime/Integrations/VContainer/RelationalComponentEntryPoint.cs +90 -10
- package/Runtime/Integrations/VContainer/RelationalComponentsBuilderExtensions.cs +13 -1
- package/Runtime/Integrations/VContainer/RelationalObjectPools.cs +114 -0
- package/Runtime/Integrations/VContainer/RelationalObjectPools.cs.meta +11 -0
- package/Runtime/Integrations/VContainer/RelationalSceneAssignmentOptions.cs +16 -4
- package/Runtime/Integrations/VContainer/RelationalSceneLoadListener.cs +241 -0
- package/Runtime/Integrations/VContainer/RelationalSceneLoadListener.cs.meta +11 -0
- package/Runtime/Integrations/Zenject/AssemblyInfo.cs +9 -0
- package/Runtime/Integrations/Zenject/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Integrations/Zenject/DiContainerRelationalExtensions.cs +69 -2
- package/Runtime/Integrations/Zenject/RelationalComponentSceneInitializer.cs +89 -12
- package/Runtime/Integrations/Zenject/RelationalComponentsInstaller.cs +23 -1
- package/Runtime/Integrations/Zenject/RelationalMemoryPools.cs +44 -0
- package/Runtime/Integrations/Zenject/RelationalMemoryPools.cs.meta +11 -0
- package/Runtime/Integrations/Zenject/RelationalSceneAssignmentOptions.cs +16 -10
- package/Runtime/Integrations/Zenject/RelationalSceneLoadListener.cs +243 -0
- package/Runtime/Integrations/Zenject/RelationalSceneLoadListener.cs.meta +11 -0
- package/Runtime/Tags/AttributeMetadataCache.cs +1 -4
- package/Runtime/Utils/Buffers.cs +4 -4
- package/Runtime/Utils/ScriptableObjectSingleton.cs +1 -2
- package/Runtime/Utils/SetTextureImportData.cs +3 -1
- package/Runtime/Utils/TextureScale.cs +10 -2
- package/Runtime/Visuals/UGUI/EnhancedImage.cs +6 -0
- package/Runtime/Visuals/UIToolkit/LayeredImage.cs +4 -1
- package/Samples~/DI - Reflex/README.md +527 -0
- package/Samples~/DI - Reflex/README.md.meta +7 -0
- package/Samples~/DI - Reflex/Scripts/ReflexPaletteService.cs +36 -0
- package/Samples~/DI - Reflex/Scripts/ReflexPaletteService.cs.meta +11 -0
- package/Samples~/DI - Reflex/Scripts/ReflexRelationalConsumer.cs +79 -0
- package/Samples~/DI - Reflex/Scripts/ReflexRelationalConsumer.cs.meta +11 -0
- package/Samples~/DI - Reflex/Scripts/ReflexSampleInstaller.cs +30 -0
- package/Samples~/DI - Reflex/Scripts/ReflexSampleInstaller.cs.meta +11 -0
- package/Samples~/DI - Reflex/Scripts/ReflexSpawner.cs +79 -0
- package/Samples~/DI - Reflex/Scripts/ReflexSpawner.cs.meta +11 -0
- package/Samples~/DI - Reflex/Scripts/Samples.UnityHelpers.DI.Reflex.asmdef +26 -0
- package/Samples~/DI - Reflex/Scripts/Samples.UnityHelpers.DI.Reflex.asmdef.meta +9 -0
- package/Samples~/DI - Reflex/Scripts.meta +8 -0
- package/Samples~/DI - Reflex.meta +8 -0
- package/Samples~/DI - VContainer/README.md +238 -56
- package/Samples~/DI - VContainer/Scripts/GameLifetimeScope.cs +22 -4
- package/Samples~/DI - VContainer/Scripts/RelationalConsumer.cs +5 -2
- package/Samples~/DI - VContainer/Scripts/Spawner.cs +113 -4
- package/Samples~/DI - Zenject/README.md +223 -58
- package/Samples~/DI - Zenject/Scripts/RelationalConsumer.cs +3 -0
- package/Samples~/DI - Zenject/Scripts/RelationalConsumerPool.cs +37 -0
- package/Samples~/DI - Zenject/Scripts/RelationalConsumerPool.cs.meta +12 -0
- package/Samples~/DI - Zenject/Scripts/SpawnerZenject.cs +74 -3
- package/Samples~/Random - PRNG/README.md +2 -1
- package/Samples~/Relational Components - Basic/README.md +3 -1
- package/Samples~/Serialization - JSON/README.md +2 -1
- package/Samples~/Spatial Structures - 2D and 3D/README.md +2 -1
- package/Samples~/UGUI - EnhancedImage/README.md +2 -1
- package/Samples~/UI Toolkit - MultiFile Selector (Editor)/README.md +2 -1
- package/Tests/Editor/Attributes/AnimationEventHelpersTests.cs +16 -0
- package/Tests/Editor/Core/Attributes/RelationalComponentAssignerTests.cs +32 -34
- package/Tests/Editor/Integrations/Reflex/ReflexIntegrationCompilationTests.cs +41 -0
- package/Tests/Editor/Integrations/Reflex/ReflexIntegrationCompilationTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Editor.Reflex.asmdef +27 -0
- package/Tests/Editor/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Editor.Reflex.asmdef.meta +7 -0
- package/Tests/Editor/Integrations/Reflex.meta +8 -0
- package/Tests/Editor/Integrations/VContainer/VContainerRelationalEntryPointTests.cs +21 -18
- package/Tests/Editor/Integrations/VContainer/VContainerRelationalHelpersTests.cs +164 -0
- package/Tests/Editor/Integrations/VContainer/VContainerRelationalHelpersTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/VContainer/WallstopStudios.UnityHelpers.Tests.Editor.VContainer.asmdef +2 -1
- package/Tests/Editor/Integrations/Zenject/WallstopStudios.UnityHelpers.Tests.Editor.Zenject.asmdef +3 -2
- package/Tests/Editor/Integrations/Zenject/ZenjectRelationalHelpersTests.cs +127 -0
- package/Tests/Editor/Integrations/Zenject/ZenjectRelationalHelpersTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/Zenject/ZenjectRelationalInitializerTests.cs +25 -23
- package/Tests/Editor/PersistentDirectorySettingsTests.cs +58 -0
- package/Tests/Editor/PersistentDirectorySettingsTests.cs.meta +11 -0
- package/Tests/Editor/PrefabCheckerReportTests.cs +32 -0
- package/Tests/Editor/PrefabCheckerReportTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs +63 -0
- package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/AnimationCopierWindowTests.cs +1 -1
- package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs +38 -0
- package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/ScriptableSpriteAtlasEditorTests.cs +1 -1
- package/Tests/Editor/Sprites/SpriteCropperAdditionalTests.cs +12 -12
- package/Tests/Editor/Sprites/SpriteCropperTests.cs +9 -9
- package/Tests/Editor/Sprites/SpritePivotAdjusterTests.cs +3 -3
- package/Tests/Editor/Sprites/TexturePlatformNameHelperTests.cs +18 -0
- package/Tests/Editor/Sprites/TextureResizerWizardTests.cs +5 -5
- package/Tests/Editor/Sprites/TextureSettingsApplierAPITests.cs +3 -3
- package/Tests/Editor/Sprites/TextureSettingsApplierWizardAdditionalTests.cs +4 -4
- package/Tests/Editor/Sprites/TextureSettingsApplierWizardTests.cs +4 -4
- package/Tests/Editor/Tools/ImageBlurToolTests.cs +22 -110
- package/Tests/Editor/Utils/CommonTestBase.cs +60 -1
- package/Tests/Editor/Utils/ScriptableObjectSingletonCreatorTests.cs +6 -6
- package/Tests/Editor/Windows/FitTextureSizeWindowTests.cs +66 -74
- package/Tests/Runtime/Attributes/RelationalComponentInitializerTests.cs +4 -15
- package/Tests/Runtime/DataStructures/SpatialTree3DBoundsConsistencyTests.cs +29 -29
- package/Tests/Runtime/Extensions/AsyncOperationExtensionsTests.cs +179 -0
- package/Tests/Runtime/Extensions/RandomExtensionTests.cs +55 -0
- package/Tests/Runtime/Integrations/Reflex/RelationalComponentsReflexTests.cs +445 -0
- package/Tests/Runtime/Integrations/Reflex/RelationalComponentsReflexTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Runtime.Reflex.asmdef +28 -0
- package/Tests/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Runtime.Reflex.asmdef.meta +7 -0
- package/Tests/Runtime/Integrations/Reflex.meta +8 -0
- package/Tests/Runtime/Integrations/VContainer/RelationalComponentsVContainerTests.cs +257 -221
- package/Tests/Runtime/Integrations/VContainer/RelationalObjectPoolsVContainerTests.cs +91 -0
- package/Tests/Runtime/Integrations/VContainer/RelationalObjectPoolsVContainerTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/Zenject/RelationalComponentsZenjectTests.cs +251 -233
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs +1 -1
- package/Tests/Runtime/Performance/SpatialTree2DPerformanceTests.cs +6 -1
- package/Tests/Runtime/Performance/SpatialTree3DPerformanceTests.cs +4 -1
- package/Tests/Runtime/Serialization/JsonConverterAdditionalTests.cs +30 -0
- package/Tests/Runtime/Serialization/JsonConverterAdditionalTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/JsonConverterTests.cs +8 -12
- package/Tests/Runtime/Serialization/JsonRoundtripComprehensiveTests.cs +4 -9
- package/Tests/Runtime/Serialization/JsonSerializationTest.cs +16 -5
- package/Tests/Runtime/Serialization/ProtoRoundtripComprehensiveTests.cs +13 -13
- package/Tests/Runtime/Serialization/SerializerAdditionalTests.cs +12 -0
- package/Tests/Runtime/Serialization/SerializerFileIoTests.cs +105 -0
- package/Tests/Runtime/Serialization/SerializerFileIoTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/UnityEngineObjectJsonTests.cs +247 -0
- package/Tests/Runtime/Serialization/UnityEngineObjectJsonTests.cs.meta +11 -0
- package/Tests/Runtime/TestUtils/CommonTestBase.cs +99 -0
- package/Tests/Runtime/TestUtils/ReflexTestSupport.cs +111 -0
- package/Tests/Runtime/TestUtils/ReflexTestSupport.cs.meta +12 -0
- package/Tests/Runtime/Utils/CoroutineHandlerTests.cs +1 -1
- package/Tests/Runtime/Utils/LZMAComprehensiveTests.cs +1 -1
- package/Tests/Runtime/Utils/LZMATests.cs +1 -1
- package/Tests/Runtime/Utils/MatchColliderToSpriteTests.cs +5 -5
- package/Tests/Runtime/Visuals/EnhancedImageTests.cs +25 -56
- package/Tests/Runtime/Visuals/VisualsTestHelpers.cs +1 -8
- package/Tests/TestUtils.meta +8 -0
- package/package-lock.json.meta +7 -0
- package/package.json +13 -4
- package/scripts/check-eol.ps1 +4 -5
- package/scripts/lint-tests.ps1 +156 -0
- package/scripts/lint-tests.ps1.meta +7 -0
- package/scripts/normalize-eol.ps1 +6 -9
- package/.github/workflows/csharpier.yml +0 -135
- package/CHANGELOG.md +0 -0
- package/EFFECTS_SYSTEM.md +0 -242
- package/MATH_AND_EXTENSIONS.md +0 -316
- package/SPATIAL_TREE_2D_PERFORMANCE.md +0 -238
- package/SPATIAL_TREE_3D_PERFORMANCE.md +0 -240
- /package/{CHANGELOG.md.meta → Docs/CHANGELOG.md.meta} +0 -0
- /package/{DATA_STRUCTURES.md → Docs/DATA_STRUCTURES.md} +0 -0
- /package/{DATA_STRUCTURES.md.meta → Docs/DATA_STRUCTURES.md.meta} +0 -0
- /package/{EDITOR_TOOLS_GUIDE.md.meta → Docs/EDITOR_TOOLS_GUIDE.md.meta} +0 -0
- /package/{EFFECTS_SYSTEM.md.meta → Docs/EFFECTS_SYSTEM.md.meta} +0 -0
- /package/{EFFECTS_SYSTEM_TUTORIAL.md.meta → Docs/EFFECTS_SYSTEM_TUTORIAL.md.meta} +0 -0
- /package/{GETTING_STARTED.md.meta → Docs/GETTING_STARTED.md.meta} +0 -0
- /package/{GLOSSARY.md.meta → Docs/GLOSSARY.md.meta} +0 -0
- /package/{HULLS.md → Docs/HULLS.md} +0 -0
- /package/{HULLS.md.meta → Docs/HULLS.md.meta} +0 -0
- /package/{INDEX.md.meta → Docs/INDEX.md.meta} +0 -0
- /package/{LICENSE.md → Docs/LICENSE.md} +0 -0
- /package/{LICENSE.md.meta → Docs/LICENSE.md.meta} +0 -0
- /package/{MATH_AND_EXTENSIONS.md.meta → Docs/MATH_AND_EXTENSIONS.md.meta} +0 -0
- /package/{RANDOM_PERFORMANCE.md.meta → Docs/RANDOM_PERFORMANCE.md.meta} +0 -0
- /package/{REFLECTION_HELPERS.md → Docs/REFLECTION_HELPERS.md} +0 -0
- /package/{REFLECTION_HELPERS.md.meta → Docs/REFLECTION_HELPERS.md.meta} +0 -0
- /package/{RELATIONAL_COMPONENTS.md.meta → Docs/RELATIONAL_COMPONENTS.md.meta} +0 -0
- /package/{SERIALIZATION.md.meta → Docs/SERIALIZATION.md.meta} +0 -0
- /package/{SINGLETONS.md → Docs/SINGLETONS.md} +0 -0
- /package/{SINGLETONS.md.meta → Docs/SINGLETONS.md.meta} +0 -0
- /package/{SPATIAL_TREES_2D_GUIDE.md.meta → Docs/SPATIAL_TREES_2D_GUIDE.md.meta} +0 -0
- /package/{SPATIAL_TREES_3D_GUIDE.md.meta → Docs/SPATIAL_TREES_3D_GUIDE.md.meta} +0 -0
- /package/{SPATIAL_TREE_2D_PERFORMANCE.md.meta → Docs/SPATIAL_TREE_2D_PERFORMANCE.md.meta} +0 -0
- /package/{SPATIAL_TREE_3D_PERFORMANCE.md.meta → Docs/SPATIAL_TREE_3D_PERFORMANCE.md.meta} +0 -0
- /package/{SPATIAL_TREE_SEMANTICS.md → Docs/SPATIAL_TREE_SEMANTICS.md} +0 -0
- /package/{SPATIAL_TREE_SEMANTICS.md.meta → Docs/SPATIAL_TREE_SEMANTICS.md.meta} +0 -0
- /package/{THIRD_PARTY_NOTICES.md.meta → Docs/THIRD_PARTY_NOTICES.md.meta} +0 -0
|
@@ -81,18 +81,18 @@ This document contains performance benchmarks for the various random number gene
|
|
|
81
81
|
|
|
82
82
|
| Random | NextBool | Next | NextUInt | NextFloat | NextDouble | NextUint - Range | NextInt - Range |
|
|
83
83
|
| --------------------------- | ----------- | ----------- | ------------- | ----------- | ----------- | ---------------- | --------------- |
|
|
84
|
-
| DotNetRandom |
|
|
85
|
-
| LinearCongruentialGenerator |
|
|
86
|
-
| IllusionFlow |
|
|
87
|
-
| PcgRandom |
|
|
88
|
-
| RomuDuo |
|
|
89
|
-
| SplitMix64 |
|
|
90
|
-
| SquirrelRandom |
|
|
91
|
-
| SystemRandom |
|
|
92
|
-
| UnityRandom |
|
|
93
|
-
| WyRandom |
|
|
94
|
-
| XorShiftRandom |
|
|
95
|
-
| XoroShiroRandom |
|
|
84
|
+
| DotNetRandom | 550,600,000 | 53,100,000 | 57,400,000 | 45,600,000 | 26,900,000 | 53,700,000 | 53,900,000 |
|
|
85
|
+
| LinearCongruentialGenerator | 814,800,000 | 538,900,000 | 1,335,100,000 | 184,700,000 | 296,500,000 | 591,500,000 | 508,400,000 |
|
|
86
|
+
| IllusionFlow | 800,200,000 | 489,500,000 | 892,600,000 | 167,600,000 | 268,200,000 | 444,600,000 | 396,100,000 |
|
|
87
|
+
| PcgRandom | 796,400,000 | 537,900,000 | 889,500,000 | 184,300,000 | 291,400,000 | 456,500,000 | 412,000,000 |
|
|
88
|
+
| RomuDuo | 794,300,000 | 359,300,000 | 766,200,000 | 167,200,000 | 191,600,000 | 446,000,000 | 397,600,000 |
|
|
89
|
+
| SplitMix64 | 801,100,000 | 537,400,000 | 972,300,000 | 183,800,000 | 296,600,000 | 487,500,000 | 446,600,000 |
|
|
90
|
+
| SquirrelRandom | 747,700,000 | 383,300,000 | 413,800,000 | 172,300,000 | 204,800,000 | 330,200,000 | 314,200,000 |
|
|
91
|
+
| SystemRandom | 146,800,000 | 148,300,000 | 65,700,000 | 132,500,000 | 139,500,000 | 59,800,000 | 61,300,000 |
|
|
92
|
+
| UnityRandom | 647,700,000 | 77,800,000 | 87,800,000 | 62,100,000 | 39,500,000 | 81,500,000 | 82,400,000 |
|
|
93
|
+
| WyRandom | 750,700,000 | 382,900,000 | 447,500,000 | 166,800,000 | 191,700,000 | 296,800,000 | 281,100,000 |
|
|
94
|
+
| XorShiftRandom | 792,900,000 | 536,400,000 | 606,000,000 | 184,100,000 | 287,300,000 | 442,800,000 | 391,200,000 |
|
|
95
|
+
| XoroShiroRandom | 789,200,000 | 359,300,000 | 715,100,000 | 167,300,000 | 192,500,000 | 428,900,000 | 383,500,000 |
|
|
96
96
|
|
|
97
97
|
<!-- RANDOM_BENCHMARKS_END -->
|
|
98
98
|
|
|
@@ -124,13 +124,13 @@ All benchmarks are run for 1 second per operation type to ensure statistical sig
|
|
|
124
124
|
**Core Guides:**
|
|
125
125
|
|
|
126
126
|
- [Getting Started](GETTING_STARTED.md) - Your first 5 minutes with Unity Helpers
|
|
127
|
-
- [Main README](README.md) - Complete feature overview
|
|
127
|
+
- [Main README](../README.md) - Complete feature overview
|
|
128
128
|
- [Feature Index](INDEX.md) - Alphabetical reference
|
|
129
129
|
|
|
130
130
|
**Random Number Generator Features:**
|
|
131
131
|
|
|
132
|
-
- [README - Random Generators](README.md#random-number-generators) - Full API reference
|
|
133
|
-
- [README - Quick Start](README.md#random-number-generation) - 60-second tutorial
|
|
132
|
+
- [README - Random Generators](../README.md#random-number-generators) - Full API reference
|
|
133
|
+
- [README - Quick Start](../README.md#random-number-generation) - 60-second tutorial
|
|
134
134
|
|
|
135
135
|
**Related Features:**
|
|
136
136
|
|
|
@@ -314,114 +314,120 @@ Notes:
|
|
|
314
314
|
|
|
315
315
|
## Dependency Injection Integrations
|
|
316
316
|
|
|
317
|
-
|
|
317
|
+
**Stop choosing between DI and clean hierarchy references** - Unity Helpers provides seamless integrations with Zenject/Extenject, VContainer, and Reflex that automatically wire up your relational component fields right after dependency injection completes.
|
|
318
318
|
|
|
319
|
-
|
|
319
|
+
### The DI Pain Point
|
|
320
320
|
|
|
321
|
-
|
|
322
|
-
- Consistent behavior: integrates with constructor/property injection and works with runtime instantiation.
|
|
323
|
-
- Safe fallback: if the DI binding is missing, falls back to the non-DI path so fields still populate.
|
|
321
|
+
Without these integrations, you're stuck writing `Awake()` methods full of `GetComponent` boilerplate **even when using a DI framework**:
|
|
324
322
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
323
|
+
```csharp
|
|
324
|
+
public class Enemy : MonoBehaviour
|
|
325
|
+
{
|
|
326
|
+
[Inject] private IHealthSystem _health; // ✅ DI handles this
|
|
329
327
|
|
|
330
|
-
|
|
328
|
+
private Animator _animator; // ❌ Still manual boilerplate
|
|
329
|
+
private Rigidbody2D _rigidbody; // ❌ Still manual boilerplate
|
|
331
330
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
331
|
+
void Awake()
|
|
332
|
+
{
|
|
333
|
+
_animator = GetComponent<Animator>();
|
|
334
|
+
_rigidbody = GetComponent<Rigidbody2D>();
|
|
335
|
+
// ... 15 more lines of GetComponent hell
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
338
339
|
|
|
339
|
-
###
|
|
340
|
+
### The Integration Solution
|
|
340
341
|
|
|
341
|
-
|
|
342
|
+
With the DI integrations, **everything just works**:
|
|
342
343
|
|
|
343
344
|
```csharp
|
|
344
|
-
|
|
345
|
-
using VContainer.Unity;
|
|
346
|
-
using WallstopStudios.UnityHelpers.Integrations.VContainer;
|
|
347
|
-
|
|
348
|
-
public sealed class GameLifetimeScope : LifetimeScope
|
|
345
|
+
public class Enemy : MonoBehaviour
|
|
349
346
|
{
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
builder.RegisterRelationalComponents();
|
|
347
|
+
[Inject] private IHealthSystem _health; // ✅ DI injection
|
|
348
|
+
[SiblingComponent] private Animator _animator; // ✅ Relational auto-wiring
|
|
349
|
+
[SiblingComponent] private Rigidbody2D _rigidbody; // ✅ Relational auto-wiring
|
|
354
350
|
|
|
355
|
-
|
|
356
|
-
// builder.RegisterRelationalComponents(new RelationalSceneAssignmentOptions(includeInactive: false));
|
|
357
|
-
}
|
|
351
|
+
// No Awake() needed! Both DI and hierarchy references wired automatically
|
|
358
352
|
}
|
|
359
353
|
```
|
|
360
354
|
|
|
361
|
-
|
|
355
|
+
### Why Use the DI Integrations
|
|
362
356
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
357
|
+
- **Zero boilerplate** - No `Awake()` method needed, no manual `GetComponent` calls, no validation code
|
|
358
|
+
- **Consistent behavior** - Works seamlessly with constructor/property/field injection and runtime instantiation
|
|
359
|
+
- **Safe fallback** - Gracefully degrades to standard behavior if DI binding is missing
|
|
360
|
+
- **Risk-free adoption** - Use incrementally, mix DI and non-DI components freely
|
|
367
361
|
|
|
368
|
-
|
|
369
|
-
{
|
|
370
|
-
[Inject] private IObjectResolver _resolver;
|
|
371
|
-
[SerializeField] private Enemy _enemyPrefab;
|
|
362
|
+
### Supported Packages (Auto-detected)
|
|
372
363
|
|
|
373
|
-
|
|
374
|
-
{
|
|
375
|
-
Enemy enemy = Instantiate(_enemyPrefab, parent);
|
|
376
|
-
return _resolver.BuildUpWithRelations(enemy);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
```
|
|
364
|
+
Unity Helpers automatically detects these packages via UPM:
|
|
380
365
|
|
|
381
|
-
|
|
366
|
+
- **Zenject/Extenject**: `com.extenject.zenject`, `com.modesttree.zenject`, `com.svermeulen.extenject`
|
|
367
|
+
- **VContainer**: `jp.cysharp.vcontainer`, `jp.hadashikick.vcontainer`
|
|
368
|
+
- **Reflex**: `com.gustavopsantos.reflex`
|
|
382
369
|
|
|
383
|
-
|
|
384
|
-
_resolver.AssignRelationalHierarchy(root, includeInactiveChildren: false);
|
|
385
|
-
```
|
|
370
|
+
> 💡 **UPM packages work out-of-the-box** - No scripting defines needed!
|
|
386
371
|
|
|
387
|
-
###
|
|
372
|
+
### Manual or Source Imports (Non-UPM)
|
|
388
373
|
|
|
389
|
-
|
|
374
|
+
If you import Zenject/VContainer/Reflex as source code, .unitypackage, or raw DLLs (not via UPM), you need to manually add scripting defines:
|
|
390
375
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
-
|
|
376
|
+
1. Open `Project Settings > Player > Other Settings > Scripting Define Symbols`
|
|
377
|
+
2. Add the appropriate define(s) for your target platforms:
|
|
378
|
+
- `ZENJECT_PRESENT` - When using Zenject/Extenject
|
|
379
|
+
- `VCONTAINER_PRESENT` - When using VContainer
|
|
380
|
+
- `REFLEX_PRESENT` - When using Reflex
|
|
381
|
+
3. Unity will recompile and the integration assemblies under `Runtime/Integrations/*` will activate automatically
|
|
394
382
|
|
|
395
|
-
|
|
383
|
+
### VContainer at a Glance
|
|
396
384
|
|
|
397
|
-
|
|
398
|
-
using UnityEngine;
|
|
399
|
-
using Zenject;
|
|
400
|
-
using WallstopStudios.UnityHelpers.Integrations.Zenject;
|
|
385
|
+
- **Enable once per scope**
|
|
401
386
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
387
|
+
```csharp
|
|
388
|
+
builder.RegisterRelationalComponents(
|
|
389
|
+
new RelationalSceneAssignmentOptions(includeInactive: true, useSinglePassScan: true),
|
|
390
|
+
enableAdditiveSceneListener: true
|
|
391
|
+
);
|
|
392
|
+
```
|
|
406
393
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
394
|
+
- **Runtime helpers**
|
|
395
|
+
- `_resolver.InstantiateComponentWithRelations(componentPrefab, parent)`
|
|
396
|
+
- `_resolver.InstantiateGameObjectWithRelations(rootPrefab, parent, includeInactiveChildren: true)`
|
|
397
|
+
- `_resolver.AssignRelationalHierarchy(existingRoot, includeInactiveChildren: true)`
|
|
398
|
+
- `RelationalObjectPools.CreatePoolWithRelations(...)` + `pool.GetWithRelations(resolver)`
|
|
412
399
|
|
|
413
|
-
|
|
414
|
-
{
|
|
415
|
-
return _container.InstantiateComponentWithRelations(_enemyPrefab, parent);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
```
|
|
400
|
+
- **Full walkthrough**: [DI – VContainer sample](Samples~/DI%20-%20VContainer/README.md)
|
|
419
401
|
|
|
420
|
-
|
|
402
|
+
### Zenject at a Glance
|
|
421
403
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
404
|
+
- **Install once per scene**
|
|
405
|
+
- Add `RelationalComponentsInstaller` to your `SceneContext`.
|
|
406
|
+
- Toggles cover include-inactive scanning, single-pass strategy, and additive-scene listening.
|
|
407
|
+
|
|
408
|
+
- **Runtime helpers**
|
|
409
|
+
- `_container.InstantiateComponentWithRelations(componentPrefab, parent)`
|
|
410
|
+
- `_container.InstantiateGameObjectWithRelations(rootPrefab, parent, includeInactiveChildren: true)`
|
|
411
|
+
- `_container.AssignRelationalHierarchy(existingRoot, includeInactiveChildren: true)`
|
|
412
|
+
- Subclass `RelationalMemoryPool<T>` to hydrate pooled items on spawn.
|
|
413
|
+
|
|
414
|
+
- **Full walkthrough**: [DI – Zenject sample](Samples~/DI%20-%20Zenject/README.md)
|
|
415
|
+
|
|
416
|
+
### Reflex at a Glance
|
|
417
|
+
|
|
418
|
+
- **Install once per scene**
|
|
419
|
+
- Reflex creates a `SceneScope` in each scene. Add `RelationalComponentsInstaller` to the same GameObject (or a child) to bind the relational assigner, run the initial scene scan, and optionally register the additive-scene listener.
|
|
420
|
+
- Toggles mirror the runtime helpers: include inactive objects, choose scan strategy, and enable additive listening.
|
|
421
|
+
|
|
422
|
+
- **Runtime helpers**
|
|
423
|
+
- `_container.InjectWithRelations(existingComponent)` to inject DI fields and hydrate relational attributes on existing objects.
|
|
424
|
+
- `_container.InstantiateComponentWithRelations(componentPrefab, parent)` for component prefabs.
|
|
425
|
+
- `_container.InstantiateGameObjectWithRelations(rootPrefab, parent, includeInactiveChildren: true)` for full hierarchies.
|
|
426
|
+
- `_container.AssignRelationalHierarchy(existingRoot, includeInactiveChildren: true)` to hydrate arbitrary hierarchies after manual instantiation.
|
|
427
|
+
|
|
428
|
+
- **Full walkthrough**: [DI – Reflex sample](Samples~/DI%20-%20Reflex/README.md)
|
|
429
|
+
|
|
430
|
+
- Reflex shares the same fallback behaviour: if the assigner is not bound, the helpers call `AssignRelationalComponents()` directly so you can adopt incrementally.
|
|
425
431
|
|
|
426
432
|
Notes
|
|
427
433
|
|
|
@@ -479,7 +485,21 @@ Beginner-friendly overview
|
|
|
479
485
|
|
|
480
486
|
VContainer (1.16.x)
|
|
481
487
|
|
|
482
|
-
- Runtime usage (LifetimeScope): Call `builder.RegisterRelationalComponents()` in `LifetimeScope.Configure`. The entry point runs automatically after the container builds.
|
|
488
|
+
- Runtime usage (LifetimeScope): Call `builder.RegisterRelationalComponents()` in `LifetimeScope.Configure`. The entry point runs automatically after the container builds. You can enable an additive-scene listener and customize scan options:
|
|
489
|
+
|
|
490
|
+
```csharp
|
|
491
|
+
using VContainer;
|
|
492
|
+
using VContainer.Unity;
|
|
493
|
+
using WallstopStudios.UnityHelpers.Integrations.VContainer;
|
|
494
|
+
|
|
495
|
+
protected override void Configure(IContainerBuilder builder)
|
|
496
|
+
{
|
|
497
|
+
// Single-pass scan + additive scene listener
|
|
498
|
+
var options = new RelationalSceneAssignmentOptions(includeInactive: true, useSinglePassScan: true);
|
|
499
|
+
builder.RegisterRelationalComponents(options, enableAdditiveSceneListener: true);
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
483
503
|
- Tests without LifetimeScope: Construct the entry point and call `Initialize()` yourself, and register your `AttributeMetadataCache` instance so the assigner uses it:
|
|
484
504
|
|
|
485
505
|
```csharp
|
|
@@ -500,7 +520,8 @@ VContainer (1.16.x)
|
|
|
500
520
|
entry.Initialize();
|
|
501
521
|
```
|
|
502
522
|
|
|
503
|
-
- Inject vs BuildUp: Use `resolver.
|
|
523
|
+
- Inject vs BuildUp: Use `resolver.InjectWithRelations(component)` to inject + assign in one call, or `resolver.Inject(component)` then `resolver.AssignRelationalComponents(component)`.
|
|
524
|
+
- Prefabs & GameObjects: `resolver.InstantiateComponentWithRelations(prefab, parent)` or `resolver.InstantiateGameObjectWithRelations(prefab, parent)`; to inject existing hierarchies use `resolver.InjectGameObjectWithRelations(root)`.
|
|
504
525
|
|
|
505
526
|
- EditMode reliability: In EditMode tests, prefer `[UnityTest]` and `yield return null` after creating objects and after initializing the entry point so Unity has a frame to register new objects before `FindObjectsOfType` runs and to allow assignments to complete.
|
|
506
527
|
- Active scene filter: Entry points operate on the active scene only. In EditMode, create a new scene with `SceneManager.CreateScene`, set it active, and move your test hierarchy into it before calling `Initialize()`.
|
|
@@ -508,10 +529,16 @@ VContainer (1.16.x)
|
|
|
508
529
|
|
|
509
530
|
Zenject/Extenject
|
|
510
531
|
|
|
511
|
-
- Runtime usage: Add `RelationalComponentsInstaller` to your `SceneContext`. It binds `IRelationalComponentAssigner` and runs `RelationalComponentSceneInitializer` once the container is ready.
|
|
532
|
+
- Runtime usage: Add `RelationalComponentsInstaller` to your `SceneContext`. It binds `IRelationalComponentAssigner` and runs `RelationalComponentSceneInitializer` once the container is ready. The installer exposes toggles to assign on initialize and to listen for additive scenes.
|
|
512
533
|
- Tests: Bind a concrete `AttributeMetadataCache` instance and construct the assigner with that cache. Then resolve `IInitializable` and call `Initialize()`.
|
|
513
534
|
- EditMode reliability: As with VContainer, consider `[UnityTest]` with a `yield return null` after creating objects and after calling `Initialize()` to allow Unity to register objects and complete assignments.
|
|
514
|
-
- Active scene filter:
|
|
535
|
+
- Active scene filter: Initial one-time scan operates on the active scene only. The additive-scene listener processes only newly loaded scenes (not all loaded scenes).
|
|
536
|
+
- Prefabs & GameObjects: `container.InstantiateComponentWithRelations(...)`, `container.InstantiateGameObjectWithRelations(...)`, or `container.InjectGameObjectWithRelations(root)`; to inject + assign a single instance: `container.InjectWithRelations(component)`.
|
|
537
|
+
|
|
538
|
+
### Object Pools (DI-aware)
|
|
539
|
+
|
|
540
|
+
- Zenject: use `RelationalMemoryPool<T>` (or `<TParam, T>`) to assign relational fields in `OnSpawned` automatically.
|
|
541
|
+
- VContainer: create pools with `RelationalObjectPools.CreatePoolWithRelations(...)` and rent via `pool.GetWithRelations(resolver)` to inject + assign.
|
|
515
542
|
|
|
516
543
|
Common pitfalls and how to avoid them
|
|
517
544
|
|
|
@@ -526,7 +553,7 @@ Common pitfalls and how to avoid them
|
|
|
526
553
|
**Core Guides:**
|
|
527
554
|
|
|
528
555
|
- [Getting Started](GETTING_STARTED.md) - Your first 5 minutes with Unity Helpers
|
|
529
|
-
- [Main README](README.md) - Complete feature overview
|
|
556
|
+
- [Main README](../README.md) - Complete feature overview
|
|
530
557
|
- [Feature Index](INDEX.md) - Alphabetical reference
|
|
531
558
|
|
|
532
559
|
**Related Features:**
|
|
@@ -646,3 +646,18 @@ References
|
|
|
646
646
|
- Replace direct `System.Text.Json.JsonSerializer` calls in app code with `Serializer.JsonSerialize/JsonDeserialize/JsonStringify`, or with `Serializer.Serialize/Deserialize` + `SerializationType.Json` to centralize options and Unity converters.
|
|
647
647
|
- Replace any custom protobuf helpers with `Serializer.ProtoSerialize/ProtoDeserialize` or the generic `Serializer.Serialize/Deserialize` APIs. Ensure models are annotated with `[ProtoContract]` and stable `[ProtoMember(n)]` tags.
|
|
648
648
|
- For existing binary saves using BinaryFormatter, prefer migrating to Json or Protobuf. If you must keep BinaryFormatter, scope it to trusted, same-version caches only.
|
|
649
|
+
|
|
650
|
+
## 2.0 changes
|
|
651
|
+
|
|
652
|
+
- BinaryFormatter (`SerializationType.SystemBinary`) is deprecated but remains functional for trusted/legacy scenarios. Prefer:
|
|
653
|
+
- `SerializationType.Json` (System.Text.Json with Unity-aware converters) for readable, diffable content.
|
|
654
|
+
- `SerializationType.Protobuf` (protobuf-net) for compact, high-performance binary payloads.
|
|
655
|
+
|
|
656
|
+
## IL2CPP / AOT guidance
|
|
657
|
+
|
|
658
|
+
System.Text.Json can require extra care under AOT (e.g., IL2CPP):
|
|
659
|
+
|
|
660
|
+
- Prefer explicit `JsonSerializerOptions` and concrete generic APIs over `object`-based serialization to reduce reflection.
|
|
661
|
+
- For hot POCO models, consider adding a source-generated context (JsonSerializerContext) in your game assembly and pass it to `JsonSerializer` calls.
|
|
662
|
+
- If you rely on many custom converters, ensure they are referenced by code so the linker doesn't strip them. The UnityHelpers converters are referenced via options by default.
|
|
663
|
+
- Avoid deserializing `System.Type` from untrusted input (see `TypeConverter`); this is intended for trusted configs/tools.
|
|
@@ -177,7 +177,7 @@ void Update()
|
|
|
177
177
|
}
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
See [Buffering Pattern](README.md#buffering-pattern) for the complete guide and [Pooling Utilities](README.md#pooling-utilities) for more pooling options.
|
|
180
|
+
See [Buffering Pattern](../README.md#buffering-pattern) for the complete guide and [Pooling Utilities](../README.md#pooling-utilities) for more pooling options.
|
|
181
181
|
|
|
182
182
|
## Structures
|
|
183
183
|
|
|
@@ -247,7 +247,7 @@ START: Do your objects move frequently?
|
|
|
247
247
|
- **Nearest neighbors on static points:** KDTree2D (Balanced)
|
|
248
248
|
- **Fast builds with good-enough queries:** KDTree2D (Unbalanced)
|
|
249
249
|
- **Objects with area; bounds queries primary:** RTree2D
|
|
250
|
-
- **Very frequent movement (every frame):** SpatialHash2D (see [README](README.md#choosing-spatial-structures))
|
|
250
|
+
- **Very frequent movement (every frame):** SpatialHash2D (see [README](../README.md#choosing-spatial-structures))
|
|
251
251
|
|
|
252
252
|
## Query Semantics
|
|
253
253
|
|
|
@@ -167,7 +167,7 @@ void Update()
|
|
|
167
167
|
}
|
|
168
168
|
```
|
|
169
169
|
|
|
170
|
-
See [Buffering Pattern](README.md#buffering-pattern) for the complete guide and [Pooling Utilities](README.md#pooling-utilities) for more pooling options.
|
|
170
|
+
See [Buffering Pattern](../README.md#buffering-pattern) for the complete guide and [Pooling Utilities](../README.md#pooling-utilities) for more pooling options.
|
|
171
171
|
|
|
172
172
|
## Structures
|
|
173
173
|
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# 2D Spatial Tree Performance Benchmarks
|
|
2
|
+
|
|
3
|
+
## TL;DR — What Problem This Solves
|
|
4
|
+
|
|
5
|
+
- Fast range/bounds/nearest‑neighbor queries on 2D data without scanning everything.
|
|
6
|
+
- Quick picks: QuadTree2D for broad‑phase; KDTree2D (Balanced) for NN; KDTree2D (Unbalanced) for fast rebuilds; RTree2D for bounds‑based data.
|
|
7
|
+
|
|
8
|
+
This document contains performance benchmarks for the 2D spatial tree implementations in Unity Helpers.
|
|
9
|
+
|
|
10
|
+
## Available 2D Spatial Trees
|
|
11
|
+
|
|
12
|
+
- **QuadTree2D** - Easiest to use, good all-around performance
|
|
13
|
+
- **KDTree2D** - Balanced and unbalanced variants available
|
|
14
|
+
- **RTree2D** - Optimized for bounding box queries
|
|
15
|
+
|
|
16
|
+
### Correctness & Semantics
|
|
17
|
+
|
|
18
|
+
- QuadTree2D and KdTree2D (balanced and unbalanced) guarantee the same results for the same input data and the same queries. They are both point-based trees and differ only in construction/query performance characteristics.
|
|
19
|
+
- RTree2D is bounds-based (stores rectangles/AABBs), not points. Its spatial knowledge and query semantics operate on rectangles, so its results will intentionally differ for sized objects and bounds intersection queries.
|
|
20
|
+
|
|
21
|
+
## Performance Benchmarks
|
|
22
|
+
|
|
23
|
+
<!-- SPATIAL_TREE_BENCHMARKS_START -->
|
|
24
|
+
|
|
25
|
+
### Datasets
|
|
26
|
+
|
|
27
|
+
<!-- tabs:start -->
|
|
28
|
+
|
|
29
|
+
#### **1,000,000 entries**
|
|
30
|
+
|
|
31
|
+
##### Construction
|
|
32
|
+
|
|
33
|
+
| Construction | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
34
|
+
| ----------------- | ------------------- | --------------------- | ---------- | ---------- |
|
|
35
|
+
| 1,000,000 entries | 3 (0.325s) | 4 (0.218s) | 4 (0.221s) | 1 (0.595s) |
|
|
36
|
+
|
|
37
|
+
##### Elements In Range
|
|
38
|
+
|
|
39
|
+
| Elements In Range | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
40
|
+
| --------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
41
|
+
| Full (~span/2) (r=499.5) | 58 | 58 | 56 | 7 |
|
|
42
|
+
| Half (~span/4) (r=249.8) | 236 | 238 | 215 | 28 |
|
|
43
|
+
| Quarter (~span/8) (r=124.9) | 945 | 946 | 815 | 119 |
|
|
44
|
+
| Tiny (~span/1000) (r=1) | 103,233 | 105,580 | 142,838 | 107,126 |
|
|
45
|
+
|
|
46
|
+
##### Get Elements In Bounds
|
|
47
|
+
|
|
48
|
+
| Get Elements In Bounds | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
49
|
+
| -------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
50
|
+
| Full (size=999.0x999.0) | 314 | 325 | 344 | 17 |
|
|
51
|
+
| Half (size=499.5x499.5) | 1,730 | 1,822 | 1,238 | 73 |
|
|
52
|
+
| Quarter (size=249.8x249.8) | 7,188 | 7,170 | 3,867 | 379 |
|
|
53
|
+
| Unit (size=1) | 149,753 | 153,363 | 197,026 | 113,010 |
|
|
54
|
+
|
|
55
|
+
##### Approximate Nearest Neighbors
|
|
56
|
+
|
|
57
|
+
| Approximate Nearest Neighbors | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
58
|
+
| ----------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
59
|
+
| 500 neighbors | 8,466 | 16,873 | 12,696 | 70,046 |
|
|
60
|
+
| 100 neighbors | 78,952 | 76,476 | 78,720 | 171,372 |
|
|
61
|
+
| 10 neighbors | 375,484 | 377,708 | 251,988 | 277,491 |
|
|
62
|
+
| 1 neighbor | 551,002 | 508,239 | 276,379 | 299,010 |
|
|
63
|
+
|
|
64
|
+
#### **100,000 entries**
|
|
65
|
+
|
|
66
|
+
##### Construction
|
|
67
|
+
|
|
68
|
+
| Construction | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
69
|
+
| --------------- | ------------------- | --------------------- | ----------- | ----------- |
|
|
70
|
+
| 100,000 entries | 50 (0.020s) | 83 (0.012s) | 50 (0.020s) | 49 (0.020s) |
|
|
71
|
+
|
|
72
|
+
##### Elements In Range
|
|
73
|
+
|
|
74
|
+
| Elements In Range | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
75
|
+
| --------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
76
|
+
| Full (~span/2) (r=199.5) | 602 | 602 | 600 | 73 |
|
|
77
|
+
| Half (~span/4) (r=99.75) | 1,355 | 1,359 | 1,248 | 185 |
|
|
78
|
+
| Quarter (~span/8) (r=49.88) | 4,672 | 5,178 | 4,300 | 723 |
|
|
79
|
+
| Tiny (~span/1000) (r=1) | 127,810 | 128,060 | 179,544 | 145,029 |
|
|
80
|
+
|
|
81
|
+
##### Get Elements In Bounds
|
|
82
|
+
|
|
83
|
+
| Get Elements In Bounds | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
84
|
+
| -------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
85
|
+
| Full (size=399.0x249.0) | 4,436 | 4,468 | 4,702 | 235 |
|
|
86
|
+
| Half (size=199.5x124.5) | 9,433 | 11,669 | 7,996 | 967 |
|
|
87
|
+
| Quarter (size=99.75x62.25) | 25,419 | 32,186 | 19,754 | 3,805 |
|
|
88
|
+
| Unit (size=1) | 184,712 | 185,636 | 245,390 | 155,220 |
|
|
89
|
+
|
|
90
|
+
##### Approximate Nearest Neighbors
|
|
91
|
+
|
|
92
|
+
| Approximate Nearest Neighbors | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
93
|
+
| ----------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
94
|
+
| 500 neighbors | 9,986 | 9,929 | 11,705 | 69,966 |
|
|
95
|
+
| 100 neighbors | 49,779 | 87,233 | 55,229 | 233,211 |
|
|
96
|
+
| 10 neighbors | 470,175 | 394,286 | 294,299 | 352,517 |
|
|
97
|
+
| 1 neighbor | 509,623 | 544,160 | 314,046 | 350,724 |
|
|
98
|
+
|
|
99
|
+
#### **10,000 entries**
|
|
100
|
+
|
|
101
|
+
##### Construction
|
|
102
|
+
|
|
103
|
+
| Construction | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
104
|
+
| -------------- | ------------------- | --------------------- | ------------ | ------------ |
|
|
105
|
+
| 10,000 entries | 533 (0.002s) | 796 (0.001s) | 408 (0.002s) | 507 (0.002s) |
|
|
106
|
+
|
|
107
|
+
##### Elements In Range
|
|
108
|
+
|
|
109
|
+
| Elements In Range | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
110
|
+
| --------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
111
|
+
| Full (~span/2) (r=49.50) | 5,944 | 5,941 | 5,936 | 735 |
|
|
112
|
+
| Half (~span/4) (r=24.75) | 22,272 | 22,233 | 13,861 | 2,919 |
|
|
113
|
+
| Quarter (~span/8) (r=12.38) | 44,278 | 51,526 | 38,041 | 12,217 |
|
|
114
|
+
| Tiny (~span/1000) (r=1) | 167,798 | 162,582 | 223,371 | 168,224 |
|
|
115
|
+
|
|
116
|
+
##### Get Elements In Bounds
|
|
117
|
+
|
|
118
|
+
| Get Elements In Bounds | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
119
|
+
| -------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
120
|
+
| Full (size=99.00x99.00) | 45,222 | 44,244 | 47,466 | 2,412 |
|
|
121
|
+
| Half (size=49.50x49.50) | 167,135 | 166,097 | 36,985 | 9,274 |
|
|
122
|
+
| Quarter (size=24.75x24.75) | 76,007 | 104,425 | 74,227 | 35,573 |
|
|
123
|
+
| Unit (size=1) | 242,092 | 234,546 | 320,164 | 181,677 |
|
|
124
|
+
|
|
125
|
+
##### Approximate Nearest Neighbors
|
|
126
|
+
|
|
127
|
+
| Approximate Nearest Neighbors | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
128
|
+
| ----------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
129
|
+
| 500 neighbors | 13,178 | 12,888 | 14,441 | 65,299 |
|
|
130
|
+
| 100 neighbors | 62,415 | 57,120 | 96,738 | 235,553 |
|
|
131
|
+
| 10 neighbors | 418,552 | 392,340 | 316,886 | 420,625 |
|
|
132
|
+
| 1 neighbor | 595,519 | 632,000 | 372,667 | 433,485 |
|
|
133
|
+
|
|
134
|
+
#### **1,000 entries**
|
|
135
|
+
|
|
136
|
+
##### Construction
|
|
137
|
+
|
|
138
|
+
| Construction | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
139
|
+
| ------------- | ------------------- | --------------------- | -------------- | -------------- |
|
|
140
|
+
| 1,000 entries | 4,672 (0.000s) | 5,611 (0.000s) | 4,847 (0.000s) | 4,764 (0.000s) |
|
|
141
|
+
|
|
142
|
+
##### Elements In Range
|
|
143
|
+
|
|
144
|
+
| Elements In Range | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
145
|
+
| -------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
146
|
+
| Full (~span/2) (r=24.50) | 58,142 | 56,029 | 57,082 | 7,394 |
|
|
147
|
+
| Half (~span/4) (r=12.25) | 60,439 | 76,572 | 57,123 | 14,698 |
|
|
148
|
+
| Quarter (~span/8) (r=6.13) | 95,988 | 108,457 | 95,703 | 37,920 |
|
|
149
|
+
| Tiny (~span/1000) (r=1) | 239,460 | 237,275 | 333,071 | 251,518 |
|
|
150
|
+
|
|
151
|
+
##### Get Elements In Bounds
|
|
152
|
+
|
|
153
|
+
| Get Elements In Bounds | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
154
|
+
| ------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
155
|
+
| Full (size=49.00x19.00) | 499,193 | 498,444 | 508,596 | 24,141 |
|
|
156
|
+
| Half (size=24.50x9.5) | 167,532 | 291,283 | 126,274 | 75,139 |
|
|
157
|
+
| Quarter (size=12.25x4.75) | 271,878 | 288,421 | 194,135 | 176,768 |
|
|
158
|
+
| Unit (size=1) | 342,402 | 339,166 | 460,883 | 281,383 |
|
|
159
|
+
|
|
160
|
+
##### Approximate Nearest Neighbors
|
|
161
|
+
|
|
162
|
+
| Approximate Nearest Neighbors | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
163
|
+
| ----------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
164
|
+
| 500 neighbors | 46,434 | 47,214 | 40,048 | 70,543 |
|
|
165
|
+
| 100 neighbors | 80,837 | 77,933 | 91,884 | 267,760 |
|
|
166
|
+
| 10 neighbors | 487,252 | 574,172 | 426,710 | 516,096 |
|
|
167
|
+
| 1 neighbor | 754,604 | 618,120 | 404,966 | 594,659 |
|
|
168
|
+
|
|
169
|
+
#### **100 entries**
|
|
170
|
+
|
|
171
|
+
##### Construction
|
|
172
|
+
|
|
173
|
+
| Construction | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
174
|
+
| ------------ | ------------------- | --------------------- | --------------- | --------------- |
|
|
175
|
+
| 100 entries | 37,174 (0.000s) | 3,938 (0.000s) | 10,384 (0.000s) | 21,978 (0.000s) |
|
|
176
|
+
|
|
177
|
+
##### Elements In Range
|
|
178
|
+
|
|
179
|
+
| Elements In Range | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
180
|
+
| -------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
181
|
+
| Full (~span/2) (r=4.5) | 505,197 | 462,582 | 480,895 | 72,679 |
|
|
182
|
+
| Half (~span/4) (r=2.25) | 428,579 | 432,700 | 256,227 | 233,286 |
|
|
183
|
+
| Quarter (~span/8) (r=1.13) | 422,859 | 432,362 | 601,655 | 318,360 |
|
|
184
|
+
| Tiny (~span/1000) (r=1) | 406,482 | 433,055 | 601,161 | 339,515 |
|
|
185
|
+
|
|
186
|
+
##### Get Elements In Bounds
|
|
187
|
+
|
|
188
|
+
| Get Elements In Bounds | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
189
|
+
| ------------------------ | ------------------- | --------------------- | ---------- | ------- |
|
|
190
|
+
| Full (size=9x9) | 2,460,211 | 2,459,261 | 2,542,373 | 223,694 |
|
|
191
|
+
| Half (size=4.5x4.5) | 572,726 | 561,349 | 365,082 | 372,098 |
|
|
192
|
+
| Quarter (size=2.25x2.25) | 594,157 | 580,857 | 738,232 | 396,288 |
|
|
193
|
+
| Unit (size=1) | 593,669 | 576,995 | 787,477 | 395,564 |
|
|
194
|
+
|
|
195
|
+
##### Approximate Nearest Neighbors
|
|
196
|
+
|
|
197
|
+
| Approximate Nearest Neighbors | KDTree2D (Balanced) | KDTree2D (Unbalanced) | QuadTree2D | RTree2D |
|
|
198
|
+
| ----------------------------- | ------------------- | --------------------- | ---------- | ------- |
|
|
199
|
+
| 100 neighbors (max) | 166,728 | 165,861 | 199,072 | 303,148 |
|
|
200
|
+
| 10 neighbors | 610,079 | 520,568 | 639,716 | 735,646 |
|
|
201
|
+
| 1 neighbor | 457,409 | 765,967 | 667,953 | 818,651 |
|
|
202
|
+
|
|
203
|
+
<!-- tabs:end -->
|
|
204
|
+
<!-- SPATIAL_TREE_BENCHMARKS_END -->
|
|
205
|
+
|
|
206
|
+
## Interpreting the Results
|
|
207
|
+
|
|
208
|
+
All numbers represent **operations per second** (higher is better), except for construction times which show operations per second and absolute time.
|
|
209
|
+
|
|
210
|
+
### Choosing the Right Tree
|
|
211
|
+
|
|
212
|
+
**QuadTree2D**:
|
|
213
|
+
|
|
214
|
+
- Best for: General-purpose 2D spatial queries
|
|
215
|
+
- Strengths: Balanced performance across all operation types, simple to use
|
|
216
|
+
- Weaknesses: Slightly slower than KDTree for point queries
|
|
217
|
+
|
|
218
|
+
**KDTree2D (Balanced)**:
|
|
219
|
+
|
|
220
|
+
- Best for: When you need consistent query performance
|
|
221
|
+
- Strengths: Fast nearest-neighbor queries, good for smaller datasets
|
|
222
|
+
- Weaknesses: Slower construction time
|
|
223
|
+
|
|
224
|
+
**KDTree2D (Unbalanced)**:
|
|
225
|
+
|
|
226
|
+
- Best for: When you need fast construction and will rebuild frequently
|
|
227
|
+
- Strengths: Fastest construction, similar query performance to balanced
|
|
228
|
+
- Weaknesses: May degrade on pathological data distributions
|
|
229
|
+
|
|
230
|
+
**RTree2D**:
|
|
231
|
+
|
|
232
|
+
- Best for: Bounding box queries, especially with large query areas
|
|
233
|
+
- Strengths: Excellent for large bounding box queries, handles overlapping objects well
|
|
234
|
+
- Weaknesses: Slower for point queries and small ranges
|
|
235
|
+
|
|
236
|
+
### Important Notes
|
|
237
|
+
|
|
238
|
+
- All spatial trees assume **immutable** positional data
|
|
239
|
+
- If positions change, you must reconstruct the tree
|
|
240
|
+
- Spatial queries are O(log n) vs O(n) for linear search
|
|
241
|
+
- Construction cost is amortized over many queries
|