├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ └── build.yml ├── .gitignore ├── Directory.Build.props ├── Directory.Build.targets ├── Directory.Packages.props ├── LICENSE ├── NuGet.config ├── README.md ├── Vortice.Mathematics.sln ├── Vortice.snk ├── global.json └── src ├── Vortice.Mathematics.Tests ├── Color4Tests.cs ├── ColorBgraTests.cs ├── ColorTests.cs ├── MathHelperTests.cs ├── PackedVectors │ ├── Byte2NormalizedTests.cs │ ├── Byte2Tests.cs │ ├── Byte4NormalizedTests.cs │ ├── Byte4Tests.cs │ ├── Half2Tests.cs │ ├── Half4Tests.cs │ ├── Short2NormalizedTests.cs │ ├── Short2Tests.cs │ └── Short4Tests.cs ├── VectorUtilitiesTests.cs └── Vortice.Mathematics.Tests.csproj └── Vortice.Mathematics ├── BoundingBox.cs ├── BoundingFrustum.cs ├── BoundingSphere.cs ├── Box.cs ├── Color.cs ├── Color3.cs ├── Color4.cs ├── ColorBgra.cs ├── Colors.cs ├── ContainmentType.cs ├── Double2.cs ├── Double3.cs ├── Double4.cs ├── Extensions.uwp.cs ├── FormatExtensions.cs ├── Int2.cs ├── Int3.cs ├── Int4.cs ├── MathHelper.cs ├── Matrix3x3.cs ├── Matrix3x4.cs ├── Matrix4x3.cs ├── Matrix5x4.cs ├── NumericsExtensions.cs ├── PackHelpers.cs ├── PackedVector ├── Byte2.cs ├── Byte2Normalized.cs ├── Byte4.cs ├── Byte4Normalized.cs ├── Half2.cs ├── Half4.cs ├── IPackedVector.cs ├── Short2.cs ├── Short2Normalized.cs ├── Short4.cs ├── Short4Normalized.cs ├── UByte2.cs ├── UByte2Normalized.cs ├── UByte4.cs ├── UByte4Normalized.cs ├── UShort2.cs ├── UShort2Normalized.cs ├── UShort4.cs └── UShort4Normalized.cs ├── PlaneIntersectionType.cs ├── Properties └── AssemblyInfo.cs ├── Ray.cs ├── Rect.cs ├── RectI.cs ├── Size.cs ├── Size3.cs ├── SizeI.cs ├── UInt2.cs ├── UInt3.cs ├── UInt4.cs ├── VectorExtensions.cs ├── VectorUtilities.cs ├── Viewport.cs └── Vortice.Mathematics.csproj /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Default settings: 7 | # A newline ending every file 8 | # Use 4 spaces as indentation 9 | [*] 10 | # Encoding 11 | charset = utf-8 12 | 13 | # Indentation and spacing 14 | indent_style = space 15 | tab_width = 4 16 | indent_size = 4 17 | 18 | # New line preferences 19 | end_of_line = lf 20 | insert_final_newline = true 21 | trim_trailing_whitespace = true 22 | 23 | # Generated code 24 | [*{_AssemblyInfo.cs,.notsupported.cs,AsmOffsets.cs}] 25 | generated_code = true 26 | 27 | # C# files 28 | [*.cs] 29 | # New line preferences 30 | csharp_new_line_before_open_brace = all 31 | csharp_new_line_before_else = true 32 | csharp_new_line_before_catch = true 33 | csharp_new_line_before_finally = true 34 | csharp_new_line_before_members_in_object_initializers = true 35 | csharp_new_line_before_members_in_anonymous_types = true 36 | csharp_new_line_between_query_expression_clauses = true 37 | 38 | # Indentation preferences 39 | csharp_indent_block_contents = true 40 | csharp_indent_braces = false 41 | csharp_indent_case_contents = true 42 | csharp_indent_case_contents_when_block = true 43 | csharp_indent_switch_labels = true 44 | csharp_indent_labels = one_less_than_current 45 | 46 | # Modifier preferences 47 | csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:suggestion 48 | 49 | # avoid this. unless absolutely necessary 50 | dotnet_style_qualification_for_field = false:suggestion 51 | dotnet_style_qualification_for_property = false:suggestion 52 | dotnet_style_qualification_for_method = false:suggestion 53 | dotnet_style_qualification_for_event = false:suggestion 54 | 55 | # Types: use keywords instead of BCL types, and permit var only when the type is clear 56 | csharp_style_var_for_built_in_types = false:suggestion 57 | csharp_style_var_when_type_is_apparent = false:none 58 | csharp_style_var_elsewhere = false:suggestion 59 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion 60 | dotnet_style_predefined_type_for_member_access = true:suggestion 61 | 62 | # name all constant fields using PascalCase 63 | dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion 64 | dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields 65 | dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style 66 | dotnet_naming_symbols.constant_fields.applicable_kinds = field 67 | dotnet_naming_symbols.constant_fields.required_modifiers = const 68 | dotnet_naming_style.pascal_case_style.capitalization = pascal_case 69 | 70 | # static fields should have s_ prefix 71 | dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion 72 | dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields 73 | dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style 74 | dotnet_naming_symbols.static_fields.applicable_kinds = field 75 | dotnet_naming_symbols.static_fields.required_modifiers = static 76 | dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected 77 | dotnet_naming_style.static_prefix_style.required_prefix = s_ 78 | dotnet_naming_style.static_prefix_style.capitalization = camel_case 79 | 80 | # internal and private fields should be _camelCase 81 | dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion 82 | dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields 83 | dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style 84 | dotnet_naming_symbols.private_internal_fields.applicable_kinds = field 85 | dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal 86 | dotnet_naming_style.camel_case_underscore_style.required_prefix = _ 87 | dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case 88 | 89 | # Code style defaults 90 | csharp_using_directive_placement = outside_namespace:suggestion 91 | dotnet_sort_system_directives_first = true 92 | csharp_prefer_braces = true:silent 93 | csharp_preserve_single_line_blocks = true:none 94 | csharp_preserve_single_line_statements = false:none 95 | csharp_prefer_static_local_function = true:suggestion 96 | csharp_prefer_simple_using_statement = false:none 97 | csharp_style_prefer_switch_expression = true:suggestion 98 | dotnet_style_readonly_field = true:suggestion 99 | 100 | # Expression-level preferences 101 | dotnet_style_object_initializer = true:suggestion 102 | dotnet_style_collection_initializer = true:suggestion 103 | dotnet_style_explicit_tuple_names = true:suggestion 104 | dotnet_style_coalesce_expression = true:suggestion 105 | dotnet_style_null_propagation = true:suggestion 106 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion 107 | dotnet_style_prefer_inferred_tuple_names = true:suggestion 108 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion 109 | dotnet_style_prefer_auto_properties = true:suggestion 110 | dotnet_style_prefer_conditional_expression_over_assignment = true:silent 111 | dotnet_style_prefer_conditional_expression_over_return = true:silent 112 | csharp_prefer_simple_default_expression = true:suggestion 113 | 114 | # Expression-bodied members 115 | csharp_style_expression_bodied_methods = true:silent 116 | csharp_style_expression_bodied_constructors = true:silent 117 | csharp_style_expression_bodied_operators = true:silent 118 | csharp_style_expression_bodied_properties = true:silent 119 | csharp_style_expression_bodied_indexers = true:silent 120 | csharp_style_expression_bodied_accessors = true:silent 121 | csharp_style_expression_bodied_lambdas = true:silent 122 | csharp_style_expression_bodied_local_functions = true:silent 123 | 124 | # Pattern matching 125 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion 126 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion 127 | csharp_style_inlined_variable_declaration = true:suggestion 128 | 129 | # Null checking preferences 130 | csharp_style_throw_expression = true:suggestion 131 | csharp_style_conditional_delegate_call = true:suggestion 132 | 133 | # Other features 134 | csharp_style_prefer_index_operator = false:none 135 | csharp_style_prefer_range_operator = false:none 136 | csharp_style_pattern_local_over_anonymous_function = false:none 137 | 138 | # Space preferences 139 | csharp_space_after_cast = false 140 | csharp_space_after_colon_in_inheritance_clause = true 141 | csharp_space_after_comma = true 142 | csharp_space_after_dot = false 143 | csharp_space_after_keywords_in_control_flow_statements = true 144 | csharp_space_after_semicolon_in_for_statement = true 145 | csharp_space_around_binary_operators = before_and_after 146 | csharp_space_around_declaration_statements = do_not_ignore 147 | csharp_space_before_colon_in_inheritance_clause = true 148 | csharp_space_before_comma = false 149 | csharp_space_before_dot = false 150 | csharp_space_before_open_square_brackets = false 151 | csharp_space_before_semicolon_in_for_statement = false 152 | csharp_space_between_empty_square_brackets = false 153 | csharp_space_between_method_call_empty_parameter_list_parentheses = false 154 | csharp_space_between_method_call_name_and_opening_parenthesis = false 155 | csharp_space_between_method_call_parameter_list_parentheses = false 156 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 157 | csharp_space_between_method_declaration_name_and_open_parenthesis = false 158 | csharp_space_between_method_declaration_parameter_list_parentheses = false 159 | csharp_space_between_parentheses = false 160 | csharp_space_between_square_brackets = false 161 | 162 | csharp_style_namespace_declarations = file_scoped:error 163 | 164 | # License header 165 | file_header_template = Copyright (c) Amer Koleci and Contributors.\nLicensed under the MIT License (MIT). See LICENSE in the repository root for more information. 166 | 167 | # C++ Files 168 | [*.{cpp,h,in}] 169 | curly_bracket_next_line = true 170 | indent_brace_style = Allman 171 | 172 | # Xml project files 173 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}] 174 | indent_size = 2 175 | 176 | [*.{csproj,vbproj,proj,nativeproj,locproj}] 177 | charset = utf-8 178 | 179 | # Xml build files 180 | [*.builds] 181 | indent_size = 2 182 | 183 | # Xml files 184 | [*.{xml,stylecop,resx,ruleset}] 185 | indent_size = 2 186 | 187 | # Xml config files 188 | [*.{props,targets,config,nuspec}] 189 | indent_size = 2 190 | 191 | # YAML config files 192 | [*.{yml,yaml}] 193 | indent_size = 2 194 | 195 | # Shell scripts 196 | [*.sh] 197 | end_of_line = lf 198 | [*.{cmd,bat}] 199 | end_of_line = crlf -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to: 3 | # treat as text and 4 | # normalize to Unix-style line endings 5 | ############################################################################### 6 | * text eol=lf 7 | 8 | ############################################################################### 9 | # Set explicit file behavior to: 10 | # treat as text and 11 | # normalize to Unix-style line endings 12 | ############################################################################### 13 | *.cmd text eol=lf 14 | *.config text eol=lf 15 | *.cs text eol=lf 16 | *.csproj text eol=lf 17 | *.hlsl text eol=lf 18 | *.json text eol=lf 19 | *.md text eol=lf 20 | *.props text eol=lf 21 | *.ps1 text eol=lf 22 | *.resx text eol=lf 23 | *.sh text eol=lf 24 | *.sln text eol=lf 25 | *.targets text eol=lf 26 | *.yml text eol=lf 27 | *.cmd text eol=crlf 28 | *.bat text eol=crlf 29 | 30 | ############################################################################### 31 | # Set explicit file behavior to: 32 | # treat as text and 33 | # normalize to Windows-style line endings 34 | ############################################################################### 35 | *.sln text eol=crlf 36 | 37 | ############################################################################### 38 | # Set explicit file behavior to: 39 | # treat as binary 40 | ############################################################################### 41 | *.png binary 42 | *.jpg binary 43 | *.gif binary 44 | *.wav binary 45 | *.snk binary 46 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [amerkoleci] 2 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'main' 7 | paths-ignore: 8 | - '*.md' 9 | - 'LICENSE' 10 | pull_request: 11 | paths-ignore: 12 | - '*.md' 13 | - 'LICENSE' 14 | 15 | jobs: 16 | build: 17 | runs-on: windows-latest 18 | 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v4 22 | 23 | - name: Setup .NET SDK 24 | uses: actions/setup-dotnet@v4 25 | with: 26 | global-json-file: ./global.json 27 | 28 | - name: Pack 29 | run: dotnet pack Vortice.Mathematics.sln --configuration Release 30 | 31 | - name: Publish to NuGet 32 | if: github.event_name == 'push' 33 | run: dotnet nuget push artifacts/**/*.nupkg -k ${{secrets.NUGET_TOKEN}} --skip-duplicate --source https://api.nuget.org/v3/index.json 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Fortran module files 15 | *.mod 16 | *.smod 17 | 18 | # Compiled Static libraries 19 | *.lai 20 | *.la 21 | *.a 22 | *.lib 23 | 24 | # Executables 25 | *.exe 26 | *.out 27 | *.app 28 | *.dmp 29 | 30 | # NuGet Packages 31 | *.nupkg 32 | *.nuget.g.props 33 | *.nuget.g.targets 34 | *.nuget.cache 35 | **/packages/* 36 | project.lock.json 37 | project.assets.json 38 | *.nuget.dgspec.json 39 | 40 | # Others 41 | *.Cache 42 | 43 | # Compiled shaders 44 | *.cso 45 | *.spv 46 | 47 | # Build dir 48 | .vs 49 | [Bb]in/ 50 | [Oo]bj/ 51 | src/native/build -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | Debug 4 | $(MSBuildThisFileDirectory) 5 | 6 | 7 | 8 | https://github.com/amerkoleci/Vortice.Mathematics 9 | git 10 | 11 | 12 | 13 | true 14 | 12.0 15 | enable 16 | enable 17 | 18 | embedded 19 | strict 20 | preview 21 | true 22 | true 23 | $(MSBuildThisFileDirectory)NuGet.config 24 | true 25 | 26 | true 27 | CS1591;CS1701 28 | 29 | true 30 | 0024000004800000940000000602000000240000525341310004000001000100758064dc2d7cc685f393036f2d5fd6c3a8d9a811a6633e614a2a224c0aa45ef6e7dd9a45172f3b0055f0af31e7637b152a02263922c9fdfd0ed4408d30dcc26fc080c9d0e4c5e1307527e661037b4927b9f27b5318307698d474bf15506f21b9b2cf8155855624863b46584c11bf75bfde5dbbe8120c00524f713541725167cb 31 | $(MSBuildThisFileDirectory)Vortice.snk 32 | 33 | 34 | 35 | true 36 | 37 | 38 | 39 | Amer Koleci 40 | Amer Koleci 41 | Amer Koleci 42 | Copyright (c) Amer Koleci and Contributors 43 | Vortice.Mathematics 44 | MIT 45 | true 46 | $(RepositoryUrl) 47 | $(MSBuildThisFileDirectory)artifacts/ 48 | math numerics 3D engine graphics gamedev vortice Direct3D DirectX Vulkan OpenGL Metal Core Standard Game 49 | true 50 | true 51 | true 52 | 53 | 54 | 55 | 56 | true 57 | true 58 | true 59 | snupkg 60 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | true 10 | true 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Directory.Packages.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Amer Koleci and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a 6 | copy of this software and associated documentation files (the "Software"), 7 | to deal in the Software without restriction, including without limitation 8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | and/or sell copies of the Software, and to permit persons to whom the 10 | Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vortice.Mathematics 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/amerkoleci/Vortice.Mathematics/blob/master/LICENSE) 4 | [![Build status](https://github.com/amerkoleci/Vortice.Mathematics/workflows/Build/badge.svg)](https://github.com/amerkoleci/Vortice.Mathematics/actions) 5 | [![NuGet](https://img.shields.io/nuget/v/Vortice.Mathematics.svg)](https://www.nuget.org/packages/Vortice.Mathematics) 6 | 7 | **Vortice.Mathematics** is a high-performance cross platform **.NET 8** and **.NET 9** math library. 8 | 9 | ## Sponsors 10 | Please consider becoming a [SPONSOR](https://github.com/sponsors/amerkoleci) to further help development and to allow faster issue triaging and new features to be implemented. 11 | **_NOTE:_** **any feature request** would require a [sponsor](https://github.com/sponsors/amerkoleci) in order to allow faster implementation and allow this project to continue. 12 | 13 | ## Credits 14 | 15 | Library development, contributions and bugfixes by: 16 | 17 | - Amer Koleci 18 | 19 | Insipration, ideas and code has been based on: 20 | 21 | - [SharpDX.Mathematics](https://github.com/sharpdx/SharpDX/tree/master/Source/SharpDX.Mathematics) 22 | - [Xenko.Core.Mathematics](https://github.com/xenko3d/xenko/tree/master/sources/core/Xenko.Core.Mathematics) 23 | - [TerraFX](https://github.com/terrafx/terrafx) 24 | 25 | -------------------------------------------------------------------------------- /Vortice.Mathematics.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 17 3 | VisualStudioVersion = 17.0.31919.166 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vortice.Mathematics", "src\Vortice.Mathematics\Vortice.Mathematics.csproj", "{D83792BE-58C1-4F40-B028-02C0449DC2AB}" 6 | EndProject 7 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{630DF6DF-DE85-4264-A5E8-4CCCC4EBED75}" 8 | ProjectSection(SolutionItems) = preProject 9 | .editorconfig = .editorconfig 10 | .gitattributes = .gitattributes 11 | .gitignore = .gitignore 12 | Directory.Build.props = Directory.Build.props 13 | Directory.Build.targets = Directory.Build.targets 14 | Directory.Packages.props = Directory.Packages.props 15 | LICENSE = LICENSE 16 | NuGet.config = NuGet.config 17 | README.md = README.md 18 | EndProjectSection 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vortice.Mathematics.Tests", "src\Vortice.Mathematics.Tests\Vortice.Mathematics.Tests.csproj", "{C1983138-9CC7-4889-B413-19B2736BBB68}" 21 | EndProject 22 | Global 23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 24 | Debug|Any CPU = Debug|Any CPU 25 | Release|Any CPU = Release|Any CPU 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {D83792BE-58C1-4F40-B028-02C0449DC2AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {D83792BE-58C1-4F40-B028-02C0449DC2AB}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {D83792BE-58C1-4F40-B028-02C0449DC2AB}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {D83792BE-58C1-4F40-B028-02C0449DC2AB}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {C1983138-9CC7-4889-B413-19B2736BBB68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {C1983138-9CC7-4889-B413-19B2736BBB68}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {C1983138-9CC7-4889-B413-19B2736BBB68}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {C1983138-9CC7-4889-B413-19B2736BBB68}.Release|Any CPU.Build.0 = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {B0734700-42E1-4F87-8DD2-0084849DA44A} 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /Vortice.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amerkoleci/Vortice.Mathematics/b6e13cb19cd11532ad81234d5d820fffb5b3e53c/Vortice.snk -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "9.0.100", 4 | "rollForward": "latestFeature", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/Color4Tests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using NUnit.Framework; 5 | 6 | namespace Vortice.Mathematics.Tests; 7 | 8 | [TestFixture(TestOf = typeof(Color4))] 9 | public partial class Color4Tests 10 | { 11 | [TestCase] 12 | public void DefaultChecks() 13 | { 14 | Color4 color = new(); 15 | Assert.That(color.R, Is.EqualTo(0.0f)); 16 | Assert.That(color.G, Is.EqualTo(0.0f)); 17 | Assert.That(color.B, Is.EqualTo(0.0f)); 18 | Assert.That(color.A, Is.EqualTo(0.0f)); 19 | } 20 | 21 | [TestCase] 22 | public void CreationTests() 23 | { 24 | Color4 color = new(0.5f); 25 | Assert.That(color.R, Is.EqualTo(0.5f)); 26 | Assert.That(color.G, Is.EqualTo(0.5f)); 27 | Assert.That(color.B, Is.EqualTo(0.5f)); 28 | Assert.That(color.A, Is.EqualTo(0.5f)); 29 | 30 | color = new(1.0f, 0.0f, 1.0f, 1.0f); 31 | Assert.That(color.R, Is.EqualTo(1.0f)); 32 | Assert.That(color.G, Is.EqualTo(0.0f)); 33 | Assert.That(color.B, Is.EqualTo(1.0f)); 34 | Assert.That(color.A, Is.EqualTo(1.0f)); 35 | } 36 | 37 | [TestCase] 38 | public void EqualTests() 39 | { 40 | Color4 first = new(0.5f); 41 | Color4 second = new(0.5f); 42 | Assert.That(first, Is.EqualTo(second)); 43 | Assert.That(first == second, Is.True); 44 | } 45 | 46 | [TestCase] 47 | public void NotEqualTests() 48 | { 49 | Color4 first = new(0.5f); 50 | Color4 second = new(0.9f); 51 | Assert.That(first, Is.Not.EqualTo(second)); 52 | Assert.That(first != second, Is.True); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/ColorBgraTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using NUnit.Framework; 5 | 6 | namespace Vortice.Mathematics.Tests; 7 | 8 | [TestFixture(TestOf = typeof(ColorBgra))] 9 | public partial class ColorBgraTests 10 | { 11 | [TestCase] 12 | public void DefaultChecks() 13 | { 14 | ColorBgra color = new ColorBgra(); 15 | Assert.That(color.R, Is.EqualTo(0)); 16 | Assert.That(color.G, Is.EqualTo(0)); 17 | Assert.That(color.B, Is.EqualTo(0)); 18 | Assert.That(color.A, Is.EqualTo(0)); 19 | Assert.That(color.PackedValue, Is.EqualTo(0u)); 20 | } 21 | 22 | [TestCase] 23 | public void CreationTests() 24 | { 25 | ColorBgra color = new(127, 127, 127, 127); 26 | Assert.That(color.R, Is.EqualTo(127)); 27 | Assert.That(color.G, Is.EqualTo(127)); 28 | Assert.That(color.B, Is.EqualTo(127)); 29 | Assert.That(color.A, Is.EqualTo(127)); 30 | 31 | color = new(0.5f); 32 | Assert.That(color.R, Is.EqualTo(128)); 33 | Assert.That(color.G, Is.EqualTo(128)); 34 | Assert.That(color.B, Is.EqualTo(128)); 35 | Assert.That(color.A, Is.EqualTo(128)); 36 | 37 | color = new(127, 0, 234, 255); 38 | Assert.That(color.R, Is.EqualTo(127)); 39 | Assert.That(color.G, Is.EqualTo(0)); 40 | Assert.That(color.B, Is.EqualTo(234)); 41 | Assert.That(color.A, Is.EqualTo(255)); 42 | 43 | color = new(0.65f, 0.0f, 0.73f, 1.0f); 44 | Assert.That(color.R, Is.EqualTo(166)); 45 | Assert.That(color.G, Is.EqualTo(0)); 46 | Assert.That(color.B, Is.EqualTo(186)); 47 | Assert.That(color.A, Is.EqualTo(255)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/ColorTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | 7 | namespace Vortice.Mathematics.Tests; 8 | 9 | [TestFixture(TestOf = typeof(Color))] 10 | public partial class ColorTests 11 | { 12 | private const float Epsilon = 0.01f; 13 | 14 | [TestCase] 15 | public void DefaultChecks() 16 | { 17 | Color color = new Color(); 18 | Assert.That(color.R, Is.EqualTo(0)); 19 | Assert.That(color.G, Is.EqualTo(0)); 20 | Assert.That(color.B, Is.EqualTo(0)); 21 | Assert.That(color.A, Is.EqualTo(0)); 22 | Assert.That(color.PackedValue, Is.EqualTo(0u)); 23 | } 24 | 25 | [TestCase] 26 | public void CreationTests() 27 | { 28 | Color color = new(127, 127, 127, 127); 29 | Assert.That(color.R, Is.EqualTo(127)); 30 | Assert.That(color.G, Is.EqualTo(127)); 31 | Assert.That(color.B, Is.EqualTo(127)); 32 | Assert.That(color.A, Is.EqualTo(127)); 33 | 34 | color = new(0.5f); 35 | Assert.That(color.R, Is.EqualTo(127)); 36 | Assert.That(color.G, Is.EqualTo(127)); 37 | Assert.That(color.B, Is.EqualTo(127)); 38 | Assert.That(color.A, Is.EqualTo(127)); 39 | 40 | color = new(127, 0, 234, 255); 41 | Assert.That(color.R, Is.EqualTo(127)); 42 | Assert.That(color.G, Is.EqualTo(0)); 43 | Assert.That(color.B, Is.EqualTo(234)); 44 | Assert.That(color.A, Is.EqualTo(255)); 45 | 46 | color = new(0.65f, 0.0f, 0.73f, 1.0f); 47 | Assert.That(color.R, Is.EqualTo(165)); 48 | Assert.That(color.G, Is.EqualTo(0)); 49 | Assert.That(color.B, Is.EqualTo(186)); 50 | Assert.That(color.A, Is.EqualTo(255)); 51 | } 52 | 53 | [TestCase] 54 | //[Ignore("Handle float comparison")] 55 | public void ConversionTests() 56 | { 57 | float red = 0.6f; 58 | float green = 0.1f; 59 | float blue = 0.7f; 60 | float alpha = 0.5f; 61 | Color color = new(red, green, blue, alpha); 62 | 63 | 64 | Vector4 vector4 = color.ToVector4(); 65 | Assert.That(vector4.X, Is.EqualTo(red).Within(Epsilon)); 66 | Assert.That(vector4.Y, Is.EqualTo(green).Within(Epsilon)); 67 | Assert.That(vector4.Z, Is.EqualTo(blue).Within(Epsilon)); 68 | Assert.That(vector4.W, Is.EqualTo(alpha).Within(Epsilon)); 69 | 70 | Color4 color4 = color.ToColor4(); 71 | Assert.That(color4.R, Is.EqualTo(red).Within(Epsilon)); 72 | Assert.That(color4.G, Is.EqualTo(green).Within(Epsilon)); 73 | Assert.That(color4.B, Is.EqualTo(blue).Within(Epsilon)); 74 | Assert.That(color4.A, Is.EqualTo(alpha).Within(Epsilon)); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/MathHelperTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using NUnit.Framework; 5 | 6 | namespace Vortice.Mathematics.Tests; 7 | 8 | [TestFixture(TestOf = typeof(MathHelper))] 9 | public partial class MathHelperTests 10 | { 11 | //[TestCase] 12 | //public void IsSupported() 13 | //{ 14 | // Assert.That(MathHelper.Lerp(3, 5), Is.EqualTo(5)); 15 | //} 16 | } 17 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/PackedVectors/Byte2NormalizedTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | using Vortice.Mathematics.PackedVector; 7 | 8 | namespace Vortice.Mathematics.Tests.PackedVectors; 9 | 10 | [TestFixture(TestOf = typeof(Byte2Normalized))] 11 | public partial class Byte2NormalizedTests 12 | { 13 | private const float Epsilon = 0.01f; 14 | 15 | [TestCase] 16 | public void DefaultChecks() 17 | { 18 | Byte2Normalized vector = new(); 19 | Assert.That(vector.X, Is.EqualTo(0)); 20 | Assert.That(vector.Y, Is.EqualTo(0)); 21 | Assert.That(vector.PackedValue, Is.EqualTo(0u)); 22 | } 23 | 24 | [TestCase] 25 | public void CreationTests() 26 | { 27 | Byte2Normalized vector = new((sbyte)125, (sbyte)-125); 28 | Assert.That(vector.X, Is.EqualTo(125)); 29 | Assert.That(vector.Y, Is.EqualTo(-125)); 30 | Assert.That(vector.PackedValue, Is.EqualTo(33661)); 31 | 32 | vector = new(0.5f, -0.5f); 33 | Assert.That(vector.X, Is.EqualTo(64.0)); 34 | Assert.That(vector.Y, Is.EqualTo(-64.0f)); 35 | 36 | Vector2 vector2 = vector.ToVector2(); 37 | 38 | Assert.That(vector2.X, Is.EqualTo(0.5f).Within(Epsilon)); 39 | Assert.That(vector2.Y, Is.EqualTo(-0.5f).Within(Epsilon)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/PackedVectors/Byte2Tests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | using Vortice.Mathematics.PackedVector; 7 | 8 | namespace Vortice.Mathematics.Tests.PackedVectors; 9 | 10 | [TestFixture(TestOf = typeof(Byte2))] 11 | public partial class Byte2Tests 12 | { 13 | [TestCase] 14 | public void DefaultChecks() 15 | { 16 | Byte2 vector = new(); 17 | Assert.That(vector.X, Is.EqualTo(0)); 18 | Assert.That(vector.Y, Is.EqualTo(0)); 19 | Assert.That(vector.PackedValue, Is.EqualTo(0u)); 20 | } 21 | 22 | [TestCase] 23 | public void CreationTests() 24 | { 25 | Byte2 vector = new((sbyte)125, (sbyte)-125); 26 | Assert.That(vector.X, Is.EqualTo(125)); 27 | Assert.That(vector.Y, Is.EqualTo(-125)); 28 | Assert.That(vector.PackedValue, Is.EqualTo(33661)); 29 | 30 | vector = new(125.0f, -125.0f); 31 | Assert.That(vector.X, Is.EqualTo(125)); 32 | Assert.That(vector.Y, Is.EqualTo(-125)); 33 | 34 | Vector2 vector2 = vector.ToVector2(); 35 | Assert.That(vector2.X, Is.EqualTo(125.0f)); 36 | Assert.That(vector2.Y, Is.EqualTo(-125.0f)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/PackedVectors/Byte4NormalizedTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | using Vortice.Mathematics.PackedVector; 7 | 8 | namespace Vortice.Mathematics.Tests.PackedVectors; 9 | 10 | [TestFixture(TestOf = typeof(Byte4Normalized))] 11 | public partial class Byte4NormalizedTests 12 | { 13 | private const float Epsilon = 0.01f; 14 | 15 | [TestCase] 16 | public void DefaultChecks() 17 | { 18 | Byte4Normalized vector = new(); 19 | Assert.That(vector.X, Is.EqualTo(0)); 20 | Assert.That(vector.Y, Is.EqualTo(0)); 21 | Assert.That(vector.Z, Is.EqualTo(0)); 22 | Assert.That(vector.W, Is.EqualTo(0)); 23 | Assert.That(vector.PackedValue, Is.EqualTo(0u)); 24 | } 25 | 26 | [TestCase] 27 | public void CreationTests() 28 | { 29 | Byte4Normalized vector = new((sbyte)125, (sbyte)-125, (sbyte)100, (sbyte)-5); 30 | Assert.That(vector.X, Is.EqualTo(125)); 31 | Assert.That(vector.Y, Is.EqualTo(-125)); 32 | Assert.That(vector.Z, Is.EqualTo(100)); 33 | Assert.That(vector.W, Is.EqualTo(-5)); 34 | Assert.That(vector.PackedValue, Is.EqualTo(4217668477)); 35 | 36 | vector = new(0.5f, -0.5f, 0.7f, -0.3f); 37 | Assert.That(vector.X, Is.EqualTo(63.0f)); 38 | Assert.That(vector.Y, Is.EqualTo(-63.0f)); 39 | Assert.That(vector.Z, Is.EqualTo(88.0f)); 40 | Assert.That(vector.W, Is.EqualTo(-38.0f)); 41 | 42 | Vector4 vector4 = vector.ToVector4(); 43 | 44 | Assert.That(vector4.X, Is.EqualTo(0.5f).Within(Epsilon)); 45 | Assert.That(vector4.Y, Is.EqualTo(-0.5f).Within(Epsilon)); 46 | Assert.That(vector4.Z, Is.EqualTo(0.7f).Within(Epsilon)); 47 | Assert.That(vector4.W, Is.EqualTo(-0.3f).Within(Epsilon)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/PackedVectors/Byte4Tests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | using Vortice.Mathematics.PackedVector; 7 | 8 | namespace Vortice.Mathematics.Tests.PackedVectors; 9 | 10 | [TestFixture(TestOf = typeof(Byte4))] 11 | public partial class Byte4Tests 12 | { 13 | [TestCase] 14 | public void DefaultChecks() 15 | { 16 | Byte4 vector = new(); 17 | Assert.That(vector.X, Is.EqualTo(0)); 18 | Assert.That(vector.Y, Is.EqualTo(0)); 19 | Assert.That(vector.Z, Is.EqualTo(0)); 20 | Assert.That(vector.W, Is.EqualTo(0)); 21 | Assert.That(vector.PackedValue, Is.EqualTo(0u)); 22 | } 23 | 24 | [TestCase] 25 | public void CreationTests() 26 | { 27 | Byte4 vector = new((sbyte)125, (sbyte)-125, (sbyte)100, (sbyte)-5); 28 | Assert.That(vector.X, Is.EqualTo(125)); 29 | Assert.That(vector.Y, Is.EqualTo(-125)); 30 | Assert.That(vector.Z, Is.EqualTo(100)); 31 | Assert.That(vector.W, Is.EqualTo(-5)); 32 | Assert.That(vector.PackedValue, Is.EqualTo(4217668477)); 33 | 34 | vector = new(125.0f, -125.0f, 100.0f, -5.0f); 35 | Assert.That(vector.X, Is.EqualTo(125)); 36 | Assert.That(vector.Y, Is.EqualTo(-125)); 37 | Assert.That(vector.Z, Is.EqualTo(100)); 38 | Assert.That(vector.W, Is.EqualTo(-5)); 39 | 40 | Vector4 vector4 = vector.ToVector4(); 41 | Assert.That(vector4.X, Is.EqualTo(125.0f)); 42 | Assert.That(vector4.Y, Is.EqualTo(-125.0f)); 43 | Assert.That(vector4.Z, Is.EqualTo(100.0f)); 44 | Assert.That(vector4.W, Is.EqualTo(-5.0f)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/PackedVectors/Half2Tests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | using Vortice.Mathematics.PackedVector; 7 | 8 | namespace Vortice.Mathematics.Tests.PackedVectors; 9 | 10 | [TestFixture(TestOf = typeof(Half2))] 11 | public partial class Half2Tests 12 | { 13 | private const float Epsilon = 0.01f; 14 | 15 | [TestCase] 16 | public void DefaultChecks() 17 | { 18 | Half2 vector = new(); 19 | Assert.That((float)vector.X, Is.EqualTo(0.0f)); 20 | Assert.That((float)vector.Y, Is.EqualTo(0.0f)); 21 | Assert.That(vector.PackedValue, Is.EqualTo(0u)); 22 | } 23 | 24 | [TestCase] 25 | public void CreationTests() 26 | { 27 | Half2 vector = new(0.5f, -0.5f); 28 | Assert.That((float)vector.X, Is.EqualTo(0.5f)); 29 | Assert.That((float)vector.Y, Is.EqualTo(-0.5f)); 30 | 31 | Vector2 vector2 = vector.ToVector2(); 32 | 33 | Assert.That(vector2.X, Is.EqualTo(0.5f).Within(Epsilon)); 34 | Assert.That(vector2.Y, Is.EqualTo(-0.5f).Within(Epsilon)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/PackedVectors/Half4Tests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | using Vortice.Mathematics.PackedVector; 7 | 8 | namespace Vortice.Mathematics.Tests.PackedVectors; 9 | 10 | [TestFixture(TestOf = typeof(Half4))] 11 | public partial class Half4Tests 12 | { 13 | private const float Epsilon = 0.01f; 14 | 15 | [TestCase] 16 | public void DefaultChecks() 17 | { 18 | Half4 vector = new(); 19 | Assert.That((float)vector.X, Is.EqualTo(0.0f)); 20 | Assert.That((float)vector.Y, Is.EqualTo(0.0f)); 21 | Assert.That((float)vector.Z, Is.EqualTo(0.0f)); 22 | Assert.That((float)vector.W, Is.EqualTo(0.0f)); 23 | Assert.That(vector.PackedValue, Is.EqualTo(0u)); 24 | } 25 | 26 | [TestCase] 27 | public void CreationTests() 28 | { 29 | Half4 vector = new(0.5f, -0.5f, 0.3f, -0.7f); 30 | Assert.That((float)vector.X, Is.EqualTo(0.5f).Within(Epsilon)); 31 | Assert.That((float)vector.Y, Is.EqualTo(-0.5f).Within(Epsilon)); 32 | Assert.That((float)vector.Z, Is.EqualTo(0.3f).Within(Epsilon)); 33 | Assert.That((float)vector.W, Is.EqualTo(-0.7f).Within(Epsilon)); 34 | 35 | Vector4 vector4 = vector.ToVector4(); 36 | 37 | Assert.That(vector4.X, Is.EqualTo(0.5f).Within(Epsilon)); 38 | Assert.That(vector4.Y, Is.EqualTo(-0.5f).Within(Epsilon)); 39 | Assert.That(vector4.Z, Is.EqualTo(0.3f).Within(Epsilon)); 40 | Assert.That(vector4.W, Is.EqualTo(-0.7f).Within(Epsilon)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/PackedVectors/Short2NormalizedTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | using Vortice.Mathematics.PackedVector; 7 | 8 | namespace Vortice.Mathematics.Tests.PackedVectors; 9 | 10 | [TestFixture(TestOf = typeof(Short2Normalized))] 11 | public partial class Short2NormalizedTests 12 | { 13 | [TestCase] 14 | public void DefaultChecks() 15 | { 16 | Short2Normalized vector = new(); 17 | Assert.That(vector.X, Is.EqualTo(0)); 18 | Assert.That(vector.Y, Is.EqualTo(0)); 19 | Assert.That(vector.PackedValue, Is.EqualTo(0u)); 20 | } 21 | 22 | [TestCase] 23 | public void CreationTests() 24 | { 25 | Short2Normalized vector = new(250, 450); 26 | Assert.That(vector.X, Is.EqualTo(250)); 27 | Assert.That(vector.Y, Is.EqualTo(450)); 28 | Assert.That(vector.PackedValue, Is.EqualTo(29491450u)); 29 | 30 | vector = new(0.5f, 0.3f); 31 | Assert.That(vector.X, Is.EqualTo(16384)); 32 | Assert.That(vector.Y, Is.EqualTo(9830)); 33 | Assert.That(vector.PackedValue, Is.EqualTo(644235264u)); 34 | 35 | Vector2 vector2 = vector.ToVector2(); 36 | Assert.That(MathHelper.CompareEqual(MathF.Round(vector2.X, 1), 0.5f), Is.True); 37 | Assert.That(MathHelper.CompareEqual(MathF.Round(vector2.Y, 1), 0.3f), Is.True); 38 | //Assert.IsTrue(Vector2Utilities.NearEqual(vector2, new Vector2(0.5f, 0.3f), MathHelper.NearZeroEpsilon)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/PackedVectors/Short2Tests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | using Vortice.Mathematics.PackedVector; 7 | 8 | namespace Vortice.Mathematics.Tests.PackedVectors; 9 | 10 | [TestFixture(TestOf = typeof(Short2))] 11 | public partial class Short2Tests 12 | { 13 | [TestCase] 14 | public void DefaultChecks() 15 | { 16 | Short2 vector = new(); 17 | Assert.That(vector.X, Is.EqualTo(0)); 18 | Assert.That(vector.Y, Is.EqualTo(0)); 19 | Assert.That(vector.PackedValue, Is.EqualTo(0u)); 20 | } 21 | 22 | [TestCase] 23 | public void CreationTests() 24 | { 25 | Short2 vector = new(250, 450); 26 | Assert.That(vector.X, Is.EqualTo(250)); 27 | Assert.That(vector.Y, Is.EqualTo(450)); 28 | Assert.That(vector.PackedValue, Is.EqualTo(29491450u)); 29 | 30 | vector = new(125.0f, 255.0f); 31 | Assert.That(vector.X, Is.EqualTo(125)); 32 | Assert.That(vector.Y, Is.EqualTo(255)); 33 | 34 | Vector2 vector2 = vector.ToVector2(); 35 | Assert.That(vector2.X, Is.EqualTo(125.0f)); 36 | Assert.That(vector2.Y, Is.EqualTo(255.0f)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/PackedVectors/Short4Tests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using NUnit.Framework; 6 | using Vortice.Mathematics.PackedVector; 7 | 8 | namespace Vortice.Mathematics.Tests.PackedVectors; 9 | 10 | [TestFixture(TestOf = typeof(Short4))] 11 | public partial class Short4Tests 12 | { 13 | [TestCase] 14 | public void DefaultChecks() 15 | { 16 | Short4 vector = new(); 17 | Assert.That(vector.X, Is.EqualTo(0)); 18 | Assert.That(vector.Y, Is.EqualTo(0)); 19 | Assert.That(vector.Z, Is.EqualTo(0)); 20 | Assert.That(vector.W, Is.EqualTo(0)); 21 | Assert.That(vector.PackedValue, Is.EqualTo(0u)); 22 | } 23 | 24 | [TestCase] 25 | public void CreationTests() 26 | { 27 | Short4 vector = new(250, 450, 320, 240); 28 | Assert.That(vector.X, Is.EqualTo(250)); 29 | Assert.That(vector.Y, Is.EqualTo(450)); 30 | Assert.That(vector.Z, Is.EqualTo(320)); 31 | Assert.That(vector.W, Is.EqualTo(240)); 32 | Assert.That(vector.PackedValue, Is.EqualTo(67555368829583610u)); 33 | 34 | vector = new(125.0f, 255.5f, 325.7f, 645.2f); 35 | Assert.That(vector.X, Is.EqualTo(125)); 36 | Assert.That(vector.Y, Is.EqualTo(256)); 37 | Assert.That(vector.Z, Is.EqualTo(326)); 38 | Assert.That(vector.W, Is.EqualTo(645)); 39 | 40 | Vector4 vector4 = vector.ToVector4(); 41 | Assert.That(vector4.X, Is.EqualTo(125.0f)); 42 | Assert.That(vector4.Y, Is.EqualTo(256.0f)); 43 | Assert.That(vector4.Z, Is.EqualTo(326.0f)); 44 | Assert.That(vector4.W, Is.EqualTo(645.0f)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/VectorUtilitiesTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Runtime.Intrinsics; 5 | using NUnit.Framework; 6 | 7 | namespace Vortice.Mathematics.Tests; 8 | 9 | [TestFixture(TestOf = typeof(VectorUtilities))] 10 | public partial class VectorUtilitiesTests 11 | { 12 | [TestCase] 13 | public void SaturateTests() 14 | { 15 | Vector128 value = VectorUtilities.Saturate(Vector128.Create(0.158f, 125.3456f, -MathF.PI, 1.4563788f)); 16 | Assert.That(value.GetElement(0), Is.EqualTo(0.158f)); 17 | Assert.That(value.GetElement(1), Is.EqualTo(1.0f)); 18 | Assert.That(value.GetElement(2), Is.EqualTo(0.0f)); 19 | Assert.That(value.GetElement(3), Is.EqualTo(1.0f)); 20 | } 21 | 22 | [TestCase] 23 | public void TruncateTests() 24 | { 25 | Vector128 value = VectorUtilities.Truncate(Vector128.Create(0.158f, 125.3456f, -MathF.PI, 1.4563788f)); 26 | Assert.That(value.GetElement(0), Is.EqualTo(0.0f)); 27 | Assert.That(value.GetElement(1), Is.EqualTo(125.0f)); 28 | Assert.That(value.GetElement(2), Is.EqualTo(-3.0f)); 29 | Assert.That(value.GetElement(3), Is.EqualTo(1.0f)); 30 | 31 | // Software fallback 32 | value = Vector128.Create( 33 | MathF.Truncate(0.158f), 34 | MathF.Truncate(125.3456f), 35 | MathF.Truncate(-MathF.PI), 36 | MathF.Truncate(1.4563788f) 37 | ); 38 | Assert.That(value.GetElement(0), Is.EqualTo(0.0f)); 39 | Assert.That(value.GetElement(1), Is.EqualTo(125.0f)); 40 | Assert.That(value.GetElement(2), Is.EqualTo(-3.0f)); 41 | Assert.That(value.GetElement(3), Is.EqualTo(1.0f)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics.Tests/Vortice.Mathematics.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0;net8.0 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/Box.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and Contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Globalization; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | using System.Text; 8 | 9 | namespace Vortice.Mathematics; 10 | 11 | /// 12 | /// Represents a 3D box. 13 | /// 14 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 15 | public struct Box : IEquatable, IFormattable 16 | { 17 | /// 18 | /// The x position of the left hand side of the box. 19 | /// 20 | public int Left; 21 | 22 | /// 23 | /// The y position of the top of the box. 24 | /// 25 | public int Top; 26 | 27 | /// 28 | /// The z position of the front of the box. 29 | /// 30 | public int Front; 31 | 32 | /// 33 | /// The x position of the right hand side of the box, plus 1. This means that Right - Left equals the width of the box. 34 | /// 35 | public int Right; 36 | 37 | /// 38 | /// The y position of the bottom of the box, plus 1. This means that top - bottom equals the height of the box. 39 | /// 40 | public int Bottom; 41 | 42 | /// 43 | /// The z position of the back of the box, plus 1. This means that front - back equals the depth of the box. 44 | /// 45 | public int Back; 46 | 47 | /// 48 | /// Initializes a new instance of structure. 49 | /// 50 | /// Left coordinates 51 | /// Top coordinates 52 | /// Front coordinate. 53 | /// 54 | /// 55 | /// 56 | public Box(int left, int top, int front, int right, int bottom, int back) 57 | { 58 | Left = left; 59 | Top = top; 60 | Front = front; 61 | Right = right; 62 | Bottom = bottom; 63 | Back = back; 64 | } 65 | 66 | /// 67 | /// Initializes a new instance of structure. 68 | /// 69 | /// The containing Left, Top and Front coordiantes. 70 | /// The containing Width, Height and Depth. 71 | public Box(in Int3 offset, in Size3 extent) 72 | { 73 | Left = offset.X; 74 | Top = offset.Y; 75 | Front = offset.Z; 76 | Right = offset.X + extent.Width; 77 | Bottom = offset.Y + extent.Height; 78 | Back = offset.Z + extent.Depth; 79 | } 80 | 81 | /// 82 | /// A with all of its components set to zero. 83 | /// 84 | public static Box Zero 85 | { 86 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 87 | get => default; 88 | } 89 | 90 | /// 91 | /// The width of the box (equals to Right - Left). 92 | /// 93 | public readonly int Width => Right - Left; 94 | 95 | /// 96 | /// The height of the box (equals to Bottom - Top). 97 | /// 98 | public readonly int Height => Bottom - Top; 99 | 100 | /// 101 | /// The depth of the box (equals to Back - Front). 102 | /// 103 | public readonly int Depth => Back - Front; 104 | 105 | /// 106 | public override readonly bool Equals([NotNullWhen(true)] object? obj) => obj is Box value && Equals(value); 107 | 108 | /// 109 | /// Determines whether the specified is equal to this instance. 110 | /// 111 | /// The to compare with this instance. 112 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 113 | public readonly bool Equals(Box other) 114 | { 115 | return Left == other.Left 116 | && Top == other.Top 117 | && Front == other.Front 118 | && Right == other.Right 119 | && Bottom == other.Bottom 120 | && Back == other.Back; 121 | } 122 | 123 | /// 124 | /// Compares two objects for equality. 125 | /// 126 | /// The on the left hand of the operand. 127 | /// The on the right hand of the operand. 128 | /// 129 | /// True if the current left is equal to the parameter; otherwise, false. 130 | /// 131 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 132 | public static bool operator ==(Box left, Box right) => left.Equals(right); 133 | 134 | /// 135 | /// Compares two objects for inequality. 136 | /// 137 | /// The on the left hand of the operand. 138 | /// The on the right hand of the operand. 139 | /// 140 | /// True if the current left is unequal to the parameter; otherwise, false. 141 | /// 142 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 143 | public static bool operator !=(Box left, Box right) => !left.Equals(right); 144 | 145 | /// 146 | public override readonly int GetHashCode() => HashCode.Combine(Left, Top, Front, Right, Bottom, Back); 147 | 148 | /// 149 | public override string ToString() => ToString(format: null, formatProvider: null); 150 | 151 | /// 152 | public readonly string ToString(string? format, IFormatProvider? formatProvider) 153 | { 154 | var separator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator; 155 | 156 | return new StringBuilder() 157 | .Append('<') 158 | .Append(Left.ToString(format, formatProvider)).Append(separator).Append(' ') 159 | .Append(Top.ToString(format, formatProvider)).Append(separator).Append(' ') 160 | .Append(Front.ToString(format, formatProvider)).Append(separator).Append(' ') 161 | .Append(Right.ToString(format, formatProvider)).Append(separator).Append(' ') 162 | .Append(Bottom.ToString(format, formatProvider)).Append(separator).Append(' ') 163 | .Append(Back.ToString(format, formatProvider)) 164 | .Append('>') 165 | .ToString(); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/ContainmentType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace Vortice.Mathematics; 5 | 6 | /// 7 | /// Defines how the bounding volumes intersects or contain one another. 8 | /// 9 | public enum ContainmentType 10 | { 11 | /// 12 | /// Indicates that there is no overlap between two bounding volumes. 13 | /// 14 | Disjoint, 15 | /// 16 | /// Indicates that one bounding volume completely contains another volume. 17 | /// 18 | Contains, 19 | /// 20 | /// Indicates that bounding volumes partially overlap one another. 21 | /// 22 | Intersects 23 | } 24 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/Extensions.uwp.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | #if WINDOWS 5 | using System.Drawing; 6 | using WindowsColor = Windows.UI.Color; 7 | using WindowsRect = Windows.Foundation.Rect; 8 | using WindowsSize = Windows.Foundation.Size; 9 | 10 | namespace Vortice.Mathematics; 11 | 12 | public static partial class Extensions 13 | { 14 | public static Point ToSystemPoint(this Windows.Foundation.Point point) 15 | { 16 | ArgumentOutOfRangeException.ThrowIfGreaterThan(point.X, int.MaxValue, nameof(point.X)); 17 | ArgumentOutOfRangeException.ThrowIfGreaterThan(point.Y, int.MaxValue, nameof(point.Y)); 18 | 19 | return new Point((int)point.X, (int)point.Y); 20 | } 21 | 22 | public static PointF ToSystemPointF(this Windows.Foundation.Point point) => 23 | new((float)point.X, (float)point.Y); 24 | 25 | public static Windows.Foundation.Point ToPlatformPoint(this Point point) => 26 | new(point.X, point.Y); 27 | 28 | public static Windows.Foundation.Point ToPlatformPoint(this PointF point) => 29 | new(point.X, point.Y); 30 | 31 | 32 | public static Size ToSystemSize(this WindowsSize size) 33 | { 34 | if (size.Width > int.MaxValue) 35 | throw new ArgumentOutOfRangeException(nameof(size.Width)); 36 | 37 | if (size.Height > int.MaxValue) 38 | throw new ArgumentOutOfRangeException(nameof(size.Height)); 39 | 40 | return new Size((int)size.Width, (int)size.Height); 41 | } 42 | 43 | public static SizeF ToSystemSizeF(this WindowsSize size) => 44 | new((float)size.Width, (float)size.Height); 45 | 46 | public static WindowsSize ToPlatformSize(this Size size) => 47 | new(size.Width, size.Height); 48 | 49 | public static WindowsSize ToPlatformSize(this SizeF size) => 50 | new(size.Width, size.Height); 51 | 52 | public static Rectangle ToSystemRect(this WindowsRect rect) 53 | { 54 | if (rect.X > int.MaxValue) 55 | throw new ArgumentOutOfRangeException(nameof(rect.X)); 56 | 57 | if (rect.Y > int.MaxValue) 58 | throw new ArgumentOutOfRangeException(nameof(rect.Y)); 59 | 60 | if (rect.Width > int.MaxValue) 61 | throw new ArgumentOutOfRangeException(nameof(rect.Width)); 62 | 63 | if (rect.Height > int.MaxValue) 64 | throw new ArgumentOutOfRangeException(nameof(rect.Height)); 65 | 66 | return new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height); 67 | } 68 | 69 | public static RectangleF ToSystemRectF(this WindowsRect rect) => 70 | new RectangleF((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height); 71 | 72 | public static WindowsRect ToPlatformRect(this Rectangle rect) => new(rect.X, rect.Y, rect.Width, rect.Height); 73 | 74 | public static WindowsRect ToPlatformRect(this RectangleF rect) => new(rect.X, rect.Y, rect.Width, rect.Height); 75 | 76 | public static Color ToSystemColor(this WindowsColor color) => new(color.R, color.G, color.B, color.A); 77 | 78 | public static WindowsColor ToPlatformColor(this Color color) => WindowsColor.FromArgb(color.A, color.R, color.G, color.B); 79 | public static WindowsColor ToPlatformColor(this System.Drawing.Color color) => WindowsColor.FromArgb(color.A, color.R, color.G, color.B); 80 | 81 | public static System.Drawing.Color ToSystemDrawingColor(this WindowsColor color) => System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B); 82 | } 83 | #endif 84 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/FormatExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | 6 | namespace Vortice.Mathematics; 7 | 8 | /// 9 | /// Defines extension methods for formatting. 10 | /// 11 | public static class FormatExtensions 12 | { 13 | public static bool TryFormat(this Vector2 vector, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = null) 14 | { 15 | int numWritten = 0; 16 | 17 | if (!"Vector2 { X = ".TryCopyTo(destination)) 18 | { 19 | charsWritten = 0; 20 | return false; 21 | } 22 | int partLength = "Vector2 { X = ".Length; 23 | 24 | numWritten += partLength; 25 | destination = destination.Slice(numWritten); 26 | 27 | if (!vector.X.TryFormat(destination, out partLength, format, provider)) 28 | { 29 | charsWritten = 0; 30 | return false; 31 | } 32 | 33 | numWritten += partLength; 34 | destination = destination.Slice(partLength); 35 | 36 | if (!", Y = ".TryCopyTo(destination)) 37 | { 38 | charsWritten = 0; 39 | return false; 40 | } 41 | partLength = ", Y = ".Length; 42 | 43 | numWritten += partLength; 44 | destination = destination.Slice(partLength); 45 | 46 | if (!vector.Y.TryFormat(destination, out partLength, format, provider)) 47 | { 48 | charsWritten = 0; 49 | return false; 50 | } 51 | 52 | numWritten += partLength; 53 | destination = destination.Slice(partLength); 54 | 55 | if (!" }".TryCopyTo(destination)) 56 | { 57 | charsWritten = 0; 58 | return false; 59 | } 60 | partLength = " }".Length; 61 | 62 | charsWritten = numWritten + partLength; 63 | return true; 64 | } 65 | 66 | public static bool TryFormat(this Vector3 vector, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = null) 67 | { 68 | int numWritten = 0; 69 | 70 | if (!"Vector3 { X = ".TryCopyTo(destination)) 71 | { 72 | charsWritten = 0; 73 | return false; 74 | } 75 | int partLength = "Vector3 { X = ".Length; 76 | 77 | numWritten += partLength; 78 | destination = destination.Slice(numWritten); 79 | 80 | if (!vector.X.TryFormat(destination, out partLength, format, provider)) 81 | { 82 | charsWritten = 0; 83 | return false; 84 | } 85 | 86 | numWritten += partLength; 87 | destination = destination.Slice(partLength); 88 | 89 | if (!", Y = ".TryCopyTo(destination)) 90 | { 91 | charsWritten = 0; 92 | return false; 93 | } 94 | partLength = ", Y = ".Length; 95 | 96 | numWritten += partLength; 97 | destination = destination.Slice(partLength); 98 | 99 | if (!vector.Y.TryFormat(destination, out partLength, format, provider)) 100 | { 101 | charsWritten = 0; 102 | return false; 103 | } 104 | 105 | numWritten += partLength; 106 | destination = destination.Slice(partLength); 107 | 108 | if (!", Z = ".TryCopyTo(destination)) 109 | { 110 | charsWritten = 0; 111 | return false; 112 | } 113 | partLength = ", Z = ".Length; 114 | 115 | numWritten += partLength; 116 | destination = destination.Slice(partLength); 117 | 118 | if (!vector.Z.TryFormat(destination, out partLength, format, provider)) 119 | { 120 | charsWritten = 0; 121 | return false; 122 | } 123 | 124 | numWritten += partLength; 125 | destination = destination.Slice(partLength); 126 | 127 | if (!" }".TryCopyTo(destination)) 128 | { 129 | charsWritten = 0; 130 | return false; 131 | } 132 | partLength = " }".Length; 133 | 134 | charsWritten = numWritten + partLength; 135 | return true; 136 | } 137 | 138 | public static bool TryFormat(this Vector2 vector, Span utf8Destination, out int bytesWritten, ReadOnlySpan format = default, IFormatProvider? provider = null) 139 | { 140 | int numWritten = 0; 141 | 142 | if (!"Vector2 { X = "u8.TryCopyTo(utf8Destination)) 143 | { 144 | bytesWritten = 0; 145 | return false; 146 | } 147 | int partLength = "Vector2 { X = "u8.Length; 148 | 149 | numWritten += partLength; 150 | utf8Destination = utf8Destination.Slice(numWritten); 151 | 152 | if (!vector.X.TryFormat(utf8Destination, out partLength, format, provider)) 153 | { 154 | bytesWritten = 0; 155 | return false; 156 | } 157 | 158 | numWritten += partLength; 159 | utf8Destination = utf8Destination.Slice(partLength); 160 | 161 | if (!", Y = "u8.TryCopyTo(utf8Destination)) 162 | { 163 | bytesWritten = 0; 164 | return false; 165 | } 166 | partLength = ", Y = "u8.Length; 167 | 168 | numWritten += partLength; 169 | utf8Destination = utf8Destination.Slice(partLength); 170 | 171 | if (!vector.Y.TryFormat(utf8Destination, out partLength, format, provider)) 172 | { 173 | bytesWritten = 0; 174 | return false; 175 | } 176 | 177 | numWritten += partLength; 178 | utf8Destination = utf8Destination.Slice(partLength); 179 | 180 | if (!" }"u8.TryCopyTo(utf8Destination)) 181 | { 182 | bytesWritten = 0; 183 | return false; 184 | } 185 | partLength = " }"u8.Length; 186 | 187 | bytesWritten = numWritten + partLength; 188 | return true; 189 | } 190 | 191 | public static bool TryFormat(this Vector3 vector, Span utf8Destination, out int bytesWritten, ReadOnlySpan format = default, IFormatProvider? provider = null) 192 | { 193 | int numWritten = 0; 194 | 195 | if (!"Vector3 { X = "u8.TryCopyTo(utf8Destination)) 196 | { 197 | bytesWritten = 0; 198 | return false; 199 | } 200 | int partLength = "Vector3 { X = "u8.Length; 201 | 202 | numWritten += partLength; 203 | utf8Destination = utf8Destination.Slice(numWritten); 204 | 205 | if (!vector.X.TryFormat(utf8Destination, out partLength, format, provider)) 206 | { 207 | bytesWritten = 0; 208 | return false; 209 | } 210 | 211 | numWritten += partLength; 212 | utf8Destination = utf8Destination.Slice(partLength); 213 | 214 | if (!", Y = "u8.TryCopyTo(utf8Destination)) 215 | { 216 | bytesWritten = 0; 217 | return false; 218 | } 219 | partLength = ", Y = "u8.Length; 220 | 221 | numWritten += partLength; 222 | utf8Destination = utf8Destination.Slice(partLength); 223 | 224 | if (!vector.Y.TryFormat(utf8Destination, out partLength, format, provider)) 225 | { 226 | bytesWritten = 0; 227 | return false; 228 | } 229 | 230 | numWritten += partLength; 231 | utf8Destination = utf8Destination.Slice(partLength); 232 | 233 | if (!", Z = "u8.TryCopyTo(utf8Destination)) 234 | { 235 | bytesWritten = 0; 236 | return false; 237 | } 238 | partLength = ", Z = "u8.Length; 239 | 240 | numWritten += partLength; 241 | utf8Destination = utf8Destination.Slice(partLength); 242 | 243 | if (!vector.Z.TryFormat(utf8Destination, out partLength, format, provider)) 244 | { 245 | bytesWritten = 0; 246 | return false; 247 | } 248 | 249 | numWritten += partLength; 250 | utf8Destination = utf8Destination.Slice(partLength); 251 | 252 | if (!" }"u8.TryCopyTo(utf8Destination)) 253 | { 254 | bytesWritten = 0; 255 | return false; 256 | } 257 | partLength = " }"u8.Length; 258 | 259 | bytesWritten = numWritten + partLength; 260 | return true; 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/Int2.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics; 5 | using System.Diagnostics.CodeAnalysis; 6 | using System.Numerics; 7 | using System.Runtime.CompilerServices; 8 | using System.Runtime.InteropServices; 9 | 10 | namespace Vortice.Mathematics; 11 | 12 | /// 13 | /// Vector type containing two 32 bit signed integer components. 14 | /// 15 | [DebuggerDisplay("X={X}, Y={Y}")] 16 | public struct Int2 : IEquatable, IFormattable 17 | { 18 | /// 19 | /// The X component of the vector. 20 | /// 21 | public int X; 22 | 23 | /// 24 | /// The Y component of the vector. 25 | /// 26 | public int Y; 27 | 28 | internal const int Count = 2; 29 | 30 | /// 31 | /// Initializes a new instance of the struct. 32 | /// 33 | /// The value that will be assigned to all components. 34 | public Int2(int value) : this(value, value) 35 | { 36 | } 37 | 38 | /// 39 | /// Initializes a new instance of the struct. 40 | /// 41 | /// Initial value for the X component of the vector. 42 | /// Initial value for the Y component of the vector. 43 | public Int2(int x, int y) 44 | { 45 | X = x; 46 | Y = y; 47 | } 48 | 49 | /// 50 | /// Initializes a new instance of the struct. 51 | /// 52 | /// The span of elements to assign to the vector. 53 | public Int2(ReadOnlySpan values) 54 | { 55 | if (values.Length < 2) 56 | { 57 | throw new ArgumentOutOfRangeException(nameof(values), "There must be 2 uint values."); 58 | } 59 | 60 | this = Unsafe.ReadUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(values))); 61 | } 62 | 63 | /// 64 | /// Initializes a new instance of the struct. 65 | /// 66 | /// containing X and Y components. 67 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 68 | public Int2(Double2 value) 69 | { 70 | X = (int)value.X; 71 | Y = (int)value.Y; 72 | } 73 | 74 | /// 75 | /// A with all of its components set to zero. 76 | /// 77 | public static Int2 Zero 78 | { 79 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 80 | get => default; 81 | } 82 | 83 | /// 84 | /// The X unit (1, 0). 85 | /// 86 | public static Int2 UnitX 87 | { 88 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 89 | get => new(1, 0); 90 | } 91 | 92 | /// 93 | /// The Y unit (0, 1). 94 | /// 95 | public static Int2 UnitY 96 | { 97 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 98 | get => new(0, 1); 99 | } 100 | 101 | /// 102 | /// A with all of its components set to one. 103 | /// 104 | public static Int2 One 105 | { 106 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 107 | get => new(1, 1); 108 | } 109 | 110 | /// Gets or sets the element at the specified index. 111 | /// The index of the element to get or set. 112 | /// The the element at . 113 | /// was less than zero or greater than the number of elements. 114 | public int this[int index] 115 | { 116 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 117 | readonly get => this.GetElement(index); 118 | 119 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 120 | set => this = this.WithElement(index, value); 121 | } 122 | 123 | public readonly void Deconstruct(out int x, out int y) 124 | { 125 | x = X; 126 | y = Y; 127 | } 128 | 129 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 130 | public readonly void CopyTo(int[] array) 131 | { 132 | CopyTo(array, 0); 133 | } 134 | 135 | public readonly void CopyTo(int[] array, int index) 136 | { 137 | if (array is null) 138 | { 139 | throw new NullReferenceException(nameof(array)); 140 | } 141 | 142 | if ((index < 0) || (index >= array.Length)) 143 | { 144 | throw new ArgumentOutOfRangeException(nameof(index)); 145 | } 146 | 147 | if ((array.Length - index) < 2) 148 | { 149 | throw new ArgumentOutOfRangeException(nameof(index)); 150 | } 151 | 152 | array[index] = X; 153 | array[index + 1] = Y; 154 | } 155 | 156 | /// Copies the vector to the given .The length of the destination span must be at least 2. 157 | /// The destination span which the values are copied into. 158 | /// If number of elements in source vector is greater than those available in destination span. 159 | public readonly void CopyTo(Span destination) 160 | { 161 | if (destination.Length < 2) 162 | { 163 | throw new ArgumentOutOfRangeException(nameof(destination)); 164 | } 165 | 166 | Unsafe.WriteUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(destination)), this); 167 | } 168 | 169 | /// Attempts to copy the vector to the given . The length of the destination span must be at least 2. 170 | /// The destination span which the values are copied into. 171 | /// if the source vector was successfully copied to . if is not large enough to hold the source vector. 172 | public readonly bool TryCopyTo(Span destination) 173 | { 174 | if (destination.Length < 2) 175 | { 176 | return false; 177 | } 178 | 179 | Unsafe.WriteUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(destination)), this); 180 | 181 | return true; 182 | } 183 | 184 | /// 185 | /// Performs an explicit conversion from to . 186 | /// 187 | /// The value to convert. 188 | /// The result of the conversion. 189 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 190 | public static explicit operator Vector2(Int2 value) => new(value.X, value.Y); 191 | 192 | /// 193 | /// Performs an explicit conversion from to . 194 | /// 195 | /// The value to convert. 196 | /// The result of the conversion. 197 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 198 | public static explicit operator Int2(Double2 value) { return new Int2(value); } 199 | 200 | /// 201 | public override readonly bool Equals([NotNullWhen(true)] object? obj) => obj is Int2 value && Equals(value); 202 | 203 | /// 204 | /// Determines whether the specified is equal to this instance. 205 | /// 206 | /// The to compare with this instance. 207 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 208 | public readonly bool Equals(Int2 other) 209 | { 210 | return X == other.X 211 | && Y == other.Y; 212 | } 213 | 214 | /// 215 | /// Compares two objects for equality. 216 | /// 217 | /// The on the left hand of the operand. 218 | /// The on the right hand of the operand. 219 | /// 220 | /// True if the current left is equal to the parameter; otherwise, false. 221 | /// 222 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 223 | public static bool operator ==(Int2 left, Int2 right) => left.Equals(right); 224 | 225 | /// 226 | /// Compares two objects for inequality. 227 | /// 228 | /// The on the left hand of the operand. 229 | /// The on the right hand of the operand. 230 | /// 231 | /// True if the current left is unequal to the parameter; otherwise, false. 232 | /// 233 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 234 | public static bool operator !=(Int2 left, Int2 right) => !left.Equals(right); 235 | 236 | /// 237 | public override readonly int GetHashCode() => HashCode.Combine(X, Y); 238 | 239 | /// 240 | public override readonly string ToString() => ToString(format: null, formatProvider: null); 241 | 242 | /// 243 | public readonly string ToString(string? format, IFormatProvider? formatProvider) 244 | => $"{nameof(Int2)} {{ {nameof(X)} = {X.ToString(format, formatProvider)}, {nameof(Y)} = {Y.ToString(format, formatProvider)} }}"; 245 | } 246 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/Matrix3x3.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | namespace Vortice.Mathematics; 7 | 8 | /// 9 | /// Describes a 3-by-3 floating point matrix. 10 | /// 11 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 12 | public readonly struct Matrix3x3 13 | { 14 | /// 15 | /// A with all of its components set to zero. 16 | /// 17 | public static Matrix3x3 Zero => new(); 18 | 19 | /// 20 | /// The identity . 21 | /// 22 | public static Matrix3x3 Identity => new(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); 23 | 24 | /// 25 | /// Value at row 1 column 1. 26 | /// 27 | public readonly float M11; 28 | 29 | /// 30 | /// Value at row 1 column 2. 31 | /// 32 | public readonly float M12; 33 | 34 | /// 35 | /// Value at row 1 column 3. 36 | /// 37 | public readonly float M13; 38 | 39 | /// 40 | /// Value at row 2 column 1. 41 | /// 42 | public readonly float M21; 43 | 44 | /// 45 | /// Value at row 2 column 2. 46 | /// 47 | public readonly float M22; 48 | 49 | /// 50 | /// Value at row 2 column 3. 51 | /// 52 | public readonly float M23; 53 | 54 | /// 55 | /// Value at row 3 column 1. 56 | /// 57 | public readonly float M31; 58 | 59 | /// 60 | /// Value at row 3 column 2. 61 | /// 62 | public readonly float M32; 63 | 64 | /// 65 | /// Value at row 3 column 3. 66 | /// 67 | public readonly float M33; 68 | 69 | /// 70 | /// Initializes a new instance of the struct. 71 | /// 72 | /// The value that will be assigned to all components. 73 | public Matrix3x3(float value) 74 | { 75 | M11 = value; 76 | M12 = value; 77 | M13 = value; 78 | M21 = value; 79 | M22 = value; 80 | M23 = value; 81 | M31 = value; 82 | M32 = value; 83 | M33 = value; 84 | } 85 | 86 | /// 87 | /// Initializes a new instance of struct. 88 | /// 89 | /// The value to assign at row 1 column 1 of the Matrix3x3. 90 | /// The value to assign at row 1 column 2 of the Matrix3x3. 91 | /// The value to assign at row 1 column 3 of the Matrix3x3. 92 | /// The value to assign at row 2 column 1 of the Matrix3x3. 93 | /// The value to assign at row 2 column 2 of the Matrix3x3. 94 | /// The value to assign at row 2 column 3 of the Matrix3x3. 95 | /// The value to assign at row 3 column 1 of the Matrix3x3. 96 | /// The value to assign at row 3 column 2 of the Matrix3x3. 97 | /// The value to assign at row 3 column 3 of the Matrix3x3. 98 | public Matrix3x3(float m11, float m12, float m13, 99 | float m21, float m22, float m23, 100 | float m31, float m32, float m33) 101 | { 102 | M11 = m11; M12 = m12; M13 = m13; 103 | M21 = m21; M22 = m22; M23 = m23; 104 | M31 = m31; M32 = m32; M33 = m33; 105 | } 106 | 107 | /// 108 | /// Initializes a new instance of the struct. 109 | /// 110 | /// The values to assign to the components of the Matrix3x3. This must be an array with nine elements. 111 | /// Thrown when is null. 112 | /// Thrown when contains more or less than nine elements. 113 | public Matrix3x3(float[] values) 114 | { 115 | if (values == null) 116 | throw new ArgumentNullException(nameof(values)); 117 | if (values.Length != 9) 118 | throw new ArgumentOutOfRangeException(nameof(values), 119 | "There must be only nine input values for Matrix3x3."); 120 | 121 | M11 = values[0]; 122 | M12 = values[1]; 123 | M13 = values[2]; 124 | 125 | M21 = values[3]; 126 | M22 = values[4]; 127 | M23 = values[5]; 128 | 129 | M31 = values[6]; 130 | M32 = values[7]; 131 | M33 = values[8]; 132 | } 133 | 134 | /// 135 | /// Initializes a new instance of the struct. 136 | /// 137 | /// The values to assign to the components of the Matrix3x3. This must be a span with nine elements. 138 | /// Thrown when is null. 139 | /// Thrown when contains more or less than nine elements. 140 | public Matrix3x3(ReadOnlySpan values) 141 | { 142 | if (values.Length != 9) 143 | throw new ArgumentOutOfRangeException(nameof(values), 144 | "There must be only nine input values for Matrix3x3."); 145 | 146 | M11 = values[0]; 147 | M12 = values[1]; 148 | M13 = values[2]; 149 | 150 | M21 = values[3]; 151 | M22 = values[4]; 152 | M23 = values[5]; 153 | 154 | M31 = values[6]; 155 | M32 = values[7]; 156 | M33 = values[8]; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/Matrix3x4.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | namespace Vortice.Mathematics; 7 | 8 | /// 9 | /// Describes a 3-by-4 floating point matrix. 10 | /// 11 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 12 | public readonly struct Matrix3x4 13 | { 14 | /// 15 | /// Value at row 1 column 1. 16 | /// 17 | public readonly float M11; 18 | 19 | /// 20 | /// Value at row 1 column 2. 21 | /// 22 | public readonly float M12; 23 | 24 | /// 25 | /// Value at row 1 column 3. 26 | /// 27 | public readonly float M13; 28 | 29 | /// 30 | /// Value at row 1 column 4. 31 | /// 32 | public readonly float M14; 33 | 34 | /// 35 | /// Value at row 2 column 1. 36 | /// 37 | public readonly float M21; 38 | 39 | /// 40 | /// Value at row 2 column 2. 41 | /// 42 | public readonly float M22; 43 | 44 | /// 45 | /// Value at row 2 column 3. 46 | /// 47 | public readonly float M23; 48 | 49 | /// 50 | /// Value at row 2 column 4. 51 | /// 52 | public readonly float M24; 53 | 54 | /// 55 | /// Value at row 3 column 1. 56 | /// 57 | public readonly float M31; 58 | 59 | /// 60 | /// Value at row 3 column 2. 61 | /// 62 | public readonly float M32; 63 | 64 | /// 65 | /// Value at row 3 column 3. 66 | /// 67 | public readonly float M33; 68 | 69 | /// 70 | /// Value at row 3 column 4. 71 | /// 72 | public readonly float M34; 73 | 74 | /// 75 | /// Initializes a new instance of the struct. 76 | /// 77 | /// The value that will be assigned to all components. 78 | public Matrix3x4(float value) 79 | { 80 | M11 = M12 = M13 = M14 = 81 | M21 = M22 = M23 = M24 = 82 | M31 = M32 = M33 = M34 = value; 83 | } 84 | 85 | /// 86 | /// Initializes a new instance of the struct. 87 | /// 88 | /// The value to assign at row 1 column 1 of the matrix. 89 | /// The value to assign at row 1 column 2 of the matrix. 90 | /// The value to assign at row 1 column 3 of the matrix. 91 | /// The value to assign at row 1 column 4 of the matrix. 92 | /// The value to assign at row 2 column 1 of the matrix. 93 | /// The value to assign at row 2 column 2 of the matrix. 94 | /// The value to assign at row 2 column 3 of the matrix. 95 | /// The value to assign at row 2 column 4 of the matrix. 96 | /// The value to assign at row 3 column 1 of the matrix. 97 | /// The value to assign at row 3 column 2 of the matrix. 98 | /// The value to assign at row 3 column 3 of the matrix. 99 | /// The value to assign at row 3 column 4 of the matrix. 100 | public Matrix3x4(float m11, float m12, float m13, float m14, 101 | float m21, float m22, float m23, float m24, 102 | float m31, float m32, float m33, float m34) 103 | { 104 | M11 = m11; 105 | M12 = m12; 106 | M13 = m13; 107 | M14 = m14; 108 | M21 = m21; 109 | M22 = m22; 110 | M23 = m23; 111 | M24 = m24; 112 | M31 = m31; 113 | M32 = m32; 114 | M33 = m33; 115 | M34 = m34; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/Matrix4x3.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Globalization; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | 8 | namespace Vortice.Mathematics; 9 | 10 | /// 11 | /// Describes a 4-by-3 floating point matrix. 12 | /// 13 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 14 | public readonly struct Matrix4x3 : IEquatable, IFormattable 15 | { 16 | /// 17 | /// Value at row 1 column 1. 18 | /// 19 | public readonly float M11; 20 | 21 | /// 22 | /// Value at row 1 column 2. 23 | /// 24 | public readonly float M12; 25 | 26 | /// 27 | /// Value at row 1 column 3. 28 | /// 29 | public readonly float M13; 30 | 31 | /// 32 | /// Value at row 2 column 1. 33 | /// 34 | public readonly float M21; 35 | 36 | /// 37 | /// Value at row 2 column 2. 38 | /// 39 | public readonly float M22; 40 | 41 | /// 42 | /// Value at row 2 column 3. 43 | /// 44 | public readonly float M23; 45 | 46 | /// 47 | /// Value at row 3 column 1. 48 | /// 49 | public readonly float M31; 50 | 51 | /// 52 | /// Value at row 3 column 2. 53 | /// 54 | public readonly float M32; 55 | 56 | /// 57 | /// Value at row 3 column 3. 58 | /// 59 | public readonly float M33; 60 | 61 | /// 62 | /// Value at row 4 column 1. 63 | /// 64 | public readonly float M41; 65 | 66 | /// 67 | /// Value at row 4 column 2. 68 | /// 69 | public readonly float M42; 70 | 71 | /// 72 | /// Value at row 4 column 3. 73 | /// 74 | public readonly float M43; 75 | 76 | /// 77 | /// Initializes a new instance of the struct. 78 | /// 79 | /// The value that will be assigned to all components. 80 | public Matrix4x3(float value) 81 | { 82 | M11 = M12 = M13 = 83 | M21 = M22 = M23 = 84 | M31 = M32 = M33 = 85 | M41 = M42 = M43 = value; 86 | } 87 | 88 | /// 89 | /// Initializes a new instance of the struct. 90 | /// 91 | /// The value to assign at row 1 column 1 of the Matrix. 92 | /// The value to assign at row 1 column 2 of the Matrix. 93 | /// The value to assign at row 1 column 3 of the Matrix. 94 | /// The value to assign at row 2 column 1 of the Matrix. 95 | /// The value to assign at row 2 column 2 of the Matrix. 96 | /// The value to assign at row 2 column 3 of the Matrix. 97 | /// The value to assign at row 3 column 1 of the Matrix. 98 | /// The value to assign at row 3 column 2 of the Matrix. 99 | /// The value to assign at row 3 column 3 of the Matrix. 100 | /// The value to assign at row 4 column 1 of the Matrix. 101 | /// The value to assign at row 4 column 2 of the Matrix. 102 | /// The value to assign at row 4 column 3 of the Matrix. 103 | public Matrix4x3( 104 | float m11, float m12, float m13, 105 | float m21, float m22, float m23, 106 | float m31, float m32, float m33, 107 | float m41, float m42, float m43) 108 | { 109 | M11 = m11; M12 = m12; M13 = m13; 110 | M21 = m21; M22 = m22; M23 = m23; 111 | M31 = m31; M32 = m32; M33 = m33; 112 | M41 = m41; M42 = m42; M43 = m43; 113 | } 114 | 115 | /// 116 | /// Compares two objects for equality. 117 | /// 118 | /// The on the left hand of the operand. 119 | /// The on the right hand of the operand. 120 | /// 121 | /// True if the current left is equal to the parameter; otherwise, false. 122 | /// 123 | public static bool operator ==(Matrix4x3 left, Matrix4x3 right) 124 | { 125 | return (left.M11 == right.M11) && (left.M12 == right.M12) && (left.M13 == right.M13) 126 | && (left.M21 == right.M21) && (left.M22 == right.M22) && (left.M23 == right.M23) 127 | && (left.M31 == right.M31) && (left.M32 == right.M32) && (left.M33 == right.M33) 128 | && (left.M41 == right.M41) && (left.M42 == right.M42) && (left.M43 == right.M43); 129 | } 130 | 131 | /// 132 | /// Compares two objects for inequality. 133 | /// 134 | /// The on the left hand of the operand. 135 | /// The on the right hand of the operand. 136 | /// 137 | /// True if the current left is unequal to the parameter; otherwise, false. 138 | /// 139 | public static bool operator !=(Matrix4x3 left, Matrix4x3 right) 140 | { 141 | return (left.M11 != right.M11) || (left.M12 != right.M12) || (left.M13 != right.M13) 142 | || (left.M21 != right.M21) || (left.M22 != right.M22) || (left.M23 != right.M23) 143 | || (left.M31 != right.M31) || (left.M32 != right.M32) || (left.M33 != right.M33) 144 | || (left.M41 != right.M41) || (left.M42 != right.M42) || (left.M43 != right.M43); 145 | } 146 | 147 | /// 148 | public override bool Equals([NotNullWhen(true)] object? obj) => (obj is Matrix4x3 other) && Equals(other); 149 | 150 | /// 151 | public bool Equals(Matrix4x3 other) => this == other; 152 | 153 | /// 154 | public override int GetHashCode() 155 | { 156 | var hashCode = new HashCode(); 157 | { 158 | hashCode.Add(M11); 159 | hashCode.Add(M12); 160 | hashCode.Add(M13); 161 | hashCode.Add(M21); 162 | hashCode.Add(M22); 163 | hashCode.Add(M23); 164 | hashCode.Add(M31); 165 | hashCode.Add(M32); 166 | hashCode.Add(M33); 167 | hashCode.Add(M41); 168 | hashCode.Add(M42); 169 | hashCode.Add(M43); 170 | } 171 | return hashCode.ToHashCode(); 172 | } 173 | 174 | /// 175 | public override string ToString() => ToString(format: null, formatProvider: null); 176 | 177 | /// 178 | public string ToString(string? format, IFormatProvider? formatProvider) 179 | { 180 | var separator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator; 181 | 182 | return new StringBuilder() 183 | .Append('<') 184 | .Append(M11.ToString(format, formatProvider)).Append(separator).Append(' ') 185 | .Append(M12.ToString(format, formatProvider)).Append(separator).Append(' ') 186 | .Append(M13.ToString(format, formatProvider)).Append(separator).Append(' ') 187 | .Append(M21.ToString(format, formatProvider)).Append(separator).Append(' ') 188 | .Append(M22.ToString(format, formatProvider)).Append(separator).Append(' ') 189 | .Append(M23.ToString(format, formatProvider)).Append(separator).Append(' ') 190 | .Append(M31.ToString(format, formatProvider)).Append(separator).Append(' ') 191 | .Append(M32.ToString(format, formatProvider)).Append(separator).Append(' ') 192 | .Append(M33.ToString(format, formatProvider)).Append(separator).Append(' ') 193 | .Append(M41.ToString(format, formatProvider)).Append(separator).Append(' ') 194 | .Append(M42.ToString(format, formatProvider)).Append(separator).Append(' ') 195 | .Append(M43.ToString(format, formatProvider)) 196 | .Append('>') 197 | .ToString(); 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/NumericsExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | 6 | namespace Vortice.Mathematics; 7 | 8 | /// 9 | /// Defines extension methods for types in the numerics namespace. 10 | /// 11 | public static class NumericsExtensions 12 | { 13 | public static Vector3 ToEuler(this in Quaternion rotation) 14 | { 15 | float xx = rotation.X * rotation.X; 16 | float yy = rotation.Y * rotation.Y; 17 | float zz = rotation.Z * rotation.Z; 18 | 19 | float m31 = 2.0f * rotation.X * rotation.Z + 2.0f * rotation.Y * rotation.W; 20 | float m32 = 2.0f * rotation.Y * rotation.Z - 2.0f * rotation.X * rotation.W; 21 | float m33 = 1.0f - 2.0f * xx - 2.0f * yy; 22 | 23 | float cy = MathF.Sqrt(m33 * m33 + m31 * m31); 24 | float cx = MathF.Atan2(-m32, cy); 25 | if (cy > 16.0f * float.Epsilon) 26 | { 27 | float m12 = 2.0f * rotation.X * rotation.Y + 2.0f * rotation.Z * rotation.W; 28 | float m22 = 1.0f - 2.0f * xx - 2.0f * zz; 29 | 30 | return new Vector3(cx, MathF.Atan2(m31, m33), MathF.Atan2(m12, m22)); 31 | } 32 | else 33 | { 34 | float m11 = 1.0f - 2.0f * yy - 2.0f * zz; 35 | float m21 = 2.0f * rotation.X * rotation.Y - 2.0f * rotation.Z * rotation.W; 36 | 37 | return new Vector3(cx, 0.0f, MathF.Atan2(-m21, m11)); 38 | } 39 | } 40 | 41 | public static Quaternion FromEuler(this in Vector3 value) 42 | { 43 | Quaternion rotation; 44 | 45 | Vector3 halfAngles = value * 0.5f; 46 | 47 | float fSinX = MathF.Sin(halfAngles.X); 48 | float fCosX = MathF.Cos(halfAngles.X); 49 | float fSinY = MathF.Sin(halfAngles.Y); 50 | float fCosY = MathF.Cos(halfAngles.Y); 51 | float fSinZ = MathF.Sin(halfAngles.Z); 52 | float fCosZ = MathF.Cos(halfAngles.Z); 53 | 54 | float fCosXY = fCosX * fCosY; 55 | float fSinXY = fSinX * fSinY; 56 | 57 | rotation.X = fSinX * fCosY * fCosZ - fSinZ * fSinY * fCosX; 58 | rotation.Y = fSinY * fCosX * fCosZ + fSinZ * fSinX * fCosY; 59 | rotation.Z = fSinZ * fCosXY - fSinXY * fCosZ; 60 | rotation.W = fCosZ * fCosXY + fSinXY * fSinZ; 61 | 62 | return rotation; 63 | } 64 | 65 | /// 66 | /// Defines a plane using a point and a normal. Missing from System.Numeric.Plane 67 | /// 68 | /// is a point of a defined plane 69 | /// is normal of the defined plane 70 | public static Plane CreatePlane(in Vector3 pointOnPlane, in Vector3 planeNormal) 71 | { 72 | return new(planeNormal, -Vector3.Dot(planeNormal, pointOnPlane)); 73 | } 74 | 75 | /// 76 | /// Defines a plane using a point and a normal. Missing from System.Numeric.Plane 77 | /// 78 | /// is a point of a defined plane 79 | /// is normal of the defined plane 80 | /// A new is defined based upon the input 81 | public static void CreatePlane(in Vector3 pointOnPlane, in Vector3 planeNormal, out Plane result) 82 | { 83 | result = new(planeNormal, -Vector3.Dot(planeNormal, pointOnPlane)); 84 | } 85 | 86 | /// 87 | /// Creates a plane of unit length. 88 | /// 89 | /// The X component of the normal. 90 | /// The Y component of the normal. 91 | /// The Z component of the normal. 92 | /// The distance of the plane along its normal from the origin. 93 | /// When the method completes, contains the normalized plane. 94 | public static void NormalizePlane(float normalX, float normalY, float normalZ, float planeD, out Plane result) 95 | { 96 | float magnitude = 1.0f / MathF.Sqrt((normalX * normalX) + (normalY * normalY) + (normalZ * normalZ)); 97 | 98 | result.Normal.X = normalX * magnitude; 99 | result.Normal.Y = normalY * magnitude; 100 | result.Normal.Z = normalZ * magnitude; 101 | result.D = planeD * magnitude; 102 | } 103 | 104 | public static Vector4 GetRow(in this Matrix4x4 matrix, int row) => new(matrix[row, 0], matrix[row, 1], matrix[row, 2], matrix[row, 3]); 105 | 106 | public static Vector4 GetColumn(in this Matrix4x4 matrix, int column) => new(matrix[0, column], matrix[1, column], matrix[2, column], matrix[3, column]); 107 | 108 | public static void SetRow(ref this Matrix4x4 matrix, int row, Vector4 value) 109 | { 110 | matrix[row, 0] = value.X; 111 | matrix[row, 1] = value.Y; 112 | matrix[row, 2] = value.Z; 113 | matrix[row, 3] = value.W; 114 | } 115 | 116 | public static void SetColumn(ref this Matrix4x4 matrix, int column, Vector4 value) 117 | { 118 | matrix[0, column] = value.X; 119 | matrix[1, column] = value.Y; 120 | matrix[2, column] = value.Z; 121 | matrix[3, column] = value.W; 122 | } 123 | 124 | 125 | public static void Deconstruct(this in Matrix4x4 matrix, out Vector3 scale, out Quaternion rotation, out Vector3 translation) 126 | { 127 | Matrix4x4.Decompose(matrix, out scale, out rotation, out translation); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackHelpers.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | namespace Vortice.Mathematics; 5 | 6 | public static unsafe class PackHelpers 7 | { 8 | public static byte ToByte(int value) 9 | { 10 | return (byte)(value < 0 ? 0 : value > 255 ? 255 : value); 11 | } 12 | 13 | public static byte ToByte(float component) 14 | { 15 | int value = (int)(component * 255.0f); 16 | return (byte)(value < 0 ? 0 : value > 255 ? 255 : value); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/Byte2.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Globalization; 5 | using System.Numerics; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using System.Runtime.Intrinsics; 9 | using static Vortice.Mathematics.VectorUtilities; 10 | 11 | namespace Vortice.Mathematics.PackedVector; 12 | 13 | /// 14 | /// Packed vector type containing two 8 bit signed integer components. 15 | /// 16 | /// Equivalent of XMBYTE2. 17 | [StructLayout(LayoutKind.Explicit)] 18 | public readonly struct Byte2 : IPackedVector, IEquatable 19 | { 20 | [FieldOffset(0)] 21 | private readonly ushort _packedValue; 22 | 23 | /// 24 | /// The X component of the vector. 25 | /// 26 | [FieldOffset(0)] 27 | public readonly sbyte X; 28 | 29 | /// 30 | /// The Y component of the vector. 31 | /// 32 | [FieldOffset(1)] 33 | public readonly sbyte Y; 34 | 35 | /// 36 | /// Initializes a new instance of the struct. 37 | /// 38 | /// The packed value to assign. 39 | public Byte2(ushort packedValue) 40 | { 41 | _packedValue = packedValue; 42 | } 43 | 44 | /// 45 | /// Initializes a new instance of the struct. 46 | /// 47 | /// The x value. 48 | /// The y value. 49 | public Byte2(sbyte x, sbyte y) 50 | { 51 | X = x; 52 | Y = y; 53 | } 54 | 55 | /// 56 | /// Initializes a new instance of the struct. 57 | /// 58 | /// The x value. 59 | /// The y value. 60 | public Byte2(float x, float y) 61 | { 62 | Vector128 vector = Clamp(Vector128.Create(x, y, 0.0f, 0.0f), ByteMin, ByteMax); 63 | vector = Round(vector); 64 | 65 | X = (sbyte)vector.GetX(); 66 | Y = (sbyte)vector.GetY(); 67 | } 68 | 69 | /// 70 | /// Initializes a new instance of the struct. 71 | /// 72 | /// The containing X and Y value. 73 | public Byte2(in Vector2 vector) 74 | : this(vector.X, vector.Y) 75 | { 76 | } 77 | 78 | /// 79 | /// Initializes a new instance of the struct. 80 | /// 81 | /// The containing X and Y value. 82 | public Byte2(Vector4 vector) 83 | : this(vector.X, vector.Y) 84 | { 85 | } 86 | 87 | /// 88 | /// Gets the packed value. 89 | /// 90 | public ushort PackedValue => _packedValue; 91 | 92 | /// 93 | /// Expands the packed representation to a . 94 | /// 95 | public Vector2 ToVector2() => new(X, Y); 96 | 97 | Vector4 IPackedVector.ToVector4() 98 | { 99 | Vector2 vector = ToVector2(); 100 | return new Vector4(vector.X, vector.Y, 0.0f, 1.0f); 101 | } 102 | 103 | /// 104 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is Byte2 other && Equals(other); 105 | 106 | /// 107 | public bool Equals(Byte2 other) => PackedValue.Equals(other.PackedValue); 108 | 109 | /// 110 | /// Compares two objects for equality. 111 | /// 112 | /// The on the left hand of the operand. 113 | /// The on the right hand of the operand. 114 | /// 115 | /// True if the current left is equal to the parameter; otherwise, false. 116 | /// 117 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 118 | public static bool operator ==(Byte2 left, Byte2 right) => left.Equals(right); 119 | 120 | /// 121 | /// Compares two objects for inequality. 122 | /// 123 | /// The on the left hand of the operand. 124 | /// The on the right hand of the operand. 125 | /// 126 | /// True if the current left is unequal to the parameter; otherwise, false. 127 | /// 128 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 129 | public static bool operator !=(Byte2 left, Byte2 right) => !left.Equals(right); 130 | 131 | /// 132 | public override int GetHashCode() => PackedValue.GetHashCode(); 133 | 134 | /// 135 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 136 | } 137 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/Byte2Normalized.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Globalization; 5 | using System.Numerics; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using System.Runtime.Intrinsics; 9 | using static Vortice.Mathematics.VectorUtilities; 10 | 11 | namespace Vortice.Mathematics.PackedVector; 12 | 13 | /// 14 | /// Packed vector type containing two 8 bit signed normalized integer components. 15 | /// 16 | /// Equivalent of XMBYTEN2. 17 | [StructLayout(LayoutKind.Explicit)] 18 | public readonly struct Byte2Normalized : IPackedVector, IEquatable 19 | { 20 | [FieldOffset(0)] 21 | private readonly ushort _packedValue; 22 | 23 | /// 24 | /// The X component of the vector. 25 | /// 26 | [FieldOffset(0)] 27 | public readonly sbyte X; 28 | 29 | /// 30 | /// The Y component of the vector. 31 | /// 32 | [FieldOffset(1)] 33 | public readonly sbyte Y; 34 | 35 | /// 36 | /// Initializes a new instance of the struct. 37 | /// 38 | /// The packed value to assign. 39 | public Byte2Normalized(ushort packedValue) 40 | { 41 | _packedValue = packedValue; 42 | } 43 | 44 | /// 45 | /// Initializes a new instance of the struct. 46 | /// 47 | /// The x value. 48 | /// The y value. 49 | public Byte2Normalized(sbyte x, sbyte y) 50 | { 51 | X = x; 52 | Y = y; 53 | } 54 | 55 | /// 56 | /// Initializes a new instance of the struct. 57 | /// 58 | /// The x value. 59 | /// The y value. 60 | public Byte2Normalized(float x, float y) 61 | { 62 | Vector128 vector = Clamp(Vector128.Create(x, y, 0.0f, 0.0f), NegativeOne, One); 63 | vector = Vector128.Multiply(vector, ByteMax); 64 | vector = Round(vector); 65 | 66 | X = (sbyte)vector.GetX(); 67 | Y = (sbyte)vector.GetY(); 68 | } 69 | 70 | /// 71 | /// Initializes a new instance of the struct. 72 | /// 73 | /// The containing X and Y value. 74 | public Byte2Normalized(in Vector2 vector) 75 | : this(vector.X, vector.Y) 76 | { 77 | } 78 | 79 | /// 80 | /// Initializes a new instance of the struct. 81 | /// 82 | /// The containing X and Y value. 83 | public Byte2Normalized(in Vector4 vector) 84 | : this(vector.X, vector.Y) 85 | { 86 | } 87 | 88 | /// 89 | /// Gets the packed value. 90 | /// 91 | public ushort PackedValue => _packedValue; 92 | 93 | /// 94 | /// Expands the packed representation to a . 95 | /// 96 | public Vector2 ToVector2() => new( 97 | (X == -128) ? -1.0f : (X * (1.0f / 127.0f)), 98 | (Y == -128) ? -1.0f : (Y * (1.0f / 127.0f)) 99 | ); 100 | 101 | Vector4 IPackedVector.ToVector4() 102 | { 103 | Vector2 vector = ToVector2(); 104 | return new Vector4(vector.X, vector.Y, 0.0f, 1.0f); 105 | } 106 | 107 | /// 108 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is Byte2Normalized other && Equals(other); 109 | 110 | /// 111 | public bool Equals(Byte2Normalized other) => PackedValue.Equals(other.PackedValue); 112 | 113 | /// 114 | /// Compares two objects for equality. 115 | /// 116 | /// The on the left hand of the operand. 117 | /// The on the right hand of the operand. 118 | /// 119 | /// True if the current left is equal to the parameter; otherwise, false. 120 | /// 121 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 122 | public static bool operator ==(Byte2Normalized left, Byte2Normalized right) => left.Equals(right); 123 | 124 | /// 125 | /// Compares two objects for inequality. 126 | /// 127 | /// The on the left hand of the operand. 128 | /// The on the right hand of the operand. 129 | /// 130 | /// True if the current left is unequal to the parameter; otherwise, false. 131 | /// 132 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 133 | public static bool operator !=(Byte2Normalized left, Byte2Normalized right) => !left.Equals(right); 134 | 135 | /// 136 | public override readonly int GetHashCode() => PackedValue.GetHashCode(); 137 | 138 | /// 139 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 140 | } 141 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/Byte4.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Globalization; 6 | using System.Numerics; 7 | using System.Runtime.CompilerServices; 8 | using System.Runtime.InteropServices; 9 | using System.Runtime.Intrinsics; 10 | using static Vortice.Mathematics.VectorUtilities; 11 | 12 | namespace Vortice.Mathematics.PackedVector; 13 | 14 | /// 15 | /// Packed vector type containing four 8 bit signed integer components. 16 | /// 17 | /// Equivalent of XMBYTE4. 18 | [StructLayout(LayoutKind.Explicit)] 19 | public readonly struct Byte4 : IPackedVector, IEquatable 20 | { 21 | [FieldOffset(0)] 22 | private readonly uint _packedValue; 23 | 24 | /// 25 | /// The X component of the vector. 26 | /// 27 | [FieldOffset(0)] 28 | public readonly sbyte X; 29 | 30 | /// 31 | /// The Y component of the vector. 32 | /// 33 | [FieldOffset(1)] 34 | public readonly sbyte Y; 35 | 36 | /// 37 | /// The Z component of the vector. 38 | /// 39 | [FieldOffset(2)] 40 | public readonly sbyte Z; 41 | 42 | /// 43 | /// The W component of the vector. 44 | /// 45 | [FieldOffset(3)] 46 | public readonly sbyte W; 47 | 48 | /// 49 | /// Initializes a new instance of the struct. 50 | /// 51 | /// The packed value to assign. 52 | public Byte4(uint packedValue) 53 | { 54 | _packedValue = packedValue; 55 | } 56 | 57 | /// 58 | /// Initializes a new instance of the struct. 59 | /// 60 | /// The x value. 61 | /// The y value. 62 | /// The z value. 63 | /// The w value. 64 | public Byte4(sbyte x, sbyte y, sbyte z, sbyte w) 65 | { 66 | X = x; 67 | Y = y; 68 | Z = z; 69 | W = w; 70 | } 71 | 72 | /// 73 | /// Initializes a new instance of the struct. 74 | /// 75 | /// The x value. 76 | /// The y value. 77 | /// The z value. 78 | /// The w value. 79 | public Byte4(float x, float y, float z, float w) 80 | { 81 | Vector128 result = Clamp(Vector128.Create(x, y, z, w), ByteMin, ByteMax); 82 | result = Round(result); 83 | 84 | X = (sbyte)result.GetX(); 85 | Y = (sbyte)result.GetY(); 86 | Z = (sbyte)result.GetZ(); 87 | W = (sbyte)result.GetW(); 88 | } 89 | 90 | /// 91 | /// Initializes a new instance of the struct. 92 | /// 93 | /// The containing X and Y value. 94 | public Byte4(in Vector4 vector) 95 | : this(vector.X, vector.Y, vector.Z, vector.W) 96 | { 97 | 98 | } 99 | 100 | /// Constructs a vector from the given . The span must contain at least 3 elements. 101 | /// The span of elements to assign to the vector. 102 | public Byte4(ReadOnlySpan values) 103 | { 104 | Vector128 result = Clamp(Vector128.Create(values), ByteMin, ByteMax); 105 | result = Round(result); 106 | 107 | X = (sbyte)result.GetX(); 108 | Y = (sbyte)result.GetY(); 109 | Z = (sbyte)result.GetZ(); 110 | W = (sbyte)result.GetW(); 111 | } 112 | 113 | /// 114 | /// Gets the packed value. 115 | /// 116 | public uint PackedValue => _packedValue; 117 | 118 | /// 119 | /// Expands the packed representation to a . 120 | /// 121 | public Vector4 ToVector4() 122 | { 123 | return new(X, Y, Z, W); 124 | } 125 | 126 | /// 127 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is Byte4 other && Equals(other); 128 | 129 | /// 130 | public bool Equals(Byte4 other) => PackedValue.Equals(other.PackedValue); 131 | 132 | /// 133 | /// Compares two objects for equality. 134 | /// 135 | /// The on the left hand of the operand. 136 | /// The on the right hand of the operand. 137 | /// 138 | /// True if the current left is equal to the parameter; otherwise, false. 139 | /// 140 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 141 | public static bool operator ==(Byte4 left, Byte4 right) => left.Equals(right); 142 | 143 | /// 144 | /// Compares two objects for inequality. 145 | /// 146 | /// The on the left hand of the operand. 147 | /// The on the right hand of the operand. 148 | /// 149 | /// True if the current left is unequal to the parameter; otherwise, false. 150 | /// 151 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 152 | public static bool operator !=(Byte4 left, Byte4 right) => !left.Equals(right); 153 | 154 | /// 155 | public override int GetHashCode() => PackedValue.GetHashCode(); 156 | 157 | /// 158 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 159 | } 160 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/Byte4Normalized.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Globalization; 6 | using System.Numerics; 7 | using System.Runtime.CompilerServices; 8 | using System.Runtime.InteropServices; 9 | using System.Runtime.Intrinsics; 10 | using static Vortice.Mathematics.VectorUtilities; 11 | 12 | namespace Vortice.Mathematics.PackedVector; 13 | 14 | /// 15 | /// Packed vector type containing four 8 bit signed normalized integer components. 16 | /// 17 | /// Equivalent of XMBYTEN4. 18 | [StructLayout(LayoutKind.Explicit)] 19 | public readonly struct Byte4Normalized : IPackedVector, IEquatable 20 | { 21 | [FieldOffset(0)] 22 | private readonly uint _packedValue; 23 | 24 | /// 25 | /// The X component of the vector. 26 | /// 27 | [FieldOffset(0)] 28 | public readonly sbyte X; 29 | 30 | /// 31 | /// The Y component of the vector. 32 | /// 33 | [FieldOffset(1)] 34 | public readonly sbyte Y; 35 | 36 | /// 37 | /// The Z component of the vector. 38 | /// 39 | [FieldOffset(2)] 40 | public readonly sbyte Z; 41 | 42 | /// 43 | /// The W component of the vector. 44 | /// 45 | [FieldOffset(3)] 46 | public readonly sbyte W; 47 | 48 | /// 49 | /// Initializes a new instance of the struct. 50 | /// 51 | /// The packed value to assign. 52 | public Byte4Normalized(uint packedValue) 53 | { 54 | _packedValue = packedValue; 55 | } 56 | 57 | /// 58 | /// Initializes a new instance of the struct. 59 | /// 60 | /// The x value. 61 | /// The y value. 62 | /// The z value. 63 | /// The w value. 64 | public Byte4Normalized(sbyte x, sbyte y, sbyte z, sbyte w) 65 | { 66 | X = x; 67 | Y = y; 68 | Z = z; 69 | W = w; 70 | } 71 | 72 | /// 73 | /// Initializes a new instance of the struct. 74 | /// 75 | /// The x value. 76 | /// The y value. 77 | /// The z value. 78 | /// The w value. 79 | public Byte4Normalized(float x, float y, float z, float w) 80 | { 81 | Vector128 result = Clamp(Vector128.Create(x, y, z, w), NegativeOne, One); 82 | result = Vector128.Multiply(result, ByteMax); 83 | result = Truncate(result); 84 | 85 | X = (sbyte)result.GetX(); 86 | Y = (sbyte)result.GetY(); 87 | Z = (sbyte)result.GetZ(); 88 | W = (sbyte)result.GetW(); 89 | } 90 | 91 | /// 92 | /// Initializes a new instance of the struct. 93 | /// 94 | /// The containing X and Y value. 95 | public Byte4Normalized(in Vector4 vector) 96 | : this(vector.X, vector.Y, vector.Z, vector.W) 97 | { 98 | } 99 | 100 | /// Constructs a vector from the given . The span must contain at least 3 elements. 101 | /// The span of elements to assign to the vector. 102 | public Byte4Normalized(ReadOnlySpan values) 103 | { 104 | if (values.Length < 4) 105 | { 106 | throw new ArgumentOutOfRangeException(nameof(values)); 107 | } 108 | 109 | Vector128 result = Clamp(Vector128.Create(values), NegativeOne, One); 110 | result = Vector128.Multiply(result, ByteMax); 111 | result = Truncate(result); 112 | 113 | X = (sbyte)result.GetX(); 114 | Y = (sbyte)result.GetY(); 115 | Z = (sbyte)result.GetZ(); 116 | W = (sbyte)result.GetW(); 117 | } 118 | 119 | /// 120 | /// Gets the packed value. 121 | /// 122 | public uint PackedValue => _packedValue; 123 | 124 | /// 125 | /// Expands the packed representation to a . 126 | /// 127 | public Vector4 ToVector4() 128 | { 129 | return new( 130 | (X == -128) ? -1.0f : (X * (1.0f / 127.0f)), 131 | (Y == -128) ? -1.0f : (Y * (1.0f / 127.0f)), 132 | (Z == -128) ? -1.0f : (Z * (1.0f / 127.0f)), 133 | (W == -128) ? -1.0f : (W * (1.0f / 127.0f)) 134 | ); 135 | } 136 | 137 | /// 138 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is Byte4Normalized other && Equals(other); 139 | 140 | /// 141 | public bool Equals(Byte4Normalized other) => PackedValue.Equals(other.PackedValue); 142 | 143 | /// 144 | /// Compares two objects for equality. 145 | /// 146 | /// The on the left hand of the operand. 147 | /// The on the right hand of the operand. 148 | /// 149 | /// True if the current left is equal to the parameter; otherwise, false. 150 | /// 151 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 152 | public static bool operator ==(Byte4Normalized left, Byte4Normalized right) => left.Equals(right); 153 | 154 | /// 155 | /// Compares two objects for inequality. 156 | /// 157 | /// The on the left hand of the operand. 158 | /// The on the right hand of the operand. 159 | /// 160 | /// True if the current left is unequal to the parameter; otherwise, false. 161 | /// 162 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 163 | public static bool operator !=(Byte4Normalized left, Byte4Normalized right) => !left.Equals(right); 164 | 165 | /// 166 | public override int GetHashCode() => PackedValue.GetHashCode(); 167 | 168 | /// 169 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 170 | } 171 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/Half2.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Numerics; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | 9 | namespace Vortice.Mathematics.PackedVector; 10 | 11 | /// 12 | /// Packed vector type containing two 16-bit floating-point values. 13 | /// 14 | /// Equivalent of XMHALF2. 15 | [StructLayout(LayoutKind.Explicit)] 16 | public readonly struct Half2 : IPackedVector, IEquatable, IFormattable 17 | { 18 | [FieldOffset(0)] 19 | private readonly uint _packedValue; 20 | 21 | /// 22 | /// Gets or sets the X component of the vector. 23 | /// 24 | [FieldOffset(0)] 25 | public readonly Half X; 26 | 27 | /// 28 | /// Gets or sets the Y component of the vector. 29 | /// 30 | [FieldOffset(2)] 31 | public readonly Half Y; 32 | 33 | /// 34 | /// Initializes a new instance of the struct. 35 | /// 36 | /// The packed value to assign. 37 | public Half2(uint packedValue) 38 | { 39 | _packedValue = packedValue; 40 | } 41 | 42 | /// 43 | /// Initializes a new instance of the structure. 44 | /// 45 | /// The X component. 46 | /// The Y component. 47 | public Half2(Half x, Half y) 48 | { 49 | X = x; 50 | Y = y; 51 | } 52 | 53 | /// 54 | /// Initializes a new instance of the structure. 55 | /// 56 | /// The X component. 57 | /// The Y component. 58 | public Half2(float x, float y) 59 | { 60 | X = (Half)x; 61 | Y = (Half)y; 62 | } 63 | 64 | /// 65 | /// Initializes a new instance of the structure. 66 | /// 67 | /// The X component. 68 | /// The Y component. 69 | public Half2(ushort x, ushort y) 70 | { 71 | X = (Half)x; 72 | Y = (Half)y; 73 | } 74 | 75 | /// 76 | /// Initializes a new instance of the structure. 77 | /// 78 | /// The value to set for both the X and Y components. 79 | public Half2(Half value) 80 | { 81 | X = value; 82 | Y = value; 83 | } 84 | 85 | /// 86 | /// Initializes a new instance of the structure. 87 | /// 88 | /// Value to initialize X and Y components with. 89 | public Half2(float value) 90 | { 91 | X = (Half)value; 92 | Y = (Half)value; 93 | } 94 | 95 | /// 96 | /// Initializes a new instance of the structure. 97 | /// 98 | /// The to pack from. 99 | public Half2(in Vector2 vector) 100 | : this(vector.X, vector.Y) 101 | { 102 | } 103 | 104 | /// 105 | /// Initializes a new instance of the structure. 106 | /// 107 | /// The to pack from. 108 | public Half2(in Vector4 vector) 109 | { 110 | X = (Half)vector.X; 111 | Y = (Half)vector.Y; 112 | } 113 | 114 | /// 115 | /// Gets the packed value. 116 | /// 117 | public uint PackedValue => _packedValue; 118 | 119 | /// 120 | /// Performs an explicit conversion from to . 121 | /// 122 | /// The value. 123 | /// The result of the conversion. 124 | public static implicit operator Half2(in Vector2 value) => new(value.X, value.Y); 125 | 126 | /// 127 | /// Performs an explicit conversion from to . 128 | /// 129 | /// The value. 130 | /// The result of the conversion. 131 | public static implicit operator Vector2(in Half2 value) => value.ToVector2(); 132 | 133 | /// 134 | /// Expands this structure to a . 135 | /// 136 | public Vector2 ToVector2() 137 | { 138 | return new((float)X, (float)Y); 139 | } 140 | 141 | #region IPackedVector Implementation 142 | uint IPackedVector.PackedValue => PackedValue; 143 | 144 | Vector4 IPackedVector.ToVector4() 145 | { 146 | Vector2 vector = ToVector2(); 147 | return new Vector4(vector.X, vector.Y, 0.0f, 1.0f); 148 | } 149 | #endregion IPackedVector Implementation 150 | 151 | /// 152 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is Half2 value && Equals(value); 153 | 154 | /// 155 | /// Determines whether the specified is equal to this instance. 156 | /// 157 | /// The to compare with this instance. 158 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 159 | public bool Equals(Half2 other) => X == other.X && Y == other.Y; 160 | 161 | /// 162 | /// Compares two objects for equality. 163 | /// 164 | /// The on the left hand of the operand. 165 | /// The on the right hand of the operand. 166 | /// 167 | /// True if the current left is equal to the parameter; otherwise, false. 168 | /// 169 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 170 | public static bool operator ==(Half2 left, Half2 right) => left.Equals(right); 171 | 172 | /// 173 | /// Compares two objects for inequality. 174 | /// 175 | /// The on the left hand of the operand. 176 | /// The on the right hand of the operand. 177 | /// 178 | /// True if the current left is unequal to the parameter; otherwise, false. 179 | /// 180 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 181 | public static bool operator !=(Half2 left, Half2 right) => !left.Equals(right); 182 | 183 | /// 184 | public override int GetHashCode() => HashCode.Combine(X, Y); 185 | 186 | /// 187 | public override string ToString() => ToString(format: null, formatProvider: null); 188 | 189 | /// 190 | public string ToString(string? format, IFormatProvider? formatProvider) 191 | { 192 | Vector2 vector = ToVector2(); 193 | return vector.ToString(format, formatProvider); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/Half4.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | 8 | namespace Vortice.Mathematics.PackedVector; 9 | 10 | /// 11 | /// Packed vector type containing four 16-bit floating-point values. 12 | /// 13 | /// Equivalent of XMHALF4. 14 | [StructLayout(LayoutKind.Explicit)] 15 | public readonly struct Half4 : IPackedVector, IEquatable, IFormattable 16 | { 17 | [FieldOffset(0)] 18 | private readonly ulong _packedValue; 19 | 20 | /// 21 | /// Gets or sets the X component of the vector. 22 | /// 23 | [FieldOffset(0)] 24 | public readonly Half X; 25 | 26 | /// 27 | /// Gets or sets the Y component of the vector. 28 | /// 29 | [FieldOffset(2)] 30 | public readonly Half Y; 31 | 32 | /// 33 | /// Gets or sets the Z component of the vector. 34 | /// 35 | [FieldOffset(4)] 36 | public readonly Half Z; 37 | 38 | /// 39 | /// Gets or sets the W component of the vector. 40 | /// 41 | [FieldOffset(6)] 42 | public readonly Half W; 43 | 44 | /// 45 | /// Initializes a new instance of the struct. 46 | /// 47 | /// The packed value to assign. 48 | public Half4(ulong packedValue) 49 | { 50 | Unsafe.SkipInit(out this); 51 | 52 | _packedValue = packedValue; 53 | } 54 | 55 | /// 56 | /// Initializes a new instance of the structure. 57 | /// 58 | /// The X component. 59 | /// The Y component. 60 | /// The Z component. 61 | /// The W component. 62 | public Half4(Half x, Half y, Half z, Half w) 63 | { 64 | Unsafe.SkipInit(out this); 65 | 66 | X = x; 67 | Y = y; 68 | Z = z; 69 | W = w; 70 | } 71 | 72 | /// 73 | /// Initializes a new instance of the structure. 74 | /// 75 | /// The X component. 76 | /// The Y component. 77 | /// The Z component. 78 | /// The W component. 79 | public Half4(float x, float y, float z, float w) 80 | { 81 | Unsafe.SkipInit(out this); 82 | 83 | X = (Half)x; 84 | Y = (Half)y; 85 | Z = (Half)z; 86 | W = (Half)w; 87 | } 88 | 89 | /// 90 | /// Initializes a new instance of the structure. 91 | /// 92 | /// The value to set for both the X, Y, Z and W components. 93 | public Half4(Half value) 94 | { 95 | Unsafe.SkipInit(out this); 96 | 97 | X = value; 98 | Y = value; 99 | Z = value; 100 | W = value; 101 | } 102 | 103 | /// 104 | /// Initializes a new instance of the structure. 105 | /// 106 | /// The value to set for both the X, Y, Z and W components. 107 | public Half4(float value) 108 | { 109 | Unsafe.SkipInit(out this); 110 | 111 | X = (Half)value; 112 | Y = (Half)value; 113 | Z = (Half)value; 114 | W = (Half)value; 115 | } 116 | 117 | /// 118 | /// Initializes a new instance of the structure. 119 | /// 120 | /// The to pack from. 121 | public Half4(Vector4 vector) 122 | { 123 | Unsafe.SkipInit(out this); 124 | 125 | X = (Half)vector.X; 126 | Y = (Half)vector.Y; 127 | Z = (Half)vector.Z; 128 | W = (Half)vector.W; 129 | } 130 | 131 | /// 132 | /// Gets the packed value. 133 | /// 134 | public ulong PackedValue => _packedValue; 135 | 136 | /// 137 | /// Performs an explicit conversion from to . 138 | /// 139 | /// The value. 140 | /// The result of the conversion. 141 | public static implicit operator Half4(Vector4 value) => new(value.X, value.Y, value.Z, value.W); 142 | 143 | /// 144 | /// Performs an explicit conversion from to . 145 | /// 146 | /// The value. 147 | /// The result of the conversion. 148 | public static implicit operator Vector4(Half4 value) => value.ToVector4(); 149 | 150 | /// 151 | /// Expands this structure to a . 152 | /// 153 | public Vector4 ToVector4() 154 | { 155 | return new((float)X, (float)Y, (float)Z, (float)W); 156 | } 157 | 158 | #region IPackedVector Implementation 159 | ulong IPackedVector.PackedValue => PackedValue; 160 | 161 | Vector4 IPackedVector.ToVector4() 162 | { 163 | return ToVector4(); 164 | } 165 | #endregion IPackedVector Implementation 166 | 167 | /// 168 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is Half4 value && Equals(value); 169 | 170 | /// 171 | /// Determines whether the specified is equal to this instance. 172 | /// 173 | /// The to compare with this instance. 174 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 175 | public bool Equals(Half4 other) => 176 | X == other.X 177 | && Y == other.Y 178 | && Z == other.Z 179 | && W == other.W; 180 | 181 | /// 182 | /// Compares two objects for equality. 183 | /// 184 | /// The on the left hand of the operand. 185 | /// The on the right hand of the operand. 186 | /// 187 | /// True if the current left is equal to the parameter; otherwise, false. 188 | /// 189 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 190 | public static bool operator ==(Half4 left, Half4 right) => left.Equals(right); 191 | 192 | /// 193 | /// Compares two objects for inequality. 194 | /// 195 | /// The on the left hand of the operand. 196 | /// The on the right hand of the operand. 197 | /// 198 | /// True if the current left is unequal to the parameter; otherwise, false. 199 | /// 200 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 201 | public static bool operator !=(Half4 left, Half4 right) => !left.Equals(right); 202 | 203 | /// 204 | public override int GetHashCode() => HashCode.Combine(X, Y, Z, W); 205 | 206 | /// 207 | public override string ToString() => ToString(format: null, formatProvider: null); 208 | 209 | /// 210 | public string ToString(string? format, IFormatProvider? formatProvider) 211 | { 212 | Vector4 vector = ToVector4(); 213 | return vector.ToString(format, formatProvider); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/IPackedVector.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | 6 | namespace Vortice.Mathematics.PackedVector; 7 | 8 | /// 9 | /// Interface that converts packed vector types to and from values. 10 | /// 11 | public interface IPackedVector 12 | { 13 | /// 14 | /// Converts the packed representation into a . 15 | /// 16 | Vector4 ToVector4(); 17 | } 18 | 19 | /// 20 | /// Converts packed vector types to and from values. 21 | /// 22 | public interface IPackedVector : IPackedVector 23 | { 24 | /// 25 | /// Gets or Sets the packed representation of the value. 26 | /// 27 | TPacked PackedValue { get; } 28 | } 29 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/Short2.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Globalization; 5 | using System.Numerics; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using System.Runtime.Intrinsics; 9 | using static Vortice.Mathematics.VectorUtilities; 10 | 11 | namespace Vortice.Mathematics.PackedVector; 12 | 13 | /// 14 | /// Packed vector type containing two 16-bit signed integer values. 15 | /// 16 | /// Equivalent of XMSHORT2. 17 | [StructLayout(LayoutKind.Explicit)] 18 | public readonly struct Short2 : IPackedVector, IEquatable 19 | { 20 | [FieldOffset(0)] 21 | private readonly uint _packedValue; 22 | 23 | /// 24 | /// The X component of the vector. 25 | /// 26 | [FieldOffset(0)] 27 | public readonly short X; 28 | 29 | /// 30 | /// The Y component of the vector. 31 | /// 32 | [FieldOffset(2)] 33 | public readonly short Y; 34 | 35 | /// 36 | /// Initializes a new instance of the struct. 37 | /// 38 | /// The packed value to assign. 39 | public Short2(uint packedValue) 40 | { 41 | _packedValue = packedValue; 42 | } 43 | 44 | /// 45 | /// Initializes a new instance of the struct. 46 | /// 47 | /// The x value. 48 | /// The y value. 49 | public Short2(short x, short y) 50 | { 51 | X = x; 52 | Y = y; 53 | } 54 | 55 | /// 56 | /// Initializes a new instance of the struct. 57 | /// 58 | /// The x value. 59 | /// The y value. 60 | public Short2(float x, float y) 61 | { 62 | Vector128 vector = Clamp(Vector128.Create(x, y, 0.0f, 0.0f), ShortMin, ShortMax); 63 | vector = Round(vector); 64 | 65 | X = (short)vector.GetX(); 66 | Y = (short)vector.GetY(); 67 | } 68 | 69 | /// 70 | /// Initializes a new instance of the struct. 71 | /// 72 | /// The containing X and Y value. 73 | public Short2(Vector2 vector) 74 | : this(vector.X, vector.Y) 75 | { 76 | } 77 | 78 | /// 79 | /// Initializes a new instance of the struct. 80 | /// 81 | /// The containing X and Y value. 82 | public Short2(Vector4 vector) 83 | : this(vector.X, vector.Y) 84 | { 85 | } 86 | 87 | /// 88 | /// Gets the packed value. 89 | /// 90 | public uint PackedValue => _packedValue; 91 | 92 | /// 93 | /// Expands the packed representation to a . 94 | /// 95 | public Vector2 ToVector2() => new(X, Y); 96 | 97 | Vector4 IPackedVector.ToVector4() 98 | { 99 | Vector2 vector = ToVector2(); 100 | return new Vector4(vector.X, vector.Y, 0.0f, 1.0f); 101 | } 102 | 103 | /// 104 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is Short2 other && Equals(other); 105 | 106 | /// 107 | public bool Equals(Short2 other) => PackedValue.Equals(other.PackedValue); 108 | 109 | /// 110 | /// Compares two objects for equality. 111 | /// 112 | /// The on the left hand of the operand. 113 | /// The on the right hand of the operand. 114 | /// 115 | /// True if the current left is equal to the parameter; otherwise, false. 116 | /// 117 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 118 | public static bool operator ==(Short2 left, Short2 right) => left.Equals(right); 119 | 120 | /// 121 | /// Compares two objects for inequality. 122 | /// 123 | /// The on the left hand of the operand. 124 | /// The on the right hand of the operand. 125 | /// 126 | /// True if the current left is unequal to the parameter; otherwise, false. 127 | /// 128 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 129 | public static bool operator !=(Short2 left, Short2 right) => !left.Equals(right); 130 | 131 | /// 132 | public override int GetHashCode() => PackedValue.GetHashCode(); 133 | 134 | /// 135 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 136 | } 137 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/Short2Normalized.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Globalization; 5 | using System.Numerics; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using System.Runtime.Intrinsics; 9 | using static Vortice.Mathematics.VectorUtilities; 10 | 11 | namespace Vortice.Mathematics.PackedVector; 12 | 13 | /// 14 | /// Packed vector type containing two 16-bit signed normalized integer components. 15 | /// 16 | /// Equivalent of XMSHORTN2. 17 | [StructLayout(LayoutKind.Explicit)] 18 | public readonly struct Short2Normalized : IPackedVector, IEquatable 19 | { 20 | [FieldOffset(0)] 21 | private readonly uint _packedValue; 22 | 23 | /// 24 | /// The X component of the vector. 25 | /// 26 | [FieldOffset(0)] 27 | public readonly short X; 28 | 29 | /// 30 | /// The Y component of the vector. 31 | /// 32 | [FieldOffset(2)] 33 | public readonly short Y; 34 | 35 | /// 36 | /// Initializes a new instance of the struct. 37 | /// 38 | /// The packed value to assign. 39 | public Short2Normalized(uint packedValue) 40 | { 41 | _packedValue = packedValue; 42 | } 43 | 44 | /// 45 | /// Initializes a new instance of the struct. 46 | /// 47 | /// The x value. 48 | /// The y value. 49 | public Short2Normalized(short x, short y) 50 | { 51 | X = x; 52 | Y = y; 53 | } 54 | 55 | /// 56 | /// Initializes a new instance of the struct. 57 | /// 58 | /// The x value. 59 | /// The y value. 60 | public Short2Normalized(float x, float y) 61 | { 62 | Vector128 vector = Clamp(Vector128.Create(x, y, 0.0f, 0.0f), NegativeOne, One); 63 | vector = Vector128.Multiply(vector, ShortMax); 64 | vector = Round(vector); 65 | 66 | X = (short)vector.GetX(); 67 | Y = (short)vector.GetY(); 68 | } 69 | 70 | /// 71 | /// Initializes a new instance of the struct. 72 | /// 73 | /// The containing X and Y value. 74 | public Short2Normalized(Vector2 vector) 75 | : this(vector.X, vector.Y) 76 | { 77 | } 78 | 79 | /// 80 | /// Initializes a new instance of the struct. 81 | /// 82 | /// The containing X and Y value. 83 | public Short2Normalized(Vector4 vector) 84 | : this(vector.X, vector.Y) 85 | { 86 | } 87 | 88 | /// 89 | /// Gets the packed value. 90 | /// 91 | public uint PackedValue => _packedValue; 92 | 93 | /// 94 | /// Expands the packed representation to a . 95 | /// 96 | public Vector2 ToVector2() => new( 97 | (X == -32768) ? -1.0f : (float)X * (1.0f / 32767.0f), 98 | (Y == -32768) ? -1.0f : (float)Y * (1.0f / 32767.0f) 99 | ); 100 | 101 | Vector4 IPackedVector.ToVector4() 102 | { 103 | Vector2 vector = ToVector2(); 104 | return new Vector4(vector.X, vector.Y, 0.0f, 1.0f); 105 | } 106 | 107 | /// 108 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is Short2Normalized other && Equals(other); 109 | 110 | /// 111 | public bool Equals(Short2Normalized other) => PackedValue.Equals(other.PackedValue); 112 | 113 | /// 114 | /// Compares two objects for equality. 115 | /// 116 | /// The on the left hand of the operand. 117 | /// The on the right hand of the operand. 118 | /// 119 | /// True if the current left is equal to the parameter; otherwise, false. 120 | /// 121 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 122 | public static bool operator ==(Short2Normalized left, Short2Normalized right) => left.Equals(right); 123 | 124 | /// 125 | /// Compares two objects for inequality. 126 | /// 127 | /// The on the left hand of the operand. 128 | /// The on the right hand of the operand. 129 | /// 130 | /// True if the current left is unequal to the parameter; otherwise, false. 131 | /// 132 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 133 | public static bool operator !=(Short2Normalized left, Short2Normalized right) => !left.Equals(right); 134 | 135 | /// 136 | public override int GetHashCode() => PackedValue.GetHashCode(); 137 | 138 | /// 139 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 140 | } 141 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/Short4.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Globalization; 5 | using System.Numerics; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using System.Runtime.Intrinsics; 9 | using static Vortice.Mathematics.VectorUtilities; 10 | 11 | namespace Vortice.Mathematics.PackedVector; 12 | 13 | /// 14 | /// Packed vector type containing four 16-bit signed integer values. 15 | /// 16 | /// Equivalent of XMSHORT4. 17 | [StructLayout(LayoutKind.Explicit)] 18 | public readonly struct Short4 : IPackedVector, IEquatable 19 | { 20 | [FieldOffset(0)] 21 | private readonly ulong _packedValue; 22 | 23 | /// 24 | /// The X component of the vector. 25 | /// 26 | [FieldOffset(0)] 27 | public readonly short X; 28 | 29 | /// 30 | /// The Y component of the vector. 31 | /// 32 | [FieldOffset(2)] 33 | public readonly short Y; 34 | 35 | /// 36 | /// The Z component of the vector. 37 | /// 38 | [FieldOffset(4)] 39 | public readonly short Z; 40 | 41 | /// 42 | /// The W component of the vector. 43 | /// 44 | [FieldOffset(6)] 45 | public readonly short W; 46 | 47 | /// 48 | /// Initializes a new instance of the struct. 49 | /// 50 | /// The packed value to assign. 51 | public Short4(ulong packedValue) 52 | { 53 | _packedValue = packedValue; 54 | } 55 | 56 | /// 57 | /// Initializes a new instance of the struct. 58 | /// 59 | /// The x value. 60 | /// The y value. 61 | /// The z value. 62 | /// The w value. 63 | public Short4(short x, short y, short z, short w) 64 | { 65 | X = x; 66 | Y = y; 67 | Z = z; 68 | W = w; 69 | } 70 | 71 | /// 72 | /// Initializes a new instance of the struct. 73 | /// 74 | /// The x value. 75 | /// The y value. 76 | /// The z value. 77 | /// The w value. 78 | public Short4(float x, float y, float z, float w) 79 | { 80 | Vector128 vector = Clamp(Vector128.Create(x, y, z, w), ShortMin, ShortMax); 81 | vector = Round(vector); 82 | 83 | X = (short)vector.GetX(); 84 | Y = (short)vector.GetY(); 85 | Z = (short)vector.GetZ(); 86 | W = (short)vector.GetW(); 87 | } 88 | 89 | /// 90 | /// Initializes a new instance of the struct. 91 | /// 92 | /// The containing X, Y, Z and W value. 93 | public Short4(in Vector4 vector) 94 | : this(vector.X, vector.Y, vector.Z, vector.W) 95 | { 96 | } 97 | 98 | /// 99 | /// Gets the packed value. 100 | /// 101 | public ulong PackedValue => _packedValue; 102 | 103 | /// 104 | /// Expands the packed representation to a . 105 | /// 106 | public Vector4 ToVector4() => new(X, Y, Z, W); 107 | /// 108 | public override readonly bool Equals([NotNullWhen(true)] object? obj) => obj is Short4 other && Equals(other); 109 | 110 | /// 111 | public readonly bool Equals(Short4 other) => PackedValue.Equals(other.PackedValue); 112 | 113 | /// 114 | /// Compares two objects for equality. 115 | /// 116 | /// The on the left hand of the operand. 117 | /// The on the right hand of the operand. 118 | /// 119 | /// True if the current left is equal to the parameter; otherwise, false. 120 | /// 121 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 122 | public static bool operator ==(Short4 left, Short4 right) => left.Equals(right); 123 | 124 | /// 125 | /// Compares two objects for inequality. 126 | /// 127 | /// The on the left hand of the operand. 128 | /// The on the right hand of the operand. 129 | /// 130 | /// True if the current left is unequal to the parameter; otherwise, false. 131 | /// 132 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 133 | public static bool operator !=(Short4 left, Short4 right) => !left.Equals(right); 134 | 135 | /// 136 | public override int GetHashCode() => PackedValue.GetHashCode(); 137 | 138 | /// 139 | public override string ToString() => PackedValue.ToString("X16", CultureInfo.InvariantCulture); 140 | } 141 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/Short4Normalized.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Globalization; 5 | using System.Numerics; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using System.Runtime.Intrinsics; 9 | using static Vortice.Mathematics.VectorUtilities; 10 | 11 | namespace Vortice.Mathematics.PackedVector; 12 | 13 | /// 14 | /// Packed vector type containing four 16-bit signed normalized integer components. 15 | /// 16 | /// Equivalent of XMSHORTN4. 17 | [StructLayout(LayoutKind.Explicit)] 18 | public readonly struct Short4Normalized : IPackedVector, IEquatable 19 | { 20 | [FieldOffset(0)] 21 | private readonly ulong _packedValue; 22 | 23 | /// 24 | /// The X component of the vector. 25 | /// 26 | [FieldOffset(0)] 27 | public readonly short X; 28 | 29 | /// 30 | /// The Y component of the vector. 31 | /// 32 | [FieldOffset(2)] 33 | public readonly short Y; 34 | 35 | /// 36 | /// The Z component of the vector. 37 | /// 38 | [FieldOffset(4)] 39 | public readonly short Z; 40 | 41 | /// 42 | /// The W component of the vector. 43 | /// 44 | [FieldOffset(6)] 45 | public readonly short W; 46 | 47 | /// 48 | /// Initializes a new instance of the struct. 49 | /// 50 | /// The packed value to assign. 51 | public Short4Normalized(ulong packedValue) 52 | { 53 | _packedValue = packedValue; 54 | } 55 | 56 | /// 57 | /// Initializes a new instance of the struct. 58 | /// 59 | /// The x value. 60 | /// The y value. 61 | /// The z value. 62 | /// The w value. 63 | public Short4Normalized(short x, short y, short z, short w) 64 | { 65 | X = x; 66 | Y = y; 67 | Z = z; 68 | W = w; 69 | } 70 | 71 | /// 72 | /// Initializes a new instance of the struct. 73 | /// 74 | /// The x value. 75 | /// The y value. 76 | /// The z value. 77 | /// The w value. 78 | public Short4Normalized(float x, float y, float z, float w) 79 | { 80 | Vector128 vector = Clamp(Vector128.Create(x, y, z, w), NegativeOne, One); 81 | vector = Vector128.Multiply(vector, ShortMax); 82 | vector = Round(vector); 83 | 84 | X = (short)vector.GetX(); 85 | Y = (short)vector.GetY(); 86 | Z = (short)vector.GetZ(); 87 | W = (short)vector.GetW(); 88 | } 89 | 90 | /// 91 | /// Initializes a new instance of the struct. 92 | /// 93 | /// The containing X, Y, Z and W value. 94 | public Short4Normalized(in Vector4 vector) 95 | : this(vector.X, vector.Y, vector.Z, vector.W) 96 | { 97 | } 98 | 99 | /// 100 | /// Constructs a vector from the given . The span must contain at least 3 elements. 101 | /// 102 | /// The span of elements to assign to the vector. 103 | public Short4Normalized(ReadOnlySpan values) 104 | { 105 | Vector128 vector = Clamp(Vector128.Create(values), NegativeOne, One); 106 | vector = Vector128.Multiply(vector, ShortMax); 107 | vector = Round(vector); 108 | 109 | X = (short)vector.GetX(); 110 | Y = (short)vector.GetY(); 111 | Z = (short)vector.GetZ(); 112 | W = (short)vector.GetW(); 113 | } 114 | 115 | /// 116 | /// Gets the packed value. 117 | /// 118 | public ulong PackedValue => _packedValue; 119 | 120 | /// 121 | /// Expands the packed representation to a . 122 | /// 123 | public Vector4 ToVector4() => new( 124 | (X == -32768) ? -1.0f : X * (1.0f / 32767.0f), 125 | (Y == -32768) ? -1.0f : Y * (1.0f / 32767.0f), 126 | (Z == -32768) ? -1.0f : Z * (1.0f / 32767.0f), 127 | (W == -32768) ? -1.0f : W * (1.0f / 32767.0f) 128 | ); 129 | 130 | /// 131 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is Short4Normalized other && Equals(other); 132 | 133 | /// 134 | public bool Equals(Short4Normalized other) => PackedValue.Equals(other.PackedValue); 135 | 136 | /// 137 | /// Compares two objects for equality. 138 | /// 139 | /// The on the left hand of the operand. 140 | /// The on the right hand of the operand. 141 | /// 142 | /// True if the current left is equal to the parameter; otherwise, false. 143 | /// 144 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 145 | public static bool operator ==(Short4Normalized left, Short4Normalized right) => left.Equals(right); 146 | 147 | /// 148 | /// Compares two objects for inequality. 149 | /// 150 | /// The on the left hand of the operand. 151 | /// The on the right hand of the operand. 152 | /// 153 | /// True if the current left is unequal to the parameter; otherwise, false. 154 | /// 155 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 156 | public static bool operator !=(Short4Normalized left, Short4Normalized right) => !left.Equals(right); 157 | 158 | /// 159 | public override int GetHashCode() => PackedValue.GetHashCode(); 160 | 161 | /// 162 | public override string ToString() => PackedValue.ToString("X16", CultureInfo.InvariantCulture); 163 | } 164 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/UByte2.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Globalization; 6 | using System.Numerics; 7 | using System.Runtime.CompilerServices; 8 | using System.Runtime.InteropServices; 9 | using System.Runtime.Intrinsics; 10 | using static Vortice.Mathematics.VectorUtilities; 11 | 12 | namespace Vortice.Mathematics.PackedVector; 13 | 14 | /// 15 | /// Packed vector type containing two 8 bit unsigned integer components. 16 | /// 17 | /// Equivalent of XMUBYTE2. 18 | [StructLayout(LayoutKind.Explicit)] 19 | public readonly struct UByte2 : IPackedVector, IEquatable 20 | { 21 | [FieldOffset(0)] 22 | private readonly ushort _packedValue; 23 | 24 | /// 25 | /// The X component of the vector. 26 | /// 27 | [FieldOffset(0)] 28 | public readonly byte X; 29 | 30 | /// 31 | /// The Y component of the vector. 32 | /// 33 | [FieldOffset(1)] 34 | public readonly byte Y; 35 | 36 | /// 37 | /// Initializes a new instance of the struct. 38 | /// 39 | /// The packed value to assign. 40 | public UByte2(ushort packedValue) 41 | { 42 | _packedValue = packedValue; 43 | } 44 | 45 | /// 46 | /// Initializes a new instance of the struct. 47 | /// 48 | /// The x value. 49 | /// The y value. 50 | public UByte2(byte x, byte y) 51 | { 52 | X = x; 53 | Y = y; 54 | } 55 | 56 | /// 57 | /// Initializes a new instance of the struct. 58 | /// 59 | /// The x value. 60 | /// The y value. 61 | public UByte2(float x, float y) 62 | { 63 | Vector128 vector = Clamp(Vector128.Create(x, y, 0.0f, 0.0f), Vector128.Zero, UByteMax); 64 | vector = Round(vector); 65 | 66 | X = (byte)vector.GetX(); 67 | Y = (byte)vector.GetY(); 68 | } 69 | 70 | /// 71 | /// Initializes a new instance of the struct. 72 | /// 73 | /// The containing X and Y value. 74 | public UByte2(Vector2 vector) 75 | : this(vector.X, vector.Y) 76 | { 77 | } 78 | 79 | /// 80 | /// Initializes a new instance of the struct. 81 | /// 82 | /// The containing X and Y value. 83 | public UByte2(in Vector4 vector) 84 | : this(vector.X, vector.Y) 85 | { 86 | } 87 | 88 | /// 89 | /// Gets the packed value. 90 | /// 91 | public ushort PackedValue => _packedValue; 92 | 93 | /// 94 | /// Expands the packed representation to a . 95 | /// 96 | public Vector2 ToVector2() => new(X, Y); 97 | 98 | Vector4 IPackedVector.ToVector4() 99 | { 100 | Vector2 vector = ToVector2(); 101 | return new Vector4(vector.X, vector.Y, 0.0f, 1.0f); 102 | } 103 | 104 | /// 105 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is UByte2 other && Equals(other); 106 | 107 | /// 108 | public bool Equals(UByte2 other) => PackedValue.Equals(other.PackedValue); 109 | 110 | /// 111 | /// Compares two objects for equality. 112 | /// 113 | /// The on the left hand of the operand. 114 | /// The on the right hand of the operand. 115 | /// 116 | /// True if the current left is equal to the parameter; otherwise, false. 117 | /// 118 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 119 | public static bool operator ==(UByte2 left, UByte2 right) => left.Equals(right); 120 | 121 | /// 122 | /// Compares two objects for inequality. 123 | /// 124 | /// The on the left hand of the operand. 125 | /// The on the right hand of the operand. 126 | /// 127 | /// True if the current left is unequal to the parameter; otherwise, false. 128 | /// 129 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 130 | public static bool operator !=(UByte2 left, UByte2 right) => !left.Equals(right); 131 | 132 | /// 133 | public override int GetHashCode() => PackedValue.GetHashCode(); 134 | 135 | /// 136 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 137 | } 138 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/UByte2Normalized.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Globalization; 6 | using System.Numerics; 7 | using System.Runtime.CompilerServices; 8 | using System.Runtime.InteropServices; 9 | using System.Runtime.Intrinsics; 10 | using static Vortice.Mathematics.VectorUtilities; 11 | 12 | namespace Vortice.Mathematics.PackedVector; 13 | 14 | /// 15 | /// Packed vector type containing two 8 bit unsigned normalized integer components. 16 | /// 17 | /// Equivalent of XMUBYTEN2. 18 | [StructLayout(LayoutKind.Explicit)] 19 | public readonly struct UByte2Normalized : IPackedVector, IEquatable 20 | { 21 | [FieldOffset(0)] 22 | private readonly ushort _packedValue; 23 | 24 | /// 25 | /// The X component of the vector. 26 | /// 27 | [FieldOffset(0)] 28 | public readonly byte X; 29 | 30 | /// 31 | /// The Y component of the vector. 32 | /// 33 | [FieldOffset(1)] 34 | public readonly byte Y; 35 | 36 | /// 37 | /// Initializes a new instance of the struct. 38 | /// 39 | /// The packed value to assign. 40 | public UByte2Normalized(ushort packedValue) 41 | { 42 | _packedValue = packedValue; 43 | } 44 | 45 | /// 46 | /// Initializes a new instance of the struct. 47 | /// 48 | /// The x value. 49 | /// The y value. 50 | public UByte2Normalized(byte x, byte y) 51 | { 52 | X = x; 53 | Y = y; 54 | } 55 | 56 | /// 57 | /// Initializes a new instance of the struct. 58 | /// 59 | /// The x value. 60 | /// The y value. 61 | public UByte2Normalized(float x, float y) 62 | { 63 | Vector128 vector = Saturate(Vector128.Create(x, y, 0.0f, 0.0f)); 64 | vector = MultiplyAdd(vector, UByteMax, OneHalf); 65 | vector = Truncate(vector); 66 | 67 | X = (byte)vector.GetX(); 68 | Y = (byte)vector.GetY(); 69 | } 70 | 71 | /// 72 | /// Initializes a new instance of the struct. 73 | /// 74 | /// The containing X and Y value. 75 | public UByte2Normalized(in Vector2 vector) 76 | : this(vector.X, vector.Y) 77 | { 78 | } 79 | 80 | /// 81 | /// Initializes a new instance of the struct. 82 | /// 83 | /// The containing X and Y value. 84 | public UByte2Normalized(in Vector4 vector) 85 | : this(vector.X, vector.Y) 86 | { 87 | } 88 | 89 | /// 90 | /// Gets the packed value. 91 | /// 92 | public ushort PackedValue => _packedValue; 93 | 94 | /// 95 | /// Expands the packed representation to a . 96 | /// 97 | public Vector2 ToVector2() => new(X * (1.0f / 255.0f), Y * (1.0f / 255.0f)); 98 | 99 | Vector4 IPackedVector.ToVector4() 100 | { 101 | Vector2 vector = ToVector2(); 102 | return new Vector4(vector.X, vector.Y, 0.0f, 1.0f); 103 | } 104 | 105 | /// 106 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is UByte2Normalized other && Equals(other); 107 | 108 | /// 109 | public bool Equals(UByte2Normalized other) => PackedValue.Equals(other.PackedValue); 110 | 111 | /// 112 | /// Compares two objects for equality. 113 | /// 114 | /// The on the left hand of the operand. 115 | /// The on the right hand of the operand. 116 | /// 117 | /// True if the current left is equal to the parameter; otherwise, false. 118 | /// 119 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 120 | public static bool operator ==(UByte2Normalized left, UByte2Normalized right) => left.Equals(right); 121 | 122 | /// 123 | /// Compares two objects for inequality. 124 | /// 125 | /// The on the left hand of the operand. 126 | /// The on the right hand of the operand. 127 | /// 128 | /// True if the current left is unequal to the parameter; otherwise, false. 129 | /// 130 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 131 | public static bool operator !=(UByte2Normalized left, UByte2Normalized right) => !left.Equals(right); 132 | 133 | /// 134 | public override int GetHashCode() => PackedValue.GetHashCode(); 135 | 136 | /// 137 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 138 | } 139 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/UByte4.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Globalization; 6 | using System.Numerics; 7 | using System.Runtime.CompilerServices; 8 | using System.Runtime.InteropServices; 9 | using System.Runtime.Intrinsics; 10 | using static Vortice.Mathematics.VectorUtilities; 11 | 12 | namespace Vortice.Mathematics.PackedVector; 13 | 14 | /// 15 | /// Packed vector type containing four 8 bit unsigned integer components. 16 | /// 17 | /// Equivalent of XMUBYTE4. 18 | [StructLayout(LayoutKind.Explicit)] 19 | public readonly struct UByte4 : IPackedVector, IEquatable 20 | { 21 | [FieldOffset(0)] 22 | private readonly uint _packedValue; 23 | 24 | /// 25 | /// The X component of the vector. 26 | /// 27 | [FieldOffset(0)] 28 | public readonly byte X; 29 | 30 | /// 31 | /// The Y component of the vector. 32 | /// 33 | [FieldOffset(1)] 34 | public readonly byte Y; 35 | 36 | /// 37 | /// The Z component of the vector. 38 | /// 39 | [FieldOffset(2)] 40 | public readonly byte Z; 41 | 42 | /// 43 | /// The W component of the vector. 44 | /// 45 | [FieldOffset(3)] 46 | public readonly byte W; 47 | 48 | /// 49 | /// Initializes a new instance of the struct. 50 | /// 51 | /// The packed value to assign. 52 | public UByte4(uint packedValue) 53 | { 54 | _packedValue = packedValue; 55 | } 56 | 57 | /// 58 | /// Initializes a new instance of the struct. 59 | /// 60 | /// The x value. 61 | /// The y value. 62 | /// The z value. 63 | /// The w value. 64 | public UByte4(byte x, byte y, byte z, byte w) 65 | { 66 | X = x; 67 | Y = y; 68 | Z = z; 69 | W = w; 70 | } 71 | 72 | /// 73 | /// Initializes a new instance of the struct. 74 | /// 75 | /// The x value. 76 | /// The y value. 77 | /// The z value. 78 | /// The w value. 79 | public UByte4(float x, float y, float z, float w) 80 | { 81 | Vector128 result = Clamp(Vector128.Create(x, y, z, w), Vector128.Zero, UByteMax); 82 | result = Round(result); 83 | 84 | X = (byte)result.GetX(); 85 | Y = (byte)result.GetY(); 86 | Z = (byte)result.GetZ(); 87 | W = (byte)result.GetW(); 88 | } 89 | 90 | /// 91 | /// Initializes a new instance of the struct. 92 | /// 93 | /// The containing X and Y value. 94 | public UByte4(in Vector4 vector) 95 | : this(vector.X, vector.Y, vector.Z, vector.W) 96 | { 97 | 98 | } 99 | 100 | /// 101 | /// Constructs a vector from the given . The span must contain at least 3 elements. 102 | /// 103 | /// The span of elements to assign to the vector. 104 | public UByte4(ReadOnlySpan values) 105 | { 106 | Vector128 result = Clamp(Vector128.Create(values), Vector128.Zero, UByteMax); 107 | result = Round(result); 108 | 109 | X = (byte)result.GetX(); 110 | Y = (byte)result.GetY(); 111 | Z = (byte)result.GetZ(); 112 | W = (byte)result.GetW(); 113 | } 114 | 115 | /// 116 | /// Gets the packed value. 117 | /// 118 | public uint PackedValue => _packedValue; 119 | 120 | /// 121 | /// Expands the packed representation to a . 122 | /// 123 | public Vector4 ToVector4() 124 | { 125 | return new(X, Y, Z, W); 126 | } 127 | 128 | /// 129 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is UByte4 other && Equals(other); 130 | 131 | /// 132 | public bool Equals(UByte4 other) => PackedValue.Equals(other.PackedValue); 133 | 134 | /// 135 | /// Compares two objects for equality. 136 | /// 137 | /// The on the left hand of the operand. 138 | /// The on the right hand of the operand. 139 | /// 140 | /// True if the current left is equal to the parameter; otherwise, false. 141 | /// 142 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 143 | public static bool operator ==(UByte4 left, UByte4 right) => left.Equals(right); 144 | 145 | /// 146 | /// Compares two objects for inequality. 147 | /// 148 | /// The on the left hand of the operand. 149 | /// The on the right hand of the operand. 150 | /// 151 | /// True if the current left is unequal to the parameter; otherwise, false. 152 | /// 153 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 154 | public static bool operator !=(UByte4 left, UByte4 right) => !left.Equals(right); 155 | 156 | /// 157 | public override int GetHashCode() => PackedValue.GetHashCode(); 158 | 159 | /// 160 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 161 | } 162 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/UByte4Normalized.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Globalization; 5 | using System.Numerics; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using System.Runtime.Intrinsics; 9 | using static Vortice.Mathematics.VectorUtilities; 10 | 11 | namespace Vortice.Mathematics.PackedVector; 12 | 13 | /// 14 | /// Packed vector type containing four 8 bit unsigned normalized integer components. 15 | /// 16 | /// Equivalent of XMUBYTEN4. 17 | [StructLayout(LayoutKind.Explicit)] 18 | public readonly struct UByte4Normalized : IPackedVector, IEquatable 19 | { 20 | [FieldOffset(0)] 21 | private readonly uint _packedValue; 22 | 23 | /// 24 | /// The X component of the vector. 25 | /// 26 | [FieldOffset(0)] 27 | public readonly byte X; 28 | 29 | /// 30 | /// The Y component of the vector. 31 | /// 32 | [FieldOffset(1)] 33 | public readonly byte Y; 34 | 35 | /// 36 | /// The Z component of the vector. 37 | /// 38 | [FieldOffset(2)] 39 | public readonly byte Z; 40 | 41 | /// 42 | /// The W component of the vector. 43 | /// 44 | [FieldOffset(3)] 45 | public readonly byte W; 46 | 47 | /// 48 | /// Initializes a new instance of the struct. 49 | /// 50 | /// The packed value to assign. 51 | public UByte4Normalized(uint packedValue) 52 | { 53 | _packedValue = packedValue; 54 | } 55 | 56 | /// 57 | /// Initializes a new instance of the struct. 58 | /// 59 | /// The x value. 60 | /// The y value. 61 | /// The z value. 62 | /// The w value. 63 | public UByte4Normalized(byte x, byte y, byte z, byte w) 64 | { 65 | X = x; 66 | Y = y; 67 | Z = z; 68 | W = w; 69 | } 70 | 71 | /// 72 | /// Initializes a new instance of the struct. 73 | /// 74 | /// The x value. 75 | /// The y value. 76 | /// The z value. 77 | /// The w value. 78 | public UByte4Normalized(float x, float y, float z, float w) 79 | { 80 | Vector128 result = Saturate(Vector128.Create(x, y, z, w)); 81 | result = Vector128.Multiply(result, UByteMax); 82 | result = Truncate(result); 83 | 84 | X = (byte)result.GetX(); 85 | Y = (byte)result.GetY(); 86 | Z = (byte)result.GetZ(); 87 | W = (byte)result.GetW(); 88 | } 89 | 90 | /// 91 | /// Initializes a new instance of the struct. 92 | /// 93 | /// The containing X and Y value. 94 | public UByte4Normalized(in Vector4 vector) 95 | : this(vector.X, vector.Y, vector.Z, vector.W) 96 | { 97 | 98 | } 99 | 100 | /// Constructs a vector from the given . The span must contain at least 3 elements. 101 | /// The span of elements to assign to the vector. 102 | public UByte4Normalized(ReadOnlySpan values) 103 | { 104 | if (values.Length < 4) 105 | { 106 | throw new ArgumentOutOfRangeException(nameof(values)); 107 | } 108 | 109 | 110 | Vector128 result = Saturate(Vector128.Create(values)); 111 | result = Vector128.Multiply(result, UByteMax); 112 | result = Truncate(result); 113 | 114 | X = (byte)result.GetX(); 115 | Y = (byte)result.GetY(); 116 | Z = (byte)result.GetZ(); 117 | W = (byte)result.GetW(); 118 | } 119 | 120 | /// 121 | /// Gets the packed value. 122 | /// 123 | public uint PackedValue => _packedValue; 124 | 125 | /// 126 | /// Expands the packed representation to a . 127 | /// 128 | public Vector4 ToVector4() 129 | { 130 | return new(X / 255.0f, Y / 255.0f, Z / 255.0f, W / 255.0f); 131 | } 132 | 133 | /// 134 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is UByte4Normalized other && Equals(other); 135 | 136 | /// 137 | public bool Equals(UByte4Normalized other) => PackedValue.Equals(other.PackedValue); 138 | 139 | /// 140 | /// Compares two objects for equality. 141 | /// 142 | /// The on the left hand of the operand. 143 | /// The on the right hand of the operand. 144 | /// 145 | /// True if the current left is equal to the parameter; otherwise, false. 146 | /// 147 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 148 | public static bool operator ==(UByte4Normalized left, UByte4Normalized right) => left.Equals(right); 149 | 150 | /// 151 | /// Compares two objects for inequality. 152 | /// 153 | /// The on the left hand of the operand. 154 | /// The on the right hand of the operand. 155 | /// 156 | /// True if the current left is unequal to the parameter; otherwise, false. 157 | /// 158 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 159 | public static bool operator !=(UByte4Normalized left, UByte4Normalized right) => !left.Equals(right); 160 | 161 | /// 162 | public override int GetHashCode() => PackedValue.GetHashCode(); 163 | 164 | /// 165 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 166 | } 167 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/UShort2.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Globalization; 6 | using System.Numerics; 7 | using System.Runtime.CompilerServices; 8 | using System.Runtime.InteropServices; 9 | using System.Runtime.Intrinsics; 10 | using static Vortice.Mathematics.VectorUtilities; 11 | 12 | namespace Vortice.Mathematics.PackedVector; 13 | 14 | /// 15 | /// Packed vector type containing two 16-bit unsigned integer components. 16 | /// 17 | /// Equivalent of XMUSHORT2. 18 | [StructLayout(LayoutKind.Explicit)] 19 | public readonly struct UShort2 : IPackedVector, IEquatable 20 | { 21 | [FieldOffset(0)] 22 | private readonly uint _packedValue; 23 | 24 | /// 25 | /// The X component of the vector. 26 | /// 27 | [FieldOffset(0)] 28 | public readonly ushort X; 29 | 30 | /// 31 | /// The Y component of the vector. 32 | /// 33 | [FieldOffset(2)] 34 | public readonly ushort Y; 35 | 36 | /// 37 | /// Initializes a new instance of the struct. 38 | /// 39 | /// The packed value to assign. 40 | public UShort2(uint packedValue) 41 | { 42 | _packedValue = packedValue; 43 | } 44 | 45 | /// 46 | /// Initializes a new instance of the struct. 47 | /// 48 | /// The x value. 49 | /// The y value. 50 | public UShort2(ushort x, ushort y) 51 | { 52 | X = x; 53 | Y = y; 54 | } 55 | 56 | /// 57 | /// Initializes a new instance of the struct. 58 | /// 59 | /// The x value. 60 | /// The y value. 61 | public UShort2(float x, float y) 62 | { 63 | Vector128 vector = Clamp(Vector128.Create(x, y, 0.0f, 0.0f), Vector128.Zero, UShortMax); 64 | vector = Round(vector); 65 | 66 | X = (ushort)vector.GetX(); 67 | Y = (ushort)vector.GetY(); 68 | } 69 | 70 | /// 71 | /// Initializes a new instance of the struct. 72 | /// 73 | /// The containing X and Y value. 74 | public UShort2(in Vector2 vector) 75 | : this(vector.X, vector.Y) 76 | { 77 | } 78 | 79 | /// 80 | /// Initializes a new instance of the struct. 81 | /// 82 | /// The containing X and Y value. 83 | public UShort2(in Vector4 vector) 84 | : this(vector.X, vector.Y) 85 | { 86 | } 87 | 88 | /// 89 | /// Gets the packed value. 90 | /// 91 | public uint PackedValue => _packedValue; 92 | 93 | /// 94 | /// Expands the packed representation to a . 95 | /// 96 | public Vector2 ToVector2() => new(X, Y); 97 | 98 | Vector4 IPackedVector.ToVector4() 99 | { 100 | Vector2 vector = ToVector2(); 101 | return new Vector4(vector.X, vector.Y, 0.0f, 1.0f); 102 | } 103 | 104 | /// 105 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is UShort2 other && Equals(other); 106 | 107 | /// 108 | public bool Equals(UShort2 other) => PackedValue.Equals(other.PackedValue); 109 | 110 | /// 111 | /// Compares two objects for equality. 112 | /// 113 | /// The on the left hand of the operand. 114 | /// The on the right hand of the operand. 115 | /// 116 | /// True if the current left is equal to the parameter; otherwise, false. 117 | /// 118 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 119 | public static bool operator ==(UShort2 left, UShort2 right) => left.Equals(right); 120 | 121 | /// 122 | /// Compares two objects for inequality. 123 | /// 124 | /// The on the left hand of the operand. 125 | /// The on the right hand of the operand. 126 | /// 127 | /// True if the current left is unequal to the parameter; otherwise, false. 128 | /// 129 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 130 | public static bool operator !=(UShort2 left, UShort2 right) => !left.Equals(right); 131 | 132 | /// 133 | public override int GetHashCode() => PackedValue.GetHashCode(); 134 | 135 | /// 136 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 137 | } 138 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/UShort2Normalized.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Globalization; 6 | using System.Numerics; 7 | using System.Runtime.CompilerServices; 8 | using System.Runtime.InteropServices; 9 | using System.Runtime.Intrinsics; 10 | using static Vortice.Mathematics.VectorUtilities; 11 | 12 | namespace Vortice.Mathematics.PackedVector; 13 | 14 | /// 15 | /// Packed vector type containing two 16-bit unsigned normalized integer components. 16 | /// 17 | /// Equivalent of XMUSHORTN2. 18 | [StructLayout(LayoutKind.Explicit)] 19 | public readonly struct UShort2Normalized : IPackedVector, IEquatable 20 | { 21 | [FieldOffset(0)] 22 | private readonly uint _packedValue; 23 | 24 | /// 25 | /// The X component of the vector. 26 | /// 27 | [FieldOffset(0)] 28 | public readonly ushort X; 29 | 30 | /// 31 | /// The Y component of the vector. 32 | /// 33 | [FieldOffset(2)] 34 | public readonly ushort Y; 35 | 36 | /// 37 | /// Initializes a new instance of the struct. 38 | /// 39 | /// The packed value to assign. 40 | public UShort2Normalized(uint packedValue) 41 | { 42 | _packedValue = packedValue; 43 | } 44 | 45 | /// 46 | /// Initializes a new instance of the struct. 47 | /// 48 | /// The x value. 49 | /// The y value. 50 | public UShort2Normalized(ushort x, ushort y) 51 | { 52 | X = x; 53 | Y = y; 54 | } 55 | 56 | /// 57 | /// Initializes a new instance of the struct. 58 | /// 59 | /// The x value. 60 | /// The y value. 61 | public UShort2Normalized(float x, float y) 62 | { 63 | Vector128 vector = Saturate(Vector128.Create(x, y, 0.0f, 0.0f)); 64 | vector = MultiplyAdd(vector, UShortMax, OneHalf); 65 | vector = Truncate(vector); 66 | 67 | X = (ushort)vector.GetX(); 68 | Y = (ushort)vector.GetY(); 69 | } 70 | 71 | /// 72 | /// Initializes a new instance of the struct. 73 | /// 74 | /// The containing X and Y value. 75 | public UShort2Normalized(in Vector2 vector) 76 | : this(vector.X, vector.Y) 77 | { 78 | } 79 | 80 | /// 81 | /// Initializes a new instance of the struct. 82 | /// 83 | /// The containing X and Y value. 84 | public UShort2Normalized(in Vector4 vector) 85 | : this(vector.X, vector.Y) 86 | { 87 | } 88 | 89 | /// 90 | /// Gets the packed value. 91 | /// 92 | public uint PackedValue => _packedValue; 93 | 94 | /// 95 | /// Expands the packed representation to a . 96 | /// 97 | public Vector2 ToVector2() => new((float)X / 65535.0f, (float)Y / 65535.0f); 98 | 99 | Vector4 IPackedVector.ToVector4() 100 | { 101 | Vector2 vector = ToVector2(); 102 | return new Vector4(vector.X, vector.Y, 0.0f, 1.0f); 103 | } 104 | 105 | /// 106 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is UShort2Normalized other && Equals(other); 107 | 108 | /// 109 | public bool Equals(UShort2Normalized other) => PackedValue.Equals(other.PackedValue); 110 | 111 | /// 112 | /// Compares two objects for equality. 113 | /// 114 | /// The on the left hand of the operand. 115 | /// The on the right hand of the operand. 116 | /// 117 | /// True if the current left is equal to the parameter; otherwise, false. 118 | /// 119 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 120 | public static bool operator ==(UShort2Normalized left, UShort2Normalized right) => left.Equals(right); 121 | 122 | /// 123 | /// Compares two objects for inequality. 124 | /// 125 | /// The on the left hand of the operand. 126 | /// The on the right hand of the operand. 127 | /// 128 | /// True if the current left is unequal to the parameter; otherwise, false. 129 | /// 130 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 131 | public static bool operator !=(UShort2Normalized left, UShort2Normalized right) => !left.Equals(right); 132 | 133 | /// 134 | public override int GetHashCode() => PackedValue.GetHashCode(); 135 | 136 | /// 137 | public override string ToString() => PackedValue.ToString("X8", CultureInfo.InvariantCulture); 138 | } 139 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/UShort4.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Globalization; 5 | using System.Numerics; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using System.Runtime.Intrinsics; 9 | using static Vortice.Mathematics.VectorUtilities; 10 | 11 | namespace Vortice.Mathematics.PackedVector; 12 | 13 | /// 14 | /// Packed vector type containing four 16-bit unsigned integer components. 15 | /// 16 | /// Equivalent of XMUSHORT4. 17 | [StructLayout(LayoutKind.Explicit)] 18 | public readonly struct UShort4 : IPackedVector, IEquatable 19 | { 20 | [FieldOffset(0)] 21 | private readonly ulong _packedValue; 22 | 23 | /// 24 | /// The X component of the vector. 25 | /// 26 | [FieldOffset(0)] 27 | public readonly ushort X; 28 | 29 | /// 30 | /// The Y component of the vector. 31 | /// 32 | [FieldOffset(2)] 33 | public readonly ushort Y; 34 | 35 | /// 36 | /// The Z component of the vector. 37 | /// 38 | [FieldOffset(4)] 39 | public readonly ushort Z; 40 | 41 | /// 42 | /// The W component of the vector. 43 | /// 44 | [FieldOffset(6)] 45 | public readonly ushort W; 46 | 47 | /// 48 | /// Initializes a new instance of the struct. 49 | /// 50 | /// The packed value to assign. 51 | public UShort4(ulong packedValue) 52 | { 53 | _packedValue = packedValue; 54 | } 55 | 56 | /// 57 | /// Initializes a new instance of the struct. 58 | /// 59 | /// The x value. 60 | /// The y value. 61 | /// The z value. 62 | /// The w value. 63 | public UShort4(ushort x, ushort y, ushort z, ushort w) 64 | { 65 | X = x; 66 | Y = y; 67 | Z = z; 68 | W = w; 69 | } 70 | 71 | /// 72 | /// Initializes a new instance of the struct. 73 | /// 74 | /// The x value. 75 | /// The y value. 76 | /// The z value. 77 | /// The w value. 78 | public UShort4(float x, float y, float z, float w) 79 | { 80 | Vector128 vector = Clamp(Vector128.Create(x, y, z, w), Vector128.Zero, UShortMax); 81 | vector = Round(vector); 82 | 83 | X = (ushort)vector.GetX(); 84 | Y = (ushort)vector.GetY(); 85 | Z = (ushort)vector.GetZ(); 86 | W = (ushort)vector.GetW(); 87 | } 88 | 89 | /// 90 | /// Initializes a new instance of the struct. 91 | /// 92 | /// The containing X, Y, Z and W value. 93 | public UShort4(in Vector4 vector) 94 | : this(vector.X, vector.Y, vector.Z, vector.W) 95 | { 96 | } 97 | 98 | /// 99 | /// Constructs a vector from the given . The span must contain at least 3 elements. 100 | /// 101 | /// The span of elements to assign to the vector. 102 | public UShort4(ReadOnlySpan values) 103 | { 104 | Vector128 vector = Clamp(Vector128.Create(values), Vector128.Zero, UShortMax); 105 | vector = Round(vector); 106 | 107 | X = (byte)vector.GetX(); 108 | Y = (byte)vector.GetY(); 109 | Z = (byte)vector.GetZ(); 110 | W = (byte)vector.GetW(); 111 | } 112 | 113 | /// 114 | /// Gets the packed value. 115 | /// 116 | public ulong PackedValue => _packedValue; 117 | 118 | /// 119 | /// Expands the packed representation to a . 120 | /// 121 | public Vector4 ToVector4() => new(X, Y, Z, W); 122 | 123 | /// 124 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is UShort4 other && Equals(other); 125 | 126 | /// 127 | public bool Equals(UShort4 other) => PackedValue.Equals(other.PackedValue); 128 | 129 | /// 130 | /// Compares two objects for equality. 131 | /// 132 | /// The on the left hand of the operand. 133 | /// The on the right hand of the operand. 134 | /// 135 | /// True if the current left is equal to the parameter; otherwise, false. 136 | /// 137 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 138 | public static bool operator ==(UShort4 left, UShort4 right) => left.Equals(right); 139 | 140 | /// 141 | /// Compares two objects for inequality. 142 | /// 143 | /// The on the left hand of the operand. 144 | /// The on the right hand of the operand. 145 | /// 146 | /// True if the current left is unequal to the parameter; otherwise, false. 147 | /// 148 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 149 | public static bool operator !=(UShort4 left, UShort4 right) => !left.Equals(right); 150 | 151 | /// 152 | public override int GetHashCode() => PackedValue.GetHashCode(); 153 | 154 | /// 155 | public override string ToString() => PackedValue.ToString("X16", CultureInfo.InvariantCulture); 156 | } 157 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PackedVector/UShort4Normalized.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Globalization; 5 | using System.Numerics; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using System.Runtime.Intrinsics; 9 | using static Vortice.Mathematics.VectorUtilities; 10 | 11 | namespace Vortice.Mathematics.PackedVector; 12 | 13 | /// 14 | /// Packed vector type containing four 16-bit unsigned normalized integer components. 15 | /// 16 | /// Equivalent of XMUSHORTN4. 17 | [StructLayout(LayoutKind.Explicit)] 18 | public readonly struct UShort4Normalized : IPackedVector, IEquatable 19 | { 20 | [FieldOffset(0)] 21 | private readonly ulong _packedValue; 22 | 23 | /// 24 | /// The X component of the vector. 25 | /// 26 | [FieldOffset(0)] 27 | public readonly ushort X; 28 | 29 | /// 30 | /// The Y component of the vector. 31 | /// 32 | [FieldOffset(2)] 33 | public readonly ushort Y; 34 | 35 | /// 36 | /// The Z component of the vector. 37 | /// 38 | [FieldOffset(4)] 39 | public readonly ushort Z; 40 | 41 | /// 42 | /// The W component of the vector. 43 | /// 44 | [FieldOffset(6)] 45 | public readonly ushort W; 46 | 47 | /// 48 | /// Initializes a new instance of the struct. 49 | /// 50 | /// The packed value to assign. 51 | public UShort4Normalized(ulong packedValue) 52 | { 53 | _packedValue = packedValue; 54 | } 55 | 56 | /// 57 | /// Initializes a new instance of the struct. 58 | /// 59 | /// The x value. 60 | /// The y value. 61 | /// The z value. 62 | /// The w value. 63 | public UShort4Normalized(ushort x, ushort y, ushort z, ushort w) 64 | { 65 | X = x; 66 | Y = y; 67 | Z = z; 68 | W = w; 69 | } 70 | 71 | /// 72 | /// Initializes a new instance of the struct. 73 | /// 74 | /// The x value. 75 | /// The y value. 76 | /// The z value. 77 | /// The w value. 78 | public UShort4Normalized(float x, float y, float z, float w) 79 | { 80 | Vector128 vector = Saturate(Vector128.Create(x, y, z, w)); 81 | vector = MultiplyAdd(vector, UShortMax, OneHalf); 82 | vector = Truncate(vector); 83 | 84 | X = (ushort)vector.GetX(); 85 | Y = (ushort)vector.GetY(); 86 | Z = (ushort)vector.GetZ(); 87 | W = (ushort)vector.GetW(); 88 | } 89 | 90 | /// 91 | /// Initializes a new instance of the struct. 92 | /// 93 | /// The containing X, Y, Z and W value. 94 | public UShort4Normalized(in Vector4 vector) 95 | : this(vector.X, vector.Y, vector.Z, vector.W) 96 | { 97 | } 98 | 99 | /// 100 | /// Constructs a vector from the given . The span must contain at least 3 elements. 101 | /// 102 | /// The span of elements to assign to the vector. 103 | public UShort4Normalized(ReadOnlySpan values) 104 | { 105 | Vector128 vector = Saturate(Vector128.Create(values)); 106 | vector = MultiplyAdd(vector, UShortMax, OneHalf); 107 | vector = Truncate(vector); 108 | 109 | X = (ushort)vector.GetX(); 110 | Y = (ushort)vector.GetY(); 111 | Z = (ushort)vector.GetZ(); 112 | W = (ushort)vector.GetW(); 113 | } 114 | 115 | /// 116 | /// Gets the packed value. 117 | /// 118 | public ulong PackedValue => _packedValue; 119 | 120 | /// 121 | /// Expands the packed representation to a . 122 | /// 123 | public Vector4 ToVector4() => new( 124 | X / 65535.0f, 125 | Y / 65535.0f, 126 | Z / 65535.0f, 127 | W / 65535.0f 128 | ); 129 | 130 | 131 | /// 132 | public override bool Equals([NotNullWhen(true)] object? obj) => obj is UShort4Normalized other && Equals(other); 133 | 134 | /// 135 | public bool Equals(UShort4Normalized other) => PackedValue.Equals(other.PackedValue); 136 | 137 | /// 138 | /// Compares two objects for equality. 139 | /// 140 | /// The on the left hand of the operand. 141 | /// The on the right hand of the operand. 142 | /// 143 | /// True if the current left is equal to the parameter; otherwise, false. 144 | /// 145 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 146 | public static bool operator ==(UShort4Normalized left, UShort4Normalized right) => left.Equals(right); 147 | 148 | /// 149 | /// Compares two objects for inequality. 150 | /// 151 | /// The on the left hand of the operand. 152 | /// The on the right hand of the operand. 153 | /// 154 | /// True if the current left is unequal to the parameter; otherwise, false. 155 | /// 156 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 157 | public static bool operator !=(UShort4Normalized left, UShort4Normalized right) => !left.Equals(right); 158 | 159 | /// 160 | public override int GetHashCode() => PackedValue.GetHashCode(); 161 | 162 | /// 163 | public override string ToString() => PackedValue.ToString("X16", CultureInfo.InvariantCulture); 164 | } 165 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/PlaneIntersectionType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Numerics; 5 | 6 | namespace Vortice.Mathematics; 7 | 8 | /// 9 | /// Defines the intersection between a and a bounding volume. 10 | /// 11 | public enum PlaneIntersectionType 12 | { 13 | /// 14 | /// There is no intersection, the bounding volume is in the negative half space of the plane. 15 | /// 16 | Front, 17 | /// 18 | /// There is no intersection, the bounding volume is in the positive half space of the plane. 19 | /// 20 | Back, 21 | /// 22 | /// The plane is intersected. 23 | /// 24 | Intersecting 25 | } 26 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [module: SkipLocalsInit] 4 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/Size3.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.ComponentModel; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace Vortice.Mathematics; 8 | 9 | /// 10 | /// Stores an ordered pair of integer numbers describing the width, height and depth of a rectangle. 11 | /// 12 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 13 | public record struct Size3 14 | { 15 | /// 16 | /// A with all of its components set to zero. 17 | /// 18 | public static Size3 Empty => default; 19 | 20 | /// 21 | /// A special valued . 22 | /// 23 | public static Size3 WholeSize => new(~0, ~0, ~0); 24 | 25 | /// 26 | /// The width component of the size. 27 | /// 28 | public int Width; 29 | 30 | /// 31 | /// The height component of the size. 32 | /// 33 | public int Height; 34 | 35 | /// 36 | /// The depth component of the size. 37 | /// 38 | public int Depth; 39 | 40 | /// 41 | /// Initializes a new instance of structure. 42 | /// 43 | /// The width component of the size. 44 | /// The height component of the size. 45 | /// The depth component of the size. 46 | public Size3(int width, int height, int depth) 47 | { 48 | Width = width; 49 | Height = height; 50 | Depth = depth; 51 | } 52 | 53 | /// 54 | /// Initializes a new instance of structure. 55 | /// 56 | /// The width and height component of the size. 57 | /// The depth component of the size. 58 | public Size3(in SizeI size, int depth) 59 | { 60 | Width = size.Width; 61 | Height = size.Height; 62 | Depth = depth; 63 | } 64 | 65 | /// 66 | /// Gets a value indicating whether this is empty. 67 | /// 68 | [EditorBrowsable(EditorBrowsableState.Never)] 69 | public readonly bool IsEmpty => this == Empty; 70 | 71 | /// 72 | /// Deconstructs this size into three integers. 73 | /// 74 | /// The out value for the width. 75 | /// The out value for the height. 76 | /// The out value for the depth. 77 | public readonly void Deconstruct(out int width, out int height, out int depth) 78 | { 79 | width = Width; 80 | height = Height; 81 | depth = Depth; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/UInt2.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Amer Koleci and contributors. 2 | // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. 3 | 4 | using System.Diagnostics; 5 | using System.Diagnostics.CodeAnalysis; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | 9 | namespace Vortice.Mathematics; 10 | 11 | /// 12 | /// Vector type containing two 32 bit unsigned integer components. 13 | /// 14 | [DebuggerDisplay("X={X}, Y={Y}")] 15 | public struct UInt2 : IEquatable, IFormattable 16 | { 17 | /// 18 | /// The X component of the vector. 19 | /// 20 | public uint X; 21 | 22 | /// 23 | /// The Y component of the vector. 24 | /// 25 | public uint Y; 26 | 27 | internal const int Count = 2; 28 | 29 | /// 30 | /// Initializes a new instance of the struct. 31 | /// 32 | /// The value that will be assigned to all components. 33 | public UInt2(uint value) : this(value, value) 34 | { 35 | } 36 | 37 | /// 38 | /// Initializes a new instance of the struct. 39 | /// 40 | /// Initial value for the X component of the vector. 41 | /// Initial value for the Y component of the vector. 42 | public UInt2(uint x, uint y) 43 | { 44 | X = x; 45 | Y = y; 46 | } 47 | 48 | /// 49 | /// Initializes a new instance of the struct. 50 | /// 51 | /// The span of elements to assign to the vector. 52 | public UInt2(ReadOnlySpan values) 53 | { 54 | if (values.Length < 2) 55 | { 56 | throw new ArgumentOutOfRangeException(nameof(values), "There must be 2 uint values."); 57 | } 58 | 59 | this = Unsafe.ReadUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(values))); 60 | } 61 | 62 | /// 63 | /// A with all of its components set to zero. 64 | /// 65 | public static UInt2 Zero 66 | { 67 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 68 | get => default; 69 | } 70 | 71 | /// 72 | /// The X unit (1, 0). 73 | /// 74 | public static UInt2 UnitX 75 | { 76 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 77 | get => new(1, 0); 78 | } 79 | 80 | /// 81 | /// The Y unit (0, 1, 0). 82 | /// 83 | public static UInt2 UnitY 84 | { 85 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 86 | get => new(0, 1); 87 | } 88 | 89 | /// 90 | /// A with all of its components set to one. 91 | /// 92 | public static UInt2 One 93 | { 94 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 95 | get => new(1, 1); 96 | } 97 | 98 | /// Gets or sets the element at the specified index. 99 | /// The index of the element to get or set. 100 | /// The the element at . 101 | /// was less than zero or greater than the number of elements. 102 | public uint this[int index] 103 | { 104 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 105 | readonly get => this.GetElement(index); 106 | 107 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 108 | set => this = this.WithElement(index, value); 109 | } 110 | 111 | public readonly void Deconstruct(out uint x, out uint y) 112 | { 113 | x = X; 114 | y = Y; 115 | } 116 | 117 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 118 | public readonly void CopyTo(uint[] array) 119 | { 120 | CopyTo(array, 0); 121 | } 122 | 123 | public readonly void CopyTo(uint[] array, int index) 124 | { 125 | if (array is null) 126 | { 127 | throw new NullReferenceException(nameof(array)); 128 | } 129 | 130 | if ((index < 0) || (index >= array.Length)) 131 | { 132 | throw new ArgumentOutOfRangeException(nameof(index)); 133 | } 134 | 135 | if ((array.Length - index) < 2) 136 | { 137 | throw new ArgumentOutOfRangeException(nameof(index)); 138 | } 139 | 140 | array[index] = X; 141 | array[index + 1] = Y; 142 | } 143 | 144 | /// Copies the vector to the given .The length of the destination span must be at least 2. 145 | /// The destination span which the values are copied into. 146 | /// If number of elements in source vector is greater than those available in destination span. 147 | public readonly void CopyTo(Span destination) 148 | { 149 | if (destination.Length < 2) 150 | { 151 | throw new ArgumentOutOfRangeException(nameof(destination)); 152 | } 153 | 154 | Unsafe.WriteUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(destination)), this); 155 | } 156 | 157 | /// Attempts to copy the vector to the given . The length of the destination span must be at least 2. 158 | /// The destination span which the values are copied into. 159 | /// if the source vector was successfully copied to . if is not large enough to hold the source vector. 160 | public readonly bool TryCopyTo(Span destination) 161 | { 162 | if (destination.Length < 2) 163 | { 164 | return false; 165 | } 166 | 167 | Unsafe.WriteUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(destination)), this); 168 | 169 | return true; 170 | } 171 | 172 | /// 173 | public override readonly bool Equals([NotNullWhen(true)] object? obj) => obj is UInt2 value && Equals(value); 174 | 175 | /// 176 | /// Determines whether the specified is equal to this instance. 177 | /// 178 | /// The to compare with this instance. 179 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 180 | public readonly bool Equals(UInt2 other) 181 | { 182 | return X == other.X 183 | && Y == other.Y; 184 | } 185 | 186 | /// 187 | /// Compares two objects for equality. 188 | /// 189 | /// The on the left hand of the operand. 190 | /// The on the right hand of the operand. 191 | /// 192 | /// True if the current left is equal to the parameter; otherwise, false. 193 | /// 194 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 195 | public static bool operator ==(UInt2 left, UInt2 right) => left.Equals(right); 196 | 197 | /// 198 | /// Compares two objects for inequality. 199 | /// 200 | /// The on the left hand of the operand. 201 | /// The on the right hand of the operand. 202 | /// 203 | /// True if the current left is unequal to the parameter; otherwise, false. 204 | /// 205 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 206 | public static bool operator !=(UInt2 left, UInt2 right) => !left.Equals(right); 207 | 208 | /// 209 | public override readonly int GetHashCode() => HashCode.Combine(X, Y); 210 | 211 | /// 212 | public override string ToString() => ToString(format: null, formatProvider: null); 213 | 214 | /// 215 | public readonly string ToString(string? format, IFormatProvider? formatProvider) 216 | => $"{nameof(UInt2)} {{ {nameof(X)} = {X.ToString(format, formatProvider)}, {nameof(Y)} = {Y.ToString(format, formatProvider)} }}"; 217 | } 218 | -------------------------------------------------------------------------------- /src/Vortice.Mathematics/Vortice.Mathematics.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0;net9.0 5 | $(TargetFrameworks);net8.0-windows10.0.19041;net9.0-windows10.0.19041 6 | High performance cross platform .NET math library 7 | README.md 8 | true 9 | 10 | 11 | 12 | 13 | 1.9.3 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | --------------------------------------------------------------------------------