-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Add left-handed spherical and cylindrical billboards #109605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
d1e9328
d972c39
a4a2f29
0674250
7ba1f60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| namespace System.Numerics.Tests | ||
| { | ||
| public class Matrix4x4LeftHandChangedBasisTests : Matrix4x4RightHandTests | ||
| { | ||
| protected override string CreateLookAtMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateLookAtLeftHanded)}"; | ||
| protected override Matrix4x4 CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector) | ||
| { | ||
| return LeftHandToRightHand * Matrix4x4.CreateLookAtLeftHanded( | ||
| ChangeRightHandToLeftHand(cameraPosition), | ||
| ChangeRightHandToLeftHand(cameraTarget), | ||
| ChangeRightHandToLeftHand(cameraUpVector)) * RightHandToLeftHand; | ||
| } | ||
|
|
||
| protected override string CreateLookToMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateLookToLeftHanded)}"; | ||
| protected override Matrix4x4 CreateLookTo(Vector3 cameraPosition, Vector3 cameraDirection, Vector3 cameraUpVector) | ||
| { | ||
| return LeftHandToRightHand * Matrix4x4.CreateLookToLeftHanded( | ||
| ChangeRightHandToLeftHand(cameraPosition), | ||
| ChangeRightHandToLeftHand(cameraDirection), | ||
| ChangeRightHandToLeftHand(cameraUpVector)) * RightHandToLeftHand; | ||
| } | ||
|
|
||
| protected override string CreateViewportMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateViewportLeftHanded)}"; | ||
| protected override Matrix4x4 CreateViewport(float x, float y, float width, float height, float minDepth, float maxDepth) | ||
| { | ||
| return LeftHandToRightHand * Matrix4x4.CreateViewportLeftHanded(x, y, width, height, -minDepth, -maxDepth) * RightHandToLeftHand; | ||
| } | ||
|
|
||
| protected override string CreateBillboardMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateBillboardLeftHanded)}"; | ||
| protected override Matrix4x4 CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector) | ||
| { | ||
| return LeftHandToRightHand * Matrix4x4.CreateBillboardLeftHanded( | ||
| ChangeRightHandToLeftHand(objectPosition), | ||
| ChangeRightHandToLeftHand(cameraPosition), | ||
| ChangeRightHandToLeftHand(cameraUpVector), | ||
| ChangeRightHandToLeftHand(cameraForwardVector)) * RightHandToLeftHand; | ||
| } | ||
|
|
||
| protected override string CreateConstrainedBillboardMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateConstrainedBillboardLeftHanded)}"; | ||
| protected override Matrix4x4 CreateConstrainedBillboard( | ||
| Vector3 objectPosition, | ||
| Vector3 cameraPosition, | ||
| Vector3 rotateAxis, | ||
| Vector3 cameraForwardVector, | ||
| Vector3 objectForwardVector) | ||
| { | ||
| return LeftHandToRightHand * Matrix4x4.CreateConstrainedBillboardLeftHanded( | ||
| ChangeRightHandToLeftHand(objectPosition), | ||
| ChangeRightHandToLeftHand(cameraPosition), | ||
| ChangeRightHandToLeftHand(rotateAxis), | ||
| ChangeRightHandToLeftHand(cameraForwardVector), | ||
| ChangeRightHandToLeftHand(objectForwardVector)) * RightHandToLeftHand; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using Xunit; | ||
|
|
||
| namespace System.Numerics.Tests | ||
| { | ||
| public class Matrix4x4LeftHandTests : Matrix4x4OrientationAwareTests | ||
| { | ||
| [Fact] | ||
| public void Matrix4x4CreateLookAtLeftHandedTest() | ||
| { | ||
| Vector3 cameraPosition = new Vector3(10.0f, 20.0f, 30.0f); | ||
| Vector3 cameraTarget = new Vector3(3.0f, 2.0f, -4.0f); | ||
| Vector3 cameraUpVector = new Vector3(0.0f, 1.0f, 0.0f); | ||
|
|
||
| Matrix4x4 expected = new Matrix4x4(); | ||
| expected.M11 = -0.979457f; | ||
| expected.M12 = -0.0928268f; | ||
| expected.M13 = -0.179017f; | ||
|
|
||
| expected.M21 = +0.0f; | ||
| expected.M22 = +0.887748f; | ||
| expected.M23 = -0.460329f; | ||
|
|
||
| expected.M31 = +0.201653f; | ||
| expected.M32 = -0.450873f; | ||
| expected.M33 = -0.869511f; | ||
|
|
||
| expected.M41 = +3.74498f; | ||
| expected.M42 = -3.30051f; | ||
| expected.M43 = +37.0821f; | ||
| expected.M44 = +1.0f; | ||
|
|
||
| Matrix4x4 actual = CreateLookAt(cameraPosition, cameraTarget, cameraUpVector); | ||
| Assert.True(MathHelper.Equal(expected, actual), $"{CreateLookAtMethodName} did not return the expected value."); | ||
|
||
| } | ||
|
|
||
| [Fact] | ||
| public void Matrix4x4CreateLookToLeftHandedTest() | ||
| { | ||
| Vector3 cameraPosition = new Vector3(10.0f, 20.0f, 30.0f); | ||
| Vector3 cameraDirection = new Vector3(-7.0f, -18.0f, -34.0f); | ||
| Vector3 cameraUpVector = new Vector3(0.0f, 1.0f, 0.0f); | ||
|
|
||
| Matrix4x4 expected = new Matrix4x4(); | ||
| expected.M11 = -0.979457f; | ||
| expected.M12 = -0.0928268f; | ||
| expected.M13 = -0.179017f; | ||
|
|
||
| expected.M21 = +0.0f; | ||
| expected.M22 = +0.887748f; | ||
| expected.M23 = -0.460329f; | ||
|
|
||
| expected.M31 = +0.201653f; | ||
| expected.M32 = -0.450873f; | ||
| expected.M33 = -0.869511f; | ||
|
|
||
| expected.M41 = +3.74498f; | ||
| expected.M42 = -3.30051f; | ||
| expected.M43 = +37.0821f; | ||
| expected.M44 = +1.0f; | ||
|
|
||
| Matrix4x4 actual = CreateLookTo(cameraPosition, cameraDirection, cameraUpVector); | ||
| Assert.True(MathHelper.Equal(expected, actual), $"{CreateLookToMethodName} did not return the expected value."); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Matrix4x4CreateViewportLeftHandedTest() | ||
| { | ||
| float x = 10.0f, y = 20.0f; | ||
| float width = 3.0f, height = 4.0f; | ||
| float minDepth = 100.0f, maxDepth = 200.0f; | ||
|
|
||
| Matrix4x4 expected = Matrix4x4.Identity; | ||
| expected.M11 = width * 0.5f; | ||
| expected.M22 = -height * 0.5f; | ||
| expected.M33 = maxDepth - minDepth; | ||
| expected.M41 = x + expected.M11; | ||
| expected.M42 = y - expected.M22; | ||
| expected.M43 = minDepth; | ||
|
|
||
| Matrix4x4 actual = CreateViewport(x, y, width, height, minDepth, maxDepth); | ||
| Assert.True(MathHelper.Equal(expected, actual), $"{CreateViewportMethodName} did not return the expected value."); | ||
| } | ||
|
|
||
| protected override string CreateLookAtMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateLookAtLeftHanded)}"; | ||
| protected override Matrix4x4 CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector) | ||
| => Matrix4x4.CreateLookAtLeftHanded(cameraPosition, cameraTarget, cameraUpVector); | ||
|
|
||
| protected override string CreateLookToMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateLookToLeftHanded)}"; | ||
| protected override Matrix4x4 CreateLookTo(Vector3 cameraPosition, Vector3 cameraDirection, Vector3 cameraUpVector) | ||
| => Matrix4x4.CreateLookToLeftHanded(cameraPosition, cameraDirection, cameraUpVector); | ||
|
|
||
| protected override string CreateViewportMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateViewportLeftHanded)}"; | ||
| protected override Matrix4x4 CreateViewport(float x, float y, float width, float height, float minDepth, float maxDepth) | ||
| => Matrix4x4.CreateViewportLeftHanded(x, y, width, height, minDepth, maxDepth); | ||
|
|
||
| protected override string CreateBillboardMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateBillboardLeftHanded)}"; | ||
| protected override Matrix4x4 CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector) | ||
| => Matrix4x4.CreateBillboardLeftHanded(objectPosition, cameraPosition, cameraUpVector, cameraForwardVector); | ||
|
|
||
| protected override string CreateConstrainedBillboardMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateConstrainedBillboardLeftHanded)}"; | ||
|
|
||
| protected override Matrix4x4 CreateConstrainedBillboard( | ||
| Vector3 objectPosition, | ||
| Vector3 cameraPosition, | ||
| Vector3 rotateAxis, | ||
| Vector3 cameraForwardVector, | ||
| Vector3 objectForwardVector) | ||
| => Matrix4x4.CreateConstrainedBillboardLeftHanded(objectPosition, cameraPosition, rotateAxis, cameraForwardVector, objectForwardVector); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| namespace System.Numerics.Tests | ||
| { | ||
| public abstract class Matrix4x4OrientationAwareTests | ||
| { | ||
| protected static Matrix4x4 RightHandToLeftHand = | ||
PranavSenthilnathan marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| new(1, 0, 0, 0, | ||
| 0, 1, 0, 0, | ||
| 0, 0, -1, 0, | ||
| 0, 0, 0, 1); | ||
|
|
||
| // The basis change is a self-inverse | ||
| protected static Matrix4x4 LeftHandToRightHand = RightHandToLeftHand; | ||
|
|
||
| protected static Vector3 ChangeRightHandToLeftHand(Vector3 v) => new(v.X, v.Y, -v.Z); | ||
| protected static Vector3 ChangeLeftHandToRightHand(Vector3 v) => new(v.X, v.Y, -v.Z); | ||
|
|
||
| protected abstract string CreateLookAtMethodName { get; } | ||
| protected abstract Matrix4x4 CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector); | ||
|
|
||
| protected abstract string CreateLookToMethodName { get; } | ||
| protected abstract Matrix4x4 CreateLookTo(Vector3 cameraPosition, Vector3 cameraDirection, Vector3 cameraUpVector); | ||
|
|
||
| protected abstract string CreateViewportMethodName { get; } | ||
| protected abstract Matrix4x4 CreateViewport(float x, float y, float width, float height, float minDepth, float maxDepth); | ||
|
|
||
| protected abstract string CreateBillboardMethodName { get; } | ||
| protected abstract Matrix4x4 CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector); | ||
|
|
||
| protected abstract string CreateConstrainedBillboardMethodName { get; } | ||
| protected abstract Matrix4x4 CreateConstrainedBillboard( | ||
| Vector3 objectPosition, | ||
| Vector3 cameraPosition, | ||
| Vector3 rotateAxis, | ||
| Vector3 cameraForwardVector, | ||
| Vector3 objectForwardVector); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| namespace System.Numerics.Tests | ||
| { | ||
| public class Matrix4x4RightHandChangedBasisTests : Matrix4x4LeftHandTests | ||
| { | ||
| protected override string CreateLookAtMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateLookAt)}"; | ||
| protected override Matrix4x4 CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector) | ||
| { | ||
| return RightHandToLeftHand * Matrix4x4.CreateLookAt( | ||
| ChangeLeftHandToRightHand(cameraPosition), | ||
| ChangeLeftHandToRightHand(cameraTarget), | ||
| ChangeLeftHandToRightHand(cameraUpVector)) * LeftHandToRightHand; | ||
| } | ||
|
|
||
| protected override string CreateLookToMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateLookTo)}"; | ||
| protected override Matrix4x4 CreateLookTo(Vector3 cameraPosition, Vector3 cameraDirection, Vector3 cameraUpVector) | ||
| { | ||
| return RightHandToLeftHand * Matrix4x4.CreateLookTo( | ||
| ChangeLeftHandToRightHand(cameraPosition), | ||
| ChangeLeftHandToRightHand(cameraDirection), | ||
| ChangeLeftHandToRightHand(cameraUpVector)) * LeftHandToRightHand; | ||
| } | ||
|
|
||
| protected override string CreateViewportMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateViewport)}"; | ||
| protected override Matrix4x4 CreateViewport(float x, float y, float width, float height, float minDepth, float maxDepth) | ||
| { | ||
| return RightHandToLeftHand * Matrix4x4.CreateViewport(x, y, width, height, -minDepth, -maxDepth) * LeftHandToRightHand; | ||
| } | ||
|
|
||
| protected override string CreateBillboardMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateBillboard)}"; | ||
| protected override Matrix4x4 CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector) | ||
| { | ||
| return RightHandToLeftHand * Matrix4x4.CreateBillboard( | ||
| ChangeLeftHandToRightHand(objectPosition), | ||
| ChangeLeftHandToRightHand(cameraPosition), | ||
| ChangeLeftHandToRightHand(cameraUpVector), | ||
| ChangeLeftHandToRightHand(cameraForwardVector)) * LeftHandToRightHand; | ||
| } | ||
|
|
||
| protected override string CreateConstrainedBillboardMethodName => $"{nameof(Matrix4x4)}.{nameof(Matrix4x4.CreateConstrainedBillboard)}"; | ||
| protected override Matrix4x4 CreateConstrainedBillboard( | ||
| Vector3 objectPosition, | ||
| Vector3 cameraPosition, | ||
| Vector3 rotateAxis, | ||
| Vector3 cameraForwardVector, | ||
| Vector3 objectForwardVector) | ||
| { | ||
| return RightHandToLeftHand * Matrix4x4.CreateConstrainedBillboard( | ||
| ChangeLeftHandToRightHand(objectPosition), | ||
| ChangeLeftHandToRightHand(cameraPosition), | ||
| ChangeLeftHandToRightHand(rotateAxis), | ||
| ChangeLeftHandToRightHand(cameraForwardVector), | ||
| ChangeLeftHandToRightHand(objectForwardVector)) * LeftHandToRightHand; | ||
| } | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.