SINGULARITY_EPSILON 特異点_閾値

This commit is contained in:
ousttrue
2026-09-03 10:20:48 +09:00
parent 9b8886da96
commit dc9de498d6
4 changed files with 10 additions and 9 deletions

View File

@@ -1,3 +1,4 @@
using System;
using UniGLTF.SpringBoneJobs.Blittables;
using Unity.Mathematics;
@@ -5,6 +6,8 @@ namespace UniGLTF.SpringBoneJobs
{
public static class Anglelimit
{
public static readonly float SINGULARITY_EPSILON = MathF.Sqrt(float.Epsilon);
public static float3 Apply(
in BlittableJointImmutable logic,
in BlittableJointMutable joint,
@@ -83,7 +86,7 @@ namespace UniGLTF.SpringBoneJobs
// headからtailに向かうベクトルとY+方向との内積
var dot = boneAxis.y;
if (dot == -1.0)
if (dot <= -1f + SINGULARITY_EPSILON)
{
// headからtailに向かうベクトルがY-方向の場合、X軸周りに180度回転させた回転を設定する
return new quaternion(1, 0, 0, 0);

View File

@@ -19,7 +19,7 @@ namespace UniGLTF.SpringBoneJobs
// x・z要素を、tailDirの正弦とjointに設定されたangleの正弦の比を用いてスケールする
var horizontalLengthSquared = 1.0f - tailDir.y * tailDir.y;
if (horizontalLengthSquared <= 1e-8f)
if (horizontalLengthSquared <= Anglelimit.SINGULARITY_EPSILON)
{
// tailDirがy軸負方向の場合、z軸正方向側を選択する
tailDir.x = 0.0f;

View File

@@ -13,7 +13,7 @@ namespace UniGLTF.SpringBoneJobs
limitAngle = math.clamp(limitAngle, 0.0f, math.PI);
var projectedLengthSquared = tailDir.y * tailDir.y + tailDir.z * tailDir.z;
if (projectedLengthSquared == 0.0f)
if (projectedLengthSquared <= Anglelimit.SINGULARITY_EPSILON)
{
// tailDirがx軸正方向または負方向の場合、Y軸正方向を選択する
tailDir = math.float3(0.0f, 1.0f, 0.0f);
@@ -30,7 +30,7 @@ namespace UniGLTF.SpringBoneJobs
{
var sinLimitAngle = math.sqrt(1.0f - cosLimitAngle * cosLimitAngle);
// tailDirがy軸負方向の場合、z軸正方向側を選択する
// zの符号を維持し、z==0 の場合は z軸正方向側を選択する
var zSign = (tailDir.z < 0.0f) ? -1.0f : 1.0f;
tailDir.y = cosLimitAngle;
tailDir.z = sinLimitAngle * zSign;

View File

@@ -1,6 +1,4 @@
using System;
using Unity.Mathematics;
using UnityEngine;
namespace UniGLTF.SpringBoneJobs
{
@@ -18,12 +16,12 @@ namespace UniGLTF.SpringBoneJobs
// tailDirのpitch・yawを計算する
float pitch;
if (tailDir.y == -1.0)
if (tailDir.y <= -1.0 + Anglelimit.SINGULARITY_EPSILON)
{
// tailDirがy軸負方向の場合、Z軸正方向側の境界を選択するため、pitchをπとする
pitch = math.PI;
}
else if (math.abs(tailDir.x) == 1.0f)
else if (math.abs(tailDir.x) <= 1.0f - Anglelimit.SINGULARITY_EPSILON)
{
// tailDirがx軸正方向または負方向の場合、pitchを0とする
pitch = 0.0f;
@@ -32,7 +30,7 @@ namespace UniGLTF.SpringBoneJobs
{
pitch = math.atan2(tailDir.z, tailDir.y);
}
var yaw = math.asin(tailDir.x);
var yaw = math.asin(math.clamp(tailDir.x, -1f, 1f));
// pitchをlimitに設定されたpitchを用いて制限する
if (math.abs(pitch) > limitPitch)