├── .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 | [](https://github.com/amerkoleci/Vortice.Mathematics/blob/master/LICENSE)
4 | [](https://github.com/amerkoleci/Vortice.Mathematics/actions)
5 | [](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 |
--------------------------------------------------------------------------------