Merge branch 'master' into customizableJobhandle

This commit is contained in:
ousttrue
2025-07-14 17:40:47 +09:00
committed by GitHub
41 changed files with 627 additions and 305 deletions

View File

@@ -1,4 +1,5 @@
using System;
using Unity.Mathematics;
using UnityEngine;
namespace UniGLTF.SpringBoneJobs.Blittables
@@ -7,15 +8,35 @@ namespace UniGLTF.SpringBoneJobs.Blittables
/// Blittableなコライダ
/// </summary>
[Serializable]
public struct BlittableCollider
public readonly struct BlittableCollider
{
public BlittableColliderType colliderType;
public Vector3 offset;
public float radius;
// capsule tail or plane normal
public Vector3 tailOrNormal;
public int transformIndex;
private readonly float3x3 _data;
public BlittableColliderType colliderType => (BlittableColliderType)(int)_data.c2.y;
public float3 offset => _data.c0;
public float radius => _data.c2.x;
// capsule tail or plane normal
public float3 tailOrNormal => _data.c1;
public int transformIndex => (int)_data.c2.z;
public BlittableCollider(
float3 offset = default,
float radius = 0,
float3 tailOrNormal = default,
BlittableColliderType colliderType = default,
int colliderTransformIndex = 0)
{
var c0 = offset;
var c1 = tailOrNormal;
var c2 = new float3(radius,(int)colliderType, colliderTransformIndex);
_data = new float3x3(c0, c1, c2);
}
public BlittableCollider SetTransformIndex(int index)
{
return new BlittableCollider(offset, radius, tailOrNormal, colliderType, index);
}
public void DrawGizmo(BlittableTransform t)
{
Gizmos.matrix = t.localToWorldMatrix;

View File

@@ -1,4 +1,5 @@
using System;
using Unity.Mathematics;
using UnityEngine;
namespace UniGLTF.SpringBoneJobs.Blittables
@@ -9,15 +10,31 @@ namespace UniGLTF.SpringBoneJobs.Blittables
/// 変わりにくいスコープ。
/// </summary>
[Serializable]
public struct BlittableJointImmutable
public readonly struct BlittableJointImmutable
{
public int parentTransformIndex;
public int headTransformIndex;
public int tailTransformIndex;
public float length;
public Quaternion localRotation;
public Vector3 boneAxis;
private readonly float4x3 _data;
public int parentTransformIndex => (int)_data.c2.x;
public int headTransformIndex => (int)_data.c2.y;
public int tailTransformIndex => (int)_data.c2.z;
public float length => _data.c2.w;
public quaternion localRotation => _data.c0;
public float3 boneAxis => _data.c1.xyz;
public BlittableJointImmutable(
int parentTransformIndex = 0,
int headTransformIndex = 0,
int tailTransformIndex = 0,
float length = 0,
quaternion localRotation = default,
float3 boneAxis = default)
{
var c0 = localRotation.value;
var c1 = new float4(boneAxis, 0);
var c2 = new float4(parentTransformIndex, headTransformIndex, tailTransformIndex, length);
_data = new float4x3(c0, c1, c2);
}
public void DrawGizmo(BlittableTransform t, BlittableJointMutable m)
{
Gizmos.matrix = t.localToWorldMatrix;

View File

@@ -1,5 +1,5 @@
using System;
using UnityEngine;
using Unity.Mathematics;
namespace UniGLTF.SpringBoneJobs.Blittables
{
@@ -10,12 +10,25 @@ namespace UniGLTF.SpringBoneJobs.Blittables
/// JointReconfigure を呼ばなければ以前と同じで不変となる。
/// </summary>
[Serializable]
public struct BlittableJointMutable
public readonly struct BlittableJointMutable
{
public float stiffnessForce;
public float gravityPower;
public Vector3 gravityDir;
public float dragForce;
public float radius;
private readonly float4x2 _data;
public float stiffnessForce => _data.c0.x;
public float gravityPower => _data.c0.y;
public float3 gravityDir => _data.c1.xyz;
public float dragForce => _data.c0.z;
public float radius => _data.c0.w;
public BlittableJointMutable(float stiffnessForce = 0,
float gravityPower = 0,
float3 gravityDir = default,
float dragForce = 0,
float radius = 0)
{
var c0 = new float4(stiffnessForce, gravityPower, dragForce, radius);
var c1 = new float4(gravityDir, 0);
_data = new float4x2(c0, c1);
}
}
}

View File

@@ -1,23 +1,33 @@
using UnityEngine;
using Unity.Mathematics;
namespace UniGLTF.SpringBoneJobs.Blittables
{
public struct BlittableModelLevel
public readonly struct BlittableModelLevel
{
private readonly float4 _data;
/// <summary>
/// World 座標系の追加の力。風など。
/// </summary>
public Vector3 ExternalForce;
public float3 ExternalForce => _data.xyz;
/// <summary>
/// 処理結果の Transform への書き戻しを停止する。
/// </summary>
public bool StopSpringBoneWriteback;
public bool StopSpringBoneWriteback => ((int)_data.w & 1) != 0;
/// <summary>
/// スケール値に連動して SpringBone のパラメータを自動調整する。
/// (見た目の角速度が同じになるようにする)
/// </summary>
public bool SupportsScalingAtRuntime;
public bool SupportsScalingAtRuntime => ((int)_data.w & 2) != 0;
public BlittableModelLevel(float3 externalForce = default,
bool stopSpringBoneWriteback = false,
bool supportsScalingAtRuntime = false)
{
var w = (stopSpringBoneWriteback ? 1 : 0) | ((supportsScalingAtRuntime ? 1 : 0) << 1);
_data = new float4(externalForce, w);
}
}
}

View File

@@ -3,11 +3,20 @@ using System;
namespace UniGLTF.SpringBoneJobs.Blittables
{
[Serializable]
public struct BlittableSpan
public readonly struct BlittableSpan
{
public int startIndex;
public int count;
private readonly int _startIndex;
private readonly int _count;
public int startIndex => _startIndex;
public int count => _count;
public int EndIndex => startIndex + count;
public BlittableSpan(int startIndex, int count)
{
_startIndex = startIndex;
_count = count;
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using Unity.Mathematics;
namespace UniGLTF.SpringBoneJobs.Blittables
{
@@ -7,12 +8,21 @@ namespace UniGLTF.SpringBoneJobs.Blittables
/// FastSpringBoneではこれを起点として並列化し、処理を行う
/// </summary>
[Serializable]
public struct BlittableSpring
public readonly struct BlittableSpring
{
public BlittableSpan colliderSpan;
public BlittableSpan logicSpan;
public int centerTransformIndex;
public int transformIndexOffset;
public int modelIndex;
private readonly int4x2 _data;
public BlittableSpan colliderSpan => new(_data.c0.x, _data.c0.y);
public BlittableSpan logicSpan => new(_data.c0.z, _data.c0.w);
public int centerTransformIndex => _data.c1.x;
public int transformIndexOffset => _data.c1.y;
public int modelIndex => _data.c1.z;
public BlittableSpring(BlittableSpan colliderSpan = default, BlittableSpan logicSpan = default, int centerTransformIndex = 0, int transformIndexOffset = 0, int modelIndex = 0)
{
var c0 = new int4(colliderSpan.startIndex, colliderSpan.count, logicSpan.startIndex, logicSpan.count);
var c1 = new int4(centerTransformIndex, transformIndexOffset, modelIndex, 0);
_data = new int4x2(c0, c1);
}
}
}

View File

@@ -1,5 +1,7 @@
using System;
using UnityEngine;
using System.Runtime.CompilerServices;
using Unity.Mathematics;
using UnityEngine.Jobs;
namespace UniGLTF.SpringBoneJobs.Blittables
{
@@ -7,14 +9,147 @@ namespace UniGLTF.SpringBoneJobs.Blittables
/// Transformの必要な機能だけを絞り、Blittableに対応させたクラス
/// </summary>
[Serializable]
public struct BlittableTransform
public readonly struct BlittableTransform
{
public Vector3 position;
public Quaternion rotation;
public Vector3 localPosition;
public Quaternion localRotation;
public Vector3 localScale;
public Matrix4x4 localToWorldMatrix;
public Matrix4x4 worldToLocalMatrix;
private readonly float4x3 _localData;
private readonly float4x4 _globalData;
public float3 position => GetPosition();
public quaternion rotation => GetRotation();
public float3 lossyScale => GetLossyScale();
public float3 localPosition => _localData.c0.xyz;
public quaternion localRotation => _localData.c1;
public float3 localScale => _localData.c2.xyz;
public float4x4 localToWorldMatrix => GetLocalToWorldMatrix();
public float4x4 worldToLocalMatrix => math.inverse(localToWorldMatrix);
public static BlittableTransform FromTransformAccess(TransformAccess transform)
{
return new BlittableTransform(
transform.rotation,
transform.localPosition,
transform.localRotation,
transform.localScale,
transform.localToWorldMatrix);
}
private BlittableTransform(
quaternion rotation,
float3 localPosition,
quaternion localRotation,
float3 localScale,
float4x4 localToWorldMatrix)
{
var c10 = new float4(localPosition, 0);
var c11 = localRotation;
var c12 = new float4(localScale, 0);
_localData = new float4x3(c10, c11.value, c12);
var c20 = new float4(localToWorldMatrix.c0.xyz, rotation.value.x);
var c21 = new float4(localToWorldMatrix.c1.xyz, rotation.value.y);
var c22 = new float4(localToWorldMatrix.c2.xyz, rotation.value.z);
var c23 = new float4(localToWorldMatrix.c3.xyz, rotation.value.w);
_globalData = new float4x4(c20, c21, c22, c23);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private float4x4 GetLocalToWorldMatrix()
{
var c0 = new float4(_globalData.c0.xyz, 0);
var c1 = new float4(_globalData.c1.xyz, 0);
var c2 = new float4(_globalData.c2.xyz, 0);
var c3 = new float4(_globalData.c3.xyz, 1);
return new float4x4(c0, c1, c2, c3);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private float3 GetPosition()
{
return localToWorldMatrix.c3.xyz;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private quaternion GetRotation()
{
return new quaternion(_globalData.c0.w, _globalData.c1.w, _globalData.c2.w, _globalData.c3.w);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private float3 GetLossyScale()
{
float4x4 tr = float4x4.TRS(position, rotation, new float3(1.0f));
float4x4 m = math.mul(math.inverse(tr), localToWorldMatrix);
return new float3(m.c0.x, m.c1.y, m.c2.z);
}
/// <summary>
/// 親Transformが移動や回転を行った際に、ローカル座標系の値をもとに新しい絶対座標系でのTransformを計算します。
/// </summary>
/// <param name="parent"></param>
/// <returns></returns>
public BlittableTransform UpdateParentMatrix(BlittableTransform parent)
{
quaternion newRotation = math.mul(parent.rotation, localRotation);
float4x4 newLocalToWorldMatrix = math.mul(parent.localToWorldMatrix, float4x4.TRS(localPosition, localRotation, localScale));
return new BlittableTransform(newRotation, localPosition, localRotation, localScale, newLocalToWorldMatrix);
}
/// <summary>
/// グローバル座標系での位置を更新し、それに伴って連動する他の値も更新します。
/// </summary>
/// <param name="newValue"></param>
/// <param name="parent"></param>
/// <returns></returns>
public BlittableTransform UpdatePosition(float3 newValue, BlittableTransform? parent = null)
{
quaternion newRotation;
float3 newLocalPosition;
quaternion newLocalRotation;
float4x4 newLocalToWorldMatrix;
if(parent.HasValue)
{
newLocalPosition = math.transform(parent.Value.worldToLocalMatrix, newValue);
newLocalRotation = math.mul(math.inverse(parent.Value.rotation), rotation);
newRotation = math.mul(parent.Value.rotation, newLocalRotation);
newLocalToWorldMatrix = math.mul(parent.Value.localToWorldMatrix, float4x4.TRS(newLocalPosition, newLocalRotation, localScale));
}
else
{
newLocalPosition = newValue;
newLocalRotation = rotation;
newRotation = rotation;
newLocalToWorldMatrix = float4x4.TRS(newValue, newRotation, localScale);
}
return new BlittableTransform(newRotation, newLocalPosition, newLocalRotation, localScale, newLocalToWorldMatrix);
}
/// <summary>
/// グローバル座標系での回転を更新し、それに伴って連動する他の値も更新します。
/// </summary>
/// <param name="newValue"></param>
/// <param name="parent"></param>
/// <returns></returns>
public BlittableTransform UpdateRotation(quaternion newValue, BlittableTransform? parent = null)
{
quaternion newRotation = newValue;
quaternion newLocalRotation;
float4x4 newLocalToWorldMatrix;
if(parent.HasValue)
{
newLocalRotation = math.normalize(math.mul(math.inverse(parent.Value.rotation), newRotation));
newLocalToWorldMatrix = math.mul(parent.Value.localToWorldMatrix, float4x4.TRS(localPosition, newLocalRotation, localScale));
}
else
{
newLocalRotation = newValue;
newLocalToWorldMatrix = float4x4.TRS(position, newRotation, localScale);
}
return new BlittableTransform(newRotation, localPosition, newLocalRotation, localScale, newLocalToWorldMatrix);
}
}
}
}

View File

@@ -5,10 +5,12 @@ using Unity.Burst;
using System;
using System.Collections.Generic;
using System.Linq;
using UniGLTF.Runtime.Utils;
using UniGLTF.SpringBoneJobs.Blittables;
using UniGLTF.SpringBoneJobs.InputPorts;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Jobs;
using UnityEngine.Profiling;
@@ -23,9 +25,9 @@ namespace UniGLTF.SpringBoneJobs
// Joint Level
private NativeArray<BlittableJointImmutable> _logics;
private NativeArray<BlittableJointMutable> _joints;
private NativeArray<Vector3> _prevTails;
private NativeArray<Vector3> _currentTails;
private NativeArray<Vector3> _nextTails;
private NativeArray<float3> _prevTails;
private NativeArray<float3> _currentTails;
private NativeArray<float3> _nextTails;
// Spring Level
private NativeArray<BlittableSpring> _springs;
// Moodel Level
@@ -39,9 +41,9 @@ namespace UniGLTF.SpringBoneJobs
// accessor: Joint Level
public NativeArray<BlittableJointImmutable> Logics => _logics;
public NativeArray<BlittableJointMutable> Joints => _joints;
public NativeArray<Vector3> PrevTails => _prevTails;
public NativeArray<Vector3> CurrentTails => _currentTails;
public NativeArray<Vector3> NextTails => _nextTails;
public NativeArray<float3> PrevTails => _prevTails;
public NativeArray<float3> CurrentTails => _currentTails;
public NativeArray<float3> NextTails => _nextTails;
// accessor: Spring Level
public NativeArray<BlittableSpring> Springs => _springs;
// accessor: Model LEvel
@@ -64,9 +66,9 @@ namespace UniGLTF.SpringBoneJobs
// joint level
_logics = new NativeArray<BlittableJointImmutable>(logicsCount, Allocator.Persistent);
_joints = new NativeArray<BlittableJointMutable>(logicsCount, Allocator.Persistent);
_prevTails = new NativeArray<Vector3>(logicsCount, Allocator.Persistent);
_currentTails = new NativeArray<Vector3>(logicsCount, Allocator.Persistent);
_nextTails = new NativeArray<Vector3>(logicsCount, Allocator.Persistent);
_prevTails = new NativeArray<float3>(logicsCount, Allocator.Persistent);
_currentTails = new NativeArray<float3>(logicsCount, Allocator.Persistent);
_nextTails = new NativeArray<float3>(logicsCount, Allocator.Persistent);
// spring level
_springs = new NativeArray<BlittableSpring>(springsCount, Allocator.Persistent);
// model level
@@ -248,11 +250,12 @@ namespace UniGLTF.SpringBoneJobs
public void Execute(int index)
{
var spring = SrcSprings[index];
spring.modelIndex = ModelIndex;
spring.colliderSpan.startIndex += CollidersOffset;
spring.logicSpan.startIndex += LogicsOffset;
spring.transformIndexOffset = TransformOffset;
DestSprings[index] = spring;
DestSprings[index] = new BlittableSpring(
modelIndex: ModelIndex,
colliderSpan: new BlittableSpan(spring.colliderSpan.startIndex + CollidersOffset, spring.colliderSpan.count),
logicSpan: new BlittableSpan(spring.logicSpan.startIndex + LogicsOffset, spring.logicSpan.count),
transformIndexOffset: TransformOffset,
centerTransformIndex: spring.centerTransformIndex);
}
}
@@ -296,9 +299,9 @@ namespace UniGLTF.SpringBoneJobs
[ReadOnly] public NativeArray<BlittableJointImmutable> Logics;
[ReadOnly] public NativeArray<BlittableTransform> Transforms;
[NativeDisableParallelForRestriction] public NativeSlice<Vector3> CurrentTails;
[NativeDisableParallelForRestriction] public NativeSlice<Vector3> PrevTails;
[NativeDisableParallelForRestriction] public NativeSlice<Vector3> NextTails;
[NativeDisableParallelForRestriction] public NativeSlice<float3> CurrentTails;
[NativeDisableParallelForRestriction] public NativeSlice<float3> PrevTails;
[NativeDisableParallelForRestriction] public NativeSlice<float3> NextTails;
public void Execute(int springIndex)
{
@@ -323,7 +326,7 @@ namespace UniGLTF.SpringBoneJobs
}
var tail = Transforms[tailIndex];
var tailPos = center.HasValue ? center.Value.worldToLocalMatrix.MultiplyPoint3x4(tail.position) : tail.position;
var tailPos = center.HasValue ? MathHelper.MultiplyPoint3x4(center.Value.worldToLocalMatrix, tail.position) : tail.position;
CurrentTails[jointIndex] = tailPos;
PrevTails[jointIndex] = tailPos;
NextTails[jointIndex] = tailPos;

View File

@@ -2,9 +2,10 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Profiling;
using UniGLTF.SpringBoneJobs.Blittables;
using Unity.Mathematics;
using UnityEngine;
namespace UniGLTF.SpringBoneJobs.InputPorts
{
@@ -22,8 +23,8 @@ namespace UniGLTF.SpringBoneJobs.InputPorts
public NativeArray<BlittableJointMutable> Joints { get; }
public NativeArray<BlittableCollider> Colliders { get; }
public NativeArray<BlittableJointImmutable> Logics { get; }
private NativeArray<Vector3> _currentTailsBackup;
private NativeArray<Vector3> _nextTailsBackup;
private NativeArray<float3> _currentTailsBackup;
private NativeArray<float3> _nextTailsBackup;
public Transform[] Transforms { get; }
/// <summary>
@@ -67,27 +68,17 @@ namespace UniGLTF.SpringBoneJobs.InputPorts
List<BlittableJointImmutable> blittableLogics = new();
foreach (var spring in springs)
{
var blittableSpring = new BlittableSpring
{
colliderSpan = new BlittableSpan
{
startIndex = blittableColliders.Count,
count = spring.colliders.Length,
},
logicSpan = new BlittableSpan
{
startIndex = blittableJoints.Count,
count = spring.joints.Length - 1,
},
centerTransformIndex = Array.IndexOf(Transforms, spring.center),
};
var blittableSpring = new BlittableSpring(
centerTransformIndex: Array.IndexOf(Transforms, spring.center),
colliderSpan: new BlittableSpan(blittableColliders.Count, spring.colliders.Length),
logicSpan: new BlittableSpan(blittableJoints.Count, spring.joints.Length - 1));
blittableSprings.Add(blittableSpring);
blittableColliders.AddRange(spring.colliders.Select(collider =>
{
var blittable = collider.Collider;
blittable.transformIndex = Array.IndexOf(Transforms, collider.Transform);
return blittable;
var transformIndex = Array.IndexOf(Transforms, collider.Transform);
return blittable.SetTransformIndex(transformIndex);
}));
blittableJoints.AddRange(spring.joints
.Take(spring.joints.Length - 1).Select(joint =>
@@ -123,25 +114,23 @@ namespace UniGLTF.SpringBoneJobs.InputPorts
var localPosition = tailJoint.Transform.localPosition;
var scale = tailJoint.Transform.lossyScale;
var localChildPosition = new Vector3(
var localChildPosition = new float3(
localPosition.x * scale.x,
localPosition.y * scale.y,
localPosition.z * scale.z
);
yield return new BlittableJointImmutable
{
headTransformIndex = Array.IndexOf<Transform>(Transforms, joint.Transform),
parentTransformIndex = Array.IndexOf<Transform>(Transforms, joint.Transform.parent),
tailTransformIndex = Array.IndexOf<Transform>(Transforms, tailJoint.Transform),
localRotation = joint.DefaultLocalRotation,
boneAxis = localChildPosition.normalized,
length = localChildPosition.magnitude
};
yield return new BlittableJointImmutable(
headTransformIndex: Array.IndexOf<Transform>(Transforms, joint.Transform),
parentTransformIndex: Array.IndexOf<Transform>(Transforms, joint.Transform.parent),
tailTransformIndex: Array.IndexOf<Transform>(Transforms, tailJoint.Transform),
localRotation: joint.DefaultLocalRotation,
boneAxis: math.normalize(localChildPosition),
length: math.length(localChildPosition));
}
}
public void BackupCurrentTails(NativeArray<Vector3> currentTails, NativeArray<Vector3> nextTails, int offset)
public void BackupCurrentTails(NativeArray<float3> currentTails, NativeArray<float3> nextTails, int offset)
{
if (!Logics.IsCreated || Logics.Length == 0)
{
@@ -155,16 +144,16 @@ namespace UniGLTF.SpringBoneJobs.InputPorts
{
_nextTailsBackup = new(Logics.Length, Allocator.Persistent);
}
NativeArray<Vector3>.Copy(currentTails, offset, _currentTailsBackup, 0, Logics.Length);
NativeArray<Vector3>.Copy(nextTails, offset, _nextTailsBackup, 0, Logics.Length);
NativeArray<float3>.Copy(currentTails, offset, _currentTailsBackup, 0, Logics.Length);
NativeArray<float3>.Copy(nextTails, offset, _nextTailsBackup, 0, Logics.Length);
}
public void RestoreCurrentTails(NativeArray<Vector3> currentTails, NativeArray<Vector3> nextTails, int offset)
public void RestoreCurrentTails(NativeArray<float3> currentTails, NativeArray<float3> nextTails, int offset)
{
if (_currentTailsBackup.IsCreated)
{
NativeArray<Vector3>.Copy(_currentTailsBackup, 0, currentTails, offset, Logics.Length);
NativeArray<Vector3>.Copy(_nextTailsBackup, 0, nextTails, offset, Logics.Length);
NativeArray<float3>.Copy(_currentTailsBackup, 0, currentTails, offset, Logics.Length);
NativeArray<float3>.Copy(_nextTailsBackup, 0, nextTails, offset, Logics.Length);
}
else
{
@@ -173,7 +162,7 @@ namespace UniGLTF.SpringBoneJobs.InputPorts
{
// mark velocity zero
#if UNITY_2022_2_OR_NEWER
currentTails.GetSubArray(offset, Logics.Length).AsSpan().Fill(new Vector3(float.NaN, float.NaN, float.NaN));
currentTails.GetSubArray(offset, Logics.Length).AsSpan().Fill(new float3(float.NaN, float.NaN, float.NaN));
#else
var subArray = currentTails.GetSubArray(offset, Logics.Length);
var value = new Vector3(float.NaN, float.NaN, float.NaN);

View File

@@ -17,16 +17,7 @@ namespace UniGLTF.SpringBoneJobs
public void Execute(int index, TransformAccess transform)
{
Transforms[index] = new BlittableTransform
{
position = transform.position,
rotation = transform.rotation,
localPosition = transform.localPosition,
localRotation = transform.localRotation,
localScale = transform.localScale,
localToWorldMatrix = transform.localToWorldMatrix,
worldToLocalMatrix = transform.worldToLocalMatrix
};
Transforms[index] = BlittableTransform.FromTransformAccess(transform);
}
}
}

View File

@@ -2,7 +2,10 @@
"name": "SpringBoneJobs",
"rootNamespace": "",
"references": [
"GUID:8d76e605759c3f64a957d63ef96ada7c"
"GUID:8d76e605759c3f64a957d63ef96ada7c",
"GUID:1cd941934d098654fa21a13f28346412",
"GUID:2665a8d13d1b3f18800f46e256720795",
"GUID:d8b63aba1907145bea998dd612889d6b"
],
"includePlatforms": [],
"excludePlatforms": [],
@@ -11,6 +14,12 @@
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"versionDefines": [
{
"name": "com.unity.burst",
"expression": "0.01",
"define": "ENABLE_SPRINGBONE_BURST"
}
],
"noEngineReferences": false
}

View File

@@ -1,8 +1,9 @@
using System;
using UniGLTF.Runtime.Utils;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using UniGLTF.SpringBoneJobs.Blittables;
using Unity.Mathematics;
#if ENABLE_SPRINGBONE_BURST
using Unity.Burst;
#endif
@@ -26,10 +27,10 @@ namespace UniGLTF.SpringBoneJobs
// Joints, Logics, PrevTail, CurrentTail, NextTail は同じ index
[ReadOnly] public NativeArray<BlittableJointMutable> Joints;
[ReadOnly] public NativeArray<BlittableJointImmutable> Logics;
[ReadOnly] public NativeArray<Vector3> PrevTail;
[ReadOnly] public NativeArray<Vector3> CurrentTail;
[ReadOnly] public NativeArray<float3> PrevTail;
[ReadOnly] public NativeArray<float3> CurrentTail;
// 処理後の tail 位置(ランダムアクセス)
[NativeDisableParallelForRestriction] public NativeArray<Vector3> NextTail;
[NativeDisableParallelForRestriction] public NativeArray<float3> NextTail;
// Spring Level
[ReadOnly] public NativeArray<BlittableSpring> Springs;
// Model Level
@@ -67,43 +68,41 @@ namespace UniGLTF.SpringBoneJobs
// 親があったら、親に依存するTransformを再計算
if (parentTransform.HasValue)
{
headTransform.position =
parentTransform.Value.localToWorldMatrix.MultiplyPoint3x4(headTransform.localPosition);
headTransform.rotation = parentTransform.Value.rotation * headTransform.localRotation;
headTransform = headTransform.UpdateParentMatrix(parentTransform.Value);
}
var currentTail = centerTransform.HasValue
? centerTransform.Value.localToWorldMatrix.MultiplyPoint3x4(CurrentTail[logicIndex])
? MathHelper.MultiplyPoint3x4(centerTransform.Value.localToWorldMatrix, CurrentTail[logicIndex])
: CurrentTail[logicIndex];
var prevTail = centerTransform.HasValue
? centerTransform.Value.localToWorldMatrix.MultiplyPoint3x4(PrevTail[logicIndex])
? MathHelper.MultiplyPoint3x4(centerTransform.Value.localToWorldMatrix, PrevTail[logicIndex])
: PrevTail[logicIndex];
var parentRotation = parentTransform?.rotation ?? Quaternion.identity;
var parentRotation = parentTransform?.rotation ?? quaternion.identity;
// scaling 対応
var scalingFactor = model.SupportsScalingAtRuntime ? TransformExtensions.AbsoluteMaxValue(headTransform.localToWorldMatrix.lossyScale) : 1.0f;
var scalingFactor = model.SupportsScalingAtRuntime ? math.cmax(math.abs(headTransform.lossyScale)) : 1.0f;
// verlet積分で次の位置を計算
var external = (joint.gravityDir * joint.gravityPower + model.ExternalForce) * DeltaTime;
var nextTail = currentTail
+ (currentTail - prevTail) * (1.0f - joint.dragForce) // 前フレームの移動を継続する(減衰もあるよ)
+ parentRotation * logic.localRotation * logic.boneAxis *
+ math.mul(math.mul(parentRotation, logic.localRotation), logic.boneAxis) *
joint.stiffnessForce * DeltaTime * scalingFactor // 親の回転による子ボーンの移動目標
+ external * scalingFactor; // 外力による移動量
// 長さをboneLengthに強制
nextTail = headTransform.position + (nextTail - headTransform.position).normalized * logic.length;
nextTail = headTransform.position + math.normalize(nextTail - headTransform.position) * logic.length;
// Collisionで移動
for (var colliderIndex = colliderSpan.startIndex; colliderIndex < colliderSpan.startIndex + colliderSpan.count; ++colliderIndex)
{
var collider = Colliders[colliderIndex];
var colliderTransform = Transforms[collider.transformIndex + transformIndexOffset];
var colliderScale = colliderTransform.localToWorldMatrix.lossyScale;
var maxColliderScale = Mathf.Max(Mathf.Max(Mathf.Abs(colliderScale.x), Mathf.Abs(colliderScale.y)), Mathf.Abs(colliderScale.z));
var worldPosition = colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.offset);
var worldTail = colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.tailOrNormal);
var colliderScale = colliderTransform.lossyScale;
var maxColliderScale = math.max(math.max(math.abs(colliderScale.x), math.abs(colliderScale.y)), math.abs(colliderScale.z));
var worldPosition = MathHelper.MultiplyPoint3x4(colliderTransform.localToWorldMatrix, collider.offset);
var worldTail = MathHelper.MultiplyPoint3x4(colliderTransform.localToWorldMatrix, collider.tailOrNormal);
switch (collider.colliderType)
{
@@ -133,39 +132,14 @@ namespace UniGLTF.SpringBoneJobs
}
NextTail[logicIndex] = centerTransform.HasValue
? centerTransform.Value.worldToLocalMatrix.MultiplyPoint3x4(nextTail)
? MathHelper.MultiplyPoint3x4(centerTransform.Value.worldToLocalMatrix, nextTail)
: nextTail;
//回転を適用
var rotation = parentRotation * logic.localRotation;
headTransform.rotation = Quaternion.FromToRotation(rotation * logic.boneAxis,
nextTail - headTransform.position) * rotation;
// Transformを更新
if (parentTransform.HasValue)
{
var parentLocalToWorldMatrix = parentTransform.Value.localToWorldMatrix;
headTransform.localRotation = Normalize(Quaternion.Inverse(parentTransform.Value.rotation) * headTransform.rotation);
headTransform.localToWorldMatrix =
parentLocalToWorldMatrix *
Matrix4x4.TRS(
headTransform.localPosition,
headTransform.localRotation,
headTransform.localScale
);
headTransform.worldToLocalMatrix = headTransform.localToWorldMatrix.inverse;
}
else
{
headTransform.localToWorldMatrix =
Matrix4x4.TRS(
headTransform.position,
headTransform.rotation,
headTransform.localScale
);
headTransform.worldToLocalMatrix = headTransform.localToWorldMatrix.inverse;
headTransform.localRotation = headTransform.rotation;
}
var rotation = math.mul(parentRotation, logic.localRotation);
headTransform = headTransform.UpdateRotation(
math.mul(MathHelper.FromToRotation(math.mul(rotation, logic.boneAxis), nextTail - headTransform.position), rotation),
parentTransform);
if (!model.StopSpringBoneWriteback)
{
@@ -180,42 +154,33 @@ namespace UniGLTF.SpringBoneJobs
}
}
/// <summary>
/// BurstではMathfがエラーを吐くため、内部でMathfを呼ばないNormalizeを自前実装
/// </summary>
private static Quaternion Normalize(Quaternion q)
{
var num = (float)Math.Sqrt(Quaternion.Dot(q, q));
return num < float.Epsilon ? Quaternion.identity : new Quaternion(q.x / num, q.y / num, q.z / num, q.w / num);
}
private static void ResolveCapsuleCollision(
Vector3 worldTail,
Vector3 worldPosition,
float3 worldTail,
float3 worldPosition,
BlittableTransform headTransform,
BlittableJointMutable joint,
BlittableCollider collider,
float maxColliderScale,
BlittableJointImmutable logic,
ref Vector3 nextTail)
ref float3 nextTail)
{
var direction = worldTail - worldPosition;
if (direction.sqrMagnitude == 0)
if (math.lengthsq(direction) == 0)
{
// head側半球の球判定
ResolveSphereCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail);
return;
}
var P = direction.normalized;
var P = math.normalize(direction);
var Q = headTransform.position - worldPosition;
var dot = Vector3.Dot(P, Q);
var dot = math.dot(P, Q);
if (dot <= 0)
{
// head側半球の球判定
ResolveSphereCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail);
return;
}
if (dot >= direction.magnitude)
if (dot >= math.length(direction))
{
// tail側半球の球判定
ResolveSphereCollision(joint, collider, worldTail, headTransform, maxColliderScale, logic, ref nextTail);
@@ -228,58 +193,58 @@ namespace UniGLTF.SpringBoneJobs
}
private static void ResolveSphereCollision(
BlittableJointMutable joint,
BlittableCollider collider,
Vector3 worldPosition,
BlittableTransform headTransform,
float maxColliderScale,
BlittableJointImmutable logic,
ref Vector3 nextTail)
in BlittableJointMutable joint,
in BlittableCollider collider,
in float3 worldPosition,
in BlittableTransform headTransform,
in float maxColliderScale,
in BlittableJointImmutable logic,
ref float3 nextTail)
{
var r = joint.radius + collider.radius * maxColliderScale;
if (Vector3.SqrMagnitude(nextTail - worldPosition) <= (r * r))
if (math.lengthsq(nextTail - worldPosition) <= (r * r))
{
// ヒット。Colliderの半径方向に押し出す
var normal = (nextTail - worldPosition).normalized;
var normal = math.normalize(nextTail - worldPosition);
var posFromCollider = worldPosition + normal * r;
// 長さをboneLengthに強制
nextTail = headTransform.position + (posFromCollider - headTransform.position).normalized * logic.length;
nextTail = headTransform.position + math.normalize(posFromCollider - headTransform.position) * logic.length;
}
}
private static void ResolveSphereCollisionInside(
BlittableJointMutable joint,
BlittableCollider collider,
BlittableTransform colliderTransform,
ref Vector3 nextTail)
in BlittableJointMutable joint,
in BlittableCollider collider,
in BlittableTransform colliderTransform,
ref float3 nextTail)
{
var transformedOffset = colliderTransform.localToWorldMatrix.MultiplyPoint(collider.offset);
var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset);
var delta = nextTail - transformedOffset;
// ジョイントとコライダーの距離。負の値は衝突していることを示す
var distance = collider.radius - joint.radius - delta.magnitude;
var distance = collider.radius - joint.radius - math.length(delta);
// ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す
if (distance < 0)
{
var direction = -delta.normalized;
var direction = -1 * math.normalize(delta);
nextTail -= direction * distance;
}
}
private static void ResolveCapsuleCollisionInside(
BlittableJointMutable joint,
BlittableCollider collider,
BlittableTransform colliderTransform,
ref Vector3 nextTail)
in BlittableJointMutable joint,
in BlittableCollider collider,
in BlittableTransform colliderTransform,
ref float3 nextTail)
{
var transformedOffset = colliderTransform.localToWorldMatrix.MultiplyPoint(collider.offset);
var transformedTail = colliderTransform.localToWorldMatrix.MultiplyPoint(collider.tailOrNormal);
var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset);
var transformedTail = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.tailOrNormal);
var offsetToTail = transformedTail - transformedOffset;
var lengthSqCapsule = offsetToTail.sqrMagnitude;
var lengthSqCapsule = math.lengthsq(offsetToTail);
var delta = nextTail - transformedOffset;
var dot = Vector3.Dot(offsetToTail, delta);
var dot = math.dot(offsetToTail, delta);
if (dot < 0.0)
{
@@ -298,12 +263,12 @@ namespace UniGLTF.SpringBoneJobs
}
// ジョイントとコライダーの距離。負の値は衝突していることを示す
var distance = collider.radius - joint.radius - delta.magnitude;
var distance = collider.radius - joint.radius - math.length(delta);
// ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す
if (distance < 0)
{
var direction = -delta.normalized;
var direction = -1 * math.normalize(delta);
nextTail -= direction * distance;
}
}
@@ -317,17 +282,17 @@ namespace UniGLTF.SpringBoneJobs
/// <param name="colliderTransform">colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.offset);</param>
/// <param name="nextTail">result of verlet integration</param>
private static void ResolvePlaneCollision(
BlittableJointMutable joint,
BlittableCollider collider,
BlittableTransform colliderTransform,
ref Vector3 nextTail)
in BlittableJointMutable joint,
in BlittableCollider collider,
in BlittableTransform colliderTransform,
ref float3 nextTail)
{
var transformedOffset = colliderTransform.localToWorldMatrix.MultiplyPoint(collider.offset);
var transformedNormal = colliderTransform.localToWorldMatrix.MultiplyVector(collider.tailOrNormal).normalized;
var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset);
var transformedNormal = math.normalize(MathHelper.MultiplyVector(colliderTransform.localToWorldMatrix, collider.tailOrNormal));
var delta = nextTail - transformedOffset;
// ジョイントとコライダーの距離。負の値は衝突していることを示す
var distance = Vector3.Dot(delta, transformedNormal) - joint.radius;
var distance = math.dot(delta, transformedNormal) - joint.radius;
if (distance < 0)
{

View File

@@ -5,7 +5,7 @@ namespace UniGLTF
{
public const int MAJOR = 0;
public const int MINOR = 129;
public const int PATCH = 2;
public const string VERSION = "0.129.2";
public const int PATCH = 3;
public const string VERSION = "0.129.3";
}
}

View File

@@ -5,7 +5,7 @@ namespace UniGLTF
{
public const int MAJOR = 2;
public const int MINOR = 65;
public const int PATCH = 2;
public const string VERSION = "2.65.2";
public const int PATCH = 3;
public const string VERSION = "2.65.3";
}
}

View File

@@ -98,7 +98,9 @@ namespace UniHumanoid
{
map[t.name] = t;
}
return human.Select(x => (map[x.boneName], x.humanBone));
return human
.Where(x => !string.IsNullOrEmpty(x.boneName) && map.ContainsKey(x.boneName))
.Select(x => (map[x.boneName], x.humanBone));
}
public Avatar CreateAvatarAndSetup(Transform root)

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

View File

@@ -1,6 +1,6 @@
{
"name": "com.vrmc.gltf",
"version": "0.129.2",
"version": "0.129.3",
"displayName": "UniGLTF",
"description": "GLTF importer and exporter",
"unity": "2021.3",

View File

@@ -40,13 +40,10 @@ namespace VRM.SpringBoneJobs
var c = new FastSpringBoneCollider
{
Transform = group.transform,
Collider = new BlittableCollider
{
offset = collider.Offset,
radius = collider.Radius,
tailOrNormal = default,
colliderType = BlittableColliderType.Sphere
}
Collider = new BlittableCollider(
offset: collider.Offset,
radius: collider.Radius,
colliderType: BlittableColliderType.Sphere)
};
colliders.Add(c);
}
@@ -85,14 +82,12 @@ namespace VRM.SpringBoneJobs
joints.Add(new FastSpringBoneJoint
{
Transform = joint,
Joint = new BlittableJointMutable
{
radius = spring.m_hitRadius,
dragForce = spring.m_dragForce,
gravityDir = spring.m_gravityDir,
gravityPower = spring.m_gravityPower,
stiffnessForce = spring.m_stiffnessForce
},
Joint = new BlittableJointMutable(
radius: spring.m_hitRadius,
dragForce: spring.m_dragForce,
gravityDir: spring.m_gravityDir,
gravityPower: spring.m_gravityPower,
stiffnessForce: spring.m_stiffnessForce),
DefaultLocalRotation = initMap[joint.transform].LocalRotation,
});
foreach (Transform child in joint)

View File

@@ -7,7 +7,8 @@
"GUID:a9bc101fb0471f94a8f99fd242fdd934",
"GUID:1cd941934d098654fa21a13f28346412",
"GUID:60c8346e00a8ddd4cafc5a02eceeec57",
"GUID:3e5d614bc16b50d41bd94c8d7444ca46"
"GUID:3e5d614bc16b50d41bd94c8d7444ca46",
"GUID:d8b63aba1907145bea998dd612889d6b"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -1,6 +1,6 @@
{
"name": "com.vrmc.univrm",
"version": "0.129.2",
"version": "0.129.3",
"displayName": "VRM",
"description": "VRM importer",
"unity": "2021.3",
@@ -14,7 +14,7 @@
"name": "VRM Consortium"
},
"dependencies": {
"com.vrmc.gltf": "0.129.2",
"com.vrmc.gltf": "0.129.3",
"com.unity.ugui": "1.0.0"
},
"samples": [

View File

@@ -52,11 +52,11 @@
#ifdef MTOON_URP
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
#define MTOON_SHADOW_COORD input.shadowCoord
#define MTOON_SHADOW_COORD(input) input.shadowCoord
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
#define MTOON_SHADOW_COORD TransformWorldToShadowCoord(input.positionWS)
#define MTOON_SHADOW_COORD(input) TransformWorldToShadowCoord(input.positionWS)
#else
#define MTOON_SHADOW_COORD float4(0, 0, 0, 0)
#define MTOON_SHADOW_COORD(input) float4(0, 0, 0, 0)
#endif
#if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
@@ -70,7 +70,7 @@
#define MTOON_LIGHT_DESCRIPTION(input, atten, lightDir, lightColor) \
const half3 lightDir = _MainLightPosition.xyz; \
const half3 lightColor = _MainLightColor.rgb; \
const float atten = MainLightShadow(MTOON_SHADOW_COORD, input.positionWS, MTOON_SAMPLE_SHADOWMASK(input.lightmapUV), _MainLightOcclusionProbes);
const float atten = MainLightShadow(MTOON_SHADOW_COORD(input), input.positionWS, MTOON_SAMPLE_SHADOWMASK(input.lightmapUV), _MainLightOcclusionProbes);
#else
@@ -85,22 +85,22 @@
#ifdef MTOON_URP
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
#define MTOON_TRANSFER_FOG_AND_LIGHTING(o, outpos, coord, vertex) \
#define MTOON_TRANSFER_FOG_AND_LIGHTING(output, outpos, coord, vertex) \
OUTPUT_LIGHTMAP_UV(coord.xy, unity_LightmapST, output.lightmapUV); \
OUTPUT_SH(output.normalWS.xyz, output.vertexSH); \
output.fogFactorAndVertexLight = half4(ComputeFogFactor(outpos.z), VertexLighting(output.positionWS, output.normalWS)); \
output.shadowCoord = GetShadowCoord(GetVertexPositionInputs(vertex.xyz));
#else
#define MTOON_TRANSFER_FOG_AND_LIGHTING(o, outpos, coord, vertex) \
#define MTOON_TRANSFER_FOG_AND_LIGHTING(output, outpos, coord, vertex) \
OUTPUT_LIGHTMAP_UV(coord.xy, unity_LightmapST, output.lightmapUV); \
OUTPUT_SH(output.normalWS.xyz, output.vertexSH); \
output.fogFactorAndVertexLight = half4(ComputeFogFactor(outpos.z), VertexLighting(output.positionWS, output.normalWS));
#endif
#else
#define MTOON_TRANSFER_FOG_AND_LIGHTING(o, outpos, coord, vertex) \
UNITY_TRANSFER_FOG(o, outpos); \
UNITY_TRANSFER_LIGHTING(o, coord.xy);
#define MTOON_TRANSFER_FOG_AND_LIGHTING(output, outpos, coord, vertex) \
UNITY_TRANSFER_FOG(output, outpos); \
UNITY_TRANSFER_LIGHTING(output, coord.xy);
#endif
// SampleSH

View File

@@ -26,14 +26,12 @@ namespace UniVRM10
[SerializeField]
public float m_jointRadius = 0.02f;
public BlittableJointMutable Blittable => new BlittableJointMutable
{
stiffnessForce = m_stiffnessForce,
dragForce = m_dragForce,
gravityDir = m_gravityDir,
gravityPower = m_gravityPower,
radius = m_jointRadius,
};
public BlittableJointMutable Blittable => new BlittableJointMutable(
stiffnessForce: m_stiffnessForce,
gravityPower: m_gravityPower,
gravityDir: m_gravityDir,
dragForce: m_dragForce,
radius: m_jointRadius);
void AddJointRecursive(Transform t, VRM10SpringBoneJoint src)
{

View File

@@ -49,26 +49,22 @@ namespace UniVRM10
.Select(collider => new FastSpringBoneCollider
{
Transform = collider.transform,
Collider = new BlittableCollider
{
offset = collider.Offset,
radius = collider.Radius,
tailOrNormal = collider.TailOrNormal,
colliderType = TranslateColliderType(collider.ColliderType)
}
Collider = new BlittableCollider(
offset: collider.Offset,
radius: collider.Radius,
tailOrNormal: collider.TailOrNormal,
colliderType: TranslateColliderType(collider.ColliderType))
}).ToArray(),
joints = spring.Joints
.Select(joint => new FastSpringBoneJoint
{
Transform = joint.transform,
Joint = new BlittableJointMutable
{
radius = joint.m_jointRadius,
dragForce = joint.m_dragForce,
gravityDir = joint.m_gravityDir,
gravityPower = joint.m_gravityPower,
stiffnessForce = joint.m_stiffnessForce
},
Joint = new BlittableJointMutable(
radius: joint.m_jointRadius,
dragForce: joint.m_dragForce,
gravityDir: joint.m_gravityDir,
gravityPower: joint.m_gravityPower,
stiffnessForce: joint.m_stiffnessForce),
DefaultLocalRotation = GetOrAddDefaultTransformState(joint.transform).LocalRotation,
}).ToArray(),
}).ToArray();

View File

@@ -590,7 +590,10 @@ namespace UniVRM10
if (gltfSpring.ColliderGroups != null)
{
spring.ColliderGroups = gltfSpring.ColliderGroups.Select(x => controller.SpringBone.ColliderGroups[x]).ToList();
spring.ColliderGroups = gltfSpring.ColliderGroups
// VRM1_Constraint_Twist_Sample_Plane.vrm
.Where(x => x >= 0 && x < controller.SpringBone.ColliderGroups.Count)
.Select(x => controller.SpringBone.ColliderGroups[x]).ToList();
}
// joint
foreach (var gltfJoint in gltfSpring.Joints)

View File

@@ -8,6 +8,7 @@
"GUID:b7aa47b240b57de44a4b2021c143c9bf",
"GUID:f2ca1407928ebdc4bbe7765cc278be44",
"GUID:2665a8d13d1b3f18800f46e256720795",
"GUID:d8b63aba1907145bea998dd612889d6b",
"GUID:1cd941934d098654fa21a13f28346412",
"GUID:3e5d614bc16b50d41bd94c8d7444ca46",
"GUID:f06555f75b070af458a003d92f9efb00"

View File

@@ -1,6 +1,6 @@
{
"name": "com.vrmc.vrm",
"version": "0.129.2",
"version": "0.129.3",
"displayName": "VRM-1.0",
"description": "VRM-1.0 importer",
"unity": "2021.3",
@@ -15,7 +15,7 @@
},
"dependencies": {
"com.unity.timeline": "1.7.6",
"com.vrmc.gltf": "0.129.2"
"com.vrmc.gltf": "0.129.3"
},
"samples": [
{

View File

@@ -6,7 +6,8 @@
"GUID:e47c917724578cc43b5506c17a27e9a0",
"GUID:8d76e605759c3f64a957d63ef96ada7c",
"GUID:1cd941934d098654fa21a13f28346412",
"GUID:5f875fdc81c40184c8333b9d63c6ddd5"
"GUID:5f875fdc81c40184c8333b9d63c6ddd5",
"GUID:d8b63aba1907145bea998dd612889d6b"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -193,14 +193,12 @@ namespace UniVRM10.ClothWarp.Jobs
var colliderTransformIndex = GetOrAddColliderTransform(collider.transform);
colliderRef.Add(colliderInfo.Count);
colliderInfo.Add(new BlittableCollider
{
offset = collider.Offset,
radius = collider.Radius,
tailOrNormal = collider.TailOrNormal,
colliderType = TranslateColliderType(collider.ColliderType),
transformIndex = colliderTransformIndex,
});
colliderInfo.Add(new BlittableCollider(
offset: collider.Offset,
radius: collider.Radius,
tailOrNormal: collider.TailOrNormal,
colliderType: TranslateColliderType(collider.ColliderType),
colliderTransformIndex: colliderTransformIndex));
_colliders.Add(collider);
}

View File

@@ -39,14 +39,12 @@ namespace UniVRM10.ClothWarp.Jobs
public BlittableJointMutable ToBlittableJointMutable()
{
return new BlittableJointMutable
{
stiffnessForce = Stiffness,
gravityPower = 1.0f,
gravityDir = Gravity,
dragForce = Deceleration,
radius = Radius,
};
return new BlittableJointMutable(
stiffnessForce: Stiffness,
gravityPower: 1.0f,
gravityDir: Gravity,
dragForce: Deceleration,
radius: Radius);
}
}

View File

@@ -185,15 +185,14 @@ namespace UniVRM10.VRM10Viewer
m_controller.ShowBoxMan(m_showBoxMan.value);
if (m_controller.TryUpdate(
m_motionMode.value == 0,
new BlittableModelLevel
{
ExternalForce = new Vector3(
new BlittableModelLevel(
externalForce: new Vector3(
m_springboneExternalX.value,
m_springboneExternalY.value,
m_springboneExternalZ.value),
StopSpringBoneWriteback = m_useSpringbonePause.value,
SupportsScalingAtRuntime = m_useSpringboneScaling.value,
},
stopSpringBoneWriteback: m_useSpringbonePause.value,
supportsScalingAtRuntime: m_useSpringboneScaling.value
),
out var loaded
))
{

View File

@@ -7,7 +7,8 @@
"GUID:e47c917724578cc43b5506c17a27e9a0",
"GUID:1cd941934d098654fa21a13f28346412",
"GUID:3e5d614bc16b50d41bd94c8d7444ca46",
"GUID:f06555f75b070af458a003d92f9efb00"
"GUID:f06555f75b070af458a003d92f9efb00",
"GUID:d8b63aba1907145bea998dd612889d6b"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -226,12 +226,11 @@ namespace UniVRM10.VRM10Viewer
m_controller.ShowBoxMan(m_showBoxMan.isOn);
if (m_controller.TryUpdate(
m_ui.IsTPose,
new BlittableModelLevel
{
ExternalForce = new Vector3(m_springboneExternalX.value, m_springboneExternalY.value, m_springboneExternalZ.value),
StopSpringBoneWriteback = m_springbonePause.isOn,
SupportsScalingAtRuntime = m_springboneScaling.isOn,
},
new BlittableModelLevel(
externalForce: new Vector3(m_springboneExternalX.value, m_springboneExternalY.value, m_springboneExternalZ.value),
stopSpringBoneWriteback: m_springbonePause.isOn,
supportsScalingAtRuntime: m_springboneScaling.isOn
),
out var loaded
))
{

View File

@@ -6,7 +6,8 @@
"GUID:1cd941934d098654fa21a13f28346412",
"GUID:b7aa47b240b57de44a4b2021c143c9bf",
"GUID:05dd262a0c0a2f841b8252c8c3815582",
"GUID:3e5d614bc16b50d41bd94c8d7444ca46"
"GUID:3e5d614bc16b50d41bd94c8d7444ca46",
"GUID:d8b63aba1907145bea998dd612889d6b"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -343,15 +343,15 @@ namespace VRM.SimpleViewer
m_loaded.EnableLipSyncValue = m_enableLipSync.isOn;
m_loaded.EnableBlinkValue = m_enableAutoBlink.isOn;
m_loaded.SetSpringboneModelLevel(new UniGLTF.SpringBoneJobs.Blittables.BlittableModelLevel
{
ExternalForce = new Vector3(
(
externalForce: new Vector3(
m_springExternalX.value,
m_springExternalY.value,
m_springExternalZ.value
),
StopSpringBoneWriteback = m_springBonePause.isOn,
SupportsScalingAtRuntime = m_springBoneScaling.isOn,
});
stopSpringBoneWriteback: m_springBonePause.isOn,
supportsScalingAtRuntime: m_springBoneScaling.isOn
));
m_loaded.Update();
}
}

View File

@@ -4,6 +4,7 @@
"com.unity.cloud.ktx": "3.3.0",
"com.unity.cloud.ktx.webgl-2022": "1.0.1",
"com.unity.ide.rider": "3.0.36",
"com.unity.ide.visualstudio": "2.0.23",
"com.unity.postprocessing": "3.4.0",
"com.unity.render-pipelines.universal": "17.0.4",
"com.unity.test-framework": "1.1.33",

View File

@@ -42,6 +42,15 @@
},
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.23",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.9"
},
"url": "https://packages.unity.com"
},
"com.unity.mathematics": {
"version": "1.2.6",
"depth": 1,