Mathematicsパッケージ演算をユーティリティクラスに分離

This commit is contained in:
AoiKamishiro
2025-07-01 09:49:29 +09:00
parent 022e23b6d5
commit da1bdcb728
6 changed files with 149 additions and 2 deletions

View File

@@ -0,0 +1,89 @@
using System.Runtime.CompilerServices;
using Unity.Mathematics;
namespace UniGLTF.Runtime.Utils
{
public static class MathHelper
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float3 MultiplyPoint3x4(float4x4 matrix, float3 point)
{
return math.mul(matrix, new float4(point, 1)).xyz;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float3 MultiplyPoint(float4x4 matrix, float3 point)
{
var v = math.mul(matrix, new float4(point, 1.0f));
return v.xyz / v.w;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float3 MultiplyVector(float4x4 matrix, float3 vector)
{
return math.mul(matrix, new float4(vector, 0)).xyz;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static quaternion FromToRotation(in float3 fromVector, in float3 toVector)
{
if (math.lengthsq(fromVector) == 0 || math.lengthsq(toVector) == 0)
{
return quaternion.identity;
}
float3 from = math.normalize(fromVector);
float3 to = math.normalize(toVector);
var dot = math.dot(from, to);
switch(dot)
{
case >= 1.0f:
return quaternion.identity;
case <= -1.0f:
{
var axis = math.cross(from, new float3(1, 0, 0));
if (math.lengthsq(axis) < 0.0001f)
{
axis = math.cross(from, new float3(0, 1, 0));
}
return quaternion.AxisAngle(math.normalize(axis), math.PI);
}
default:
{
var angle = math.acos(dot);
var axis = math.cross(from, to);
return quaternion.AxisAngle(math.normalize(axis), angle);
}
}
}
/// <summary>
/// <see cref="UnityEngine.Mathf.Approximately"/> を Unity.Mathematics パッケージ向けに再実装した関数
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static bool Approximately(float a, float b)
{
return math.abs(b - a) < math.max(1E-06f * math.max(math.abs(a), math.abs(b)), math.EPSILON * 8f);
}
/// <inheritdoc cref="MathHelper.Approximately(float, float)"/>
public static bool Approximately(float3 a, float3 b)
{
return Approximately(a.x, b.x) &&
Approximately(a.y, b.y) &&
Approximately(a.z, b.z);
}
/// <inheritdoc cref="MathHelper.Approximately(float, float)"/>
public static bool Approximately(quaternion a, quaternion b)
{
return Approximately(a.value.x, b.value.x) &&
Approximately(a.value.y, b.value.y) &&
Approximately(a.value.z, b.value.z) &&
Approximately(a.value.w, b.value.w);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 50ff9ccb88bd4c208ab432127ec7b04d
timeCreated: 1751330089

View File

@@ -1,7 +1,9 @@
{
"name": "UniGLTF.Utils",
"rootNamespace": "",
"references": [],
"references": [
"GUID:d8b63aba1907145bea998dd612889d6b"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,

View File

@@ -6,7 +6,8 @@
"GUID:5f875fdc81c40184c8333b9d63c6ddd5",
"GUID:27619889b8ba8c24980f49ee34dbb44a",
"GUID:0acc523941302664db1f4e527237feb3",
"GUID:1cd941934d098654fa21a13f28346412"
"GUID:1cd941934d098654fa21a13f28346412",
"GUID:d8b63aba1907145bea998dd612889d6b"
],
"includePlatforms": [
"Editor"

View File

@@ -0,0 +1,49 @@
using NUnit.Framework;
using UniGLTF.Runtime.Utils;
using Unity.Mathematics;
using UnityEngine;
namespace UniGLTF
{
public class MathTests
{
private readonly float4x4 _matrix = new float4x4(
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16);
private readonly float3 _vector1 = new float3(1, 2, 3);
private readonly float3 _vector2 = new float3(4, 5, 6);
[Test]
public void MultiplyPoint3x4Test()
{
var result = MathHelper.MultiplyPoint3x4(_matrix, _vector1);
var expected = ((Matrix4x4)_matrix).MultiplyPoint3x4(_vector1);
Assert.That(MathHelper.Approximately(result, expected), Is.True);
}
[Test]
public void MultiplyPointTest()
{
var result = MathHelper.MultiplyPoint(_matrix, _vector1);
var expected = ((Matrix4x4)_matrix).MultiplyPoint(_vector1);
Assert.That(MathHelper.Approximately(result, expected), Is.True);
}
[Test]
public void MultiplyVectorTest()
{
var result = MathHelper.MultiplyVector(_matrix, _vector1);
var expected = ((Matrix4x4)_matrix).MultiplyVector(_vector1);
Assert.That(MathHelper.Approximately(result, expected), Is.True);
}
[Test]
public void FromToRotationTest()
{
var result = MathHelper.FromToRotation(_vector1, _vector2);
var expected = Quaternion.FromToRotation(_vector1, _vector2);
Assert.That(MathHelper.Approximately(result, expected), Is.True);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4b920c4a4ea1401085ba8923e4ccaca2
timeCreated: 1751329860