mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-04-25 07:28:51 -05:00
Merge branch 'master' into fix-path-error
This commit is contained in:
commit
c7f311ba1a
|
|
@ -4,6 +4,8 @@ using Unity.Jobs;
|
|||
using UnityEngine.Profiling;
|
||||
using UniGLTF.SpringBoneJobs.InputPorts;
|
||||
using UnityEngine;
|
||||
using Unity.Collections;
|
||||
using System.Linq;
|
||||
|
||||
namespace UniGLTF.SpringBoneJobs
|
||||
{
|
||||
|
|
@ -20,19 +22,17 @@ namespace UniGLTF.SpringBoneJobs
|
|||
private FastSpringBoneCombinedBuffer _combinedBuffer;
|
||||
public FastSpringBoneCombinedBuffer Combined => _combinedBuffer;
|
||||
private readonly LinkedList<FastSpringBoneBuffer> _buffers = new LinkedList<FastSpringBoneBuffer>();
|
||||
private bool _isDirty;
|
||||
private Queue<(bool isAdd, FastSpringBoneBuffer buffer)> _request = new();
|
||||
public bool HasBuffer => _buffers.Count > 0 && _combinedBuffer != null;
|
||||
|
||||
public void Register(FastSpringBoneBuffer buffer)
|
||||
{
|
||||
_buffers.AddLast(buffer);
|
||||
_isDirty = true;
|
||||
_request.Enqueue((true, buffer));
|
||||
}
|
||||
|
||||
public void Unregister(FastSpringBoneBuffer buffer)
|
||||
{
|
||||
_buffers.Remove(buffer);
|
||||
_isDirty = true;
|
||||
_request.Enqueue((false, buffer));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -40,14 +40,45 @@ namespace UniGLTF.SpringBoneJobs
|
|||
/// </summary>
|
||||
public JobHandle ReconstructIfDirty(JobHandle handle)
|
||||
{
|
||||
if (_isDirty)
|
||||
if (_request.Count == 0)
|
||||
{
|
||||
var result = ReconstructBuffers(handle);
|
||||
_isDirty = false;
|
||||
return result;
|
||||
return handle;
|
||||
}
|
||||
|
||||
return handle;
|
||||
if (_combinedBuffer is FastSpringBoneCombinedBuffer combined)
|
||||
{
|
||||
// index が変わる前に シミュレーションの状態を保存する。
|
||||
// 状態の保存場所が BlittableJoint から CurrentTails に移動しているのでここでやる。
|
||||
var logicsIndex = 0;
|
||||
foreach (var buffer in _buffers)
|
||||
{
|
||||
if (_request.Any(x => !x.isAdd && x.buffer == buffer))
|
||||
{
|
||||
// 削除するので skip
|
||||
continue;
|
||||
}
|
||||
buffer.BackupCurrentTails(combined.CurrentTails, combined.NextTails, logicsIndex);
|
||||
logicsIndex += buffer.Logics.Length;
|
||||
}
|
||||
}
|
||||
|
||||
// buffer 増減
|
||||
while (_request.Count > 0)
|
||||
{
|
||||
var (isAdd, buffer) = _request.Dequeue();
|
||||
if (isAdd)
|
||||
{
|
||||
// 速度 0 にする
|
||||
_buffers.AddLast(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffers.Remove(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// 再構築
|
||||
return ReconstructBuffers(handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -60,10 +91,6 @@ namespace UniGLTF.SpringBoneJobs
|
|||
Profiler.BeginSample("FastSpringBone.ReconstructBuffers.DisposeBuffers");
|
||||
if (_combinedBuffer is FastSpringBoneCombinedBuffer combined)
|
||||
{
|
||||
Profiler.BeginSample("FastSpringBone.ReconstructBuffers.SaveToSourceBuffer");
|
||||
combined.SaveToSourceBuffer();
|
||||
Profiler.EndSample();
|
||||
|
||||
// TODO: Dispose せずに再利用?
|
||||
combined.Dispose();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ namespace UniGLTF.SpringBoneJobs
|
|||
springsCount += buffer.Springs.Length;
|
||||
collidersCount += buffer.Colliders.Length;
|
||||
logicsCount += buffer.Logics.Length;
|
||||
transformsCount += buffer.BlittableTransforms.Length;
|
||||
transformsCount += buffer.Transforms.Length;
|
||||
}
|
||||
Profiler.EndSample();
|
||||
|
||||
|
|
@ -112,6 +112,24 @@ namespace UniGLTF.SpringBoneJobs
|
|||
|
||||
private JobHandle Batching(JobHandle handle)
|
||||
{
|
||||
// TransformAccessArrayの構築
|
||||
Profiler.BeginSample("FastSpringBone.ReconstructBuffers.LoadTransformAccessArray");
|
||||
var transforms = new Transform[_transforms.Length];
|
||||
var transformAccessArrayOffset = 0;
|
||||
foreach (var buffer in _batchedBuffers)
|
||||
{
|
||||
Array.Copy(buffer.Transforms, 0, transforms, transformAccessArrayOffset, buffer.Transforms.Length);
|
||||
transformAccessArrayOffset += buffer.Transforms.Length;
|
||||
}
|
||||
_transformAccessArray = new TransformAccessArray(transforms);
|
||||
Profiler.EndSample();
|
||||
|
||||
// Transforms を更新。後続の InitCurrentTails で使う
|
||||
handle = new PullTransformJob
|
||||
{
|
||||
Transforms = Transforms
|
||||
}.Schedule(TransformAccessArray, handle);
|
||||
|
||||
Profiler.BeginSample("FastSpringBone.ReconstructBuffers.ScheduleLoadBufferJobs");
|
||||
var springsOffset = 0;
|
||||
var collidersOffset = 0;
|
||||
|
|
@ -129,13 +147,8 @@ namespace UniGLTF.SpringBoneJobs
|
|||
_jointMap.Add(buffer.Transforms[head], logicsOffset + j);
|
||||
}
|
||||
|
||||
// バッファの読み込みをスケジュール
|
||||
handle = new LoadTransformsJob
|
||||
{
|
||||
SrcTransforms = buffer.BlittableTransforms,
|
||||
DestTransforms = new NativeSlice<BlittableTransform>(_transforms, transformOffset,
|
||||
buffer.BlittableTransforms.Length)
|
||||
}.Schedule(buffer.BlittableTransforms.Length, 1, handle);
|
||||
// 速度の維持
|
||||
buffer.RestoreCurrentTails(_currentTails, _nextTails, logicsOffset);
|
||||
|
||||
handle = new LoadSpringsJob
|
||||
{
|
||||
|
|
@ -165,26 +178,10 @@ namespace UniGLTF.SpringBoneJobs
|
|||
springsOffset += buffer.Springs.Length;
|
||||
collidersOffset += buffer.Colliders.Length;
|
||||
logicsOffset += buffer.Logics.Length;
|
||||
transformOffset += buffer.BlittableTransforms.Length;
|
||||
transformOffset += buffer.Transforms.Length;
|
||||
}
|
||||
|
||||
handle = InitCurrentTails(handle);
|
||||
|
||||
// TransformAccessArrayの構築と並行してJobを行うため、この時点で走らせておく
|
||||
JobHandle.ScheduleBatchedJobs();
|
||||
Profiler.EndSample();
|
||||
|
||||
// TransformAccessArrayの構築
|
||||
Profiler.BeginSample("FastSpringBone.ReconstructBuffers.LoadTransformAccessArray");
|
||||
var transforms = new Transform[_transforms.Length];
|
||||
var transformAccessArrayOffset = 0;
|
||||
foreach (var buffer in _batchedBuffers)
|
||||
{
|
||||
Array.Copy(buffer.Transforms, 0, transforms, transformAccessArrayOffset, buffer.Transforms.Length);
|
||||
transformAccessArrayOffset += buffer.BlittableTransforms.Length;
|
||||
}
|
||||
|
||||
_transformAccessArray = new TransformAccessArray(transforms);
|
||||
Profiler.EndSample();
|
||||
|
||||
return handle;
|
||||
|
|
@ -208,25 +205,6 @@ namespace UniGLTF.SpringBoneJobs
|
|||
if (_transformAccessArray.isCreated) _transformAccessArray.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// バッチングされたバッファから、個々のバッファへと値を戻す
|
||||
/// Logics to _batchedBuffers[].Logics
|
||||
/// バッファの再構築前にこの処理を行わないと、揺れの状態がリセットされてしまい、不自然な挙動になる
|
||||
/// </summary>
|
||||
internal void SaveToSourceBuffer()
|
||||
{
|
||||
var logicsIndex = 0;
|
||||
for (var i = 0; i < _batchedBuffers.Length; ++i)
|
||||
{
|
||||
var length = _batchedBufferLogicSizes[i];
|
||||
if (!_batchedBuffers[i].IsDisposed && length > 0)
|
||||
{
|
||||
NativeArray<BlittableJointImmutable>.Copy(Logics, logicsIndex, _batchedBuffers[i].Logics, 0, length);
|
||||
}
|
||||
logicsIndex += length;
|
||||
}
|
||||
}
|
||||
|
||||
public void FlipBuffer()
|
||||
{
|
||||
var tmp = _prevTails;
|
||||
|
|
@ -251,23 +229,6 @@ namespace UniGLTF.SpringBoneJobs
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_SPRINGBONE_BURST
|
||||
[BurstCompile]
|
||||
#endif
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private struct LoadTransformsJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<BlittableTransform> SrcTransforms;
|
||||
[WriteOnly] public NativeSlice<BlittableTransform> DestTransforms;
|
||||
|
||||
public void Execute(int index)
|
||||
{
|
||||
DestTransforms[index] = SrcTransforms[index];
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_SPRINGBONE_BURST
|
||||
[BurstCompile]
|
||||
#endif
|
||||
|
|
@ -328,49 +289,69 @@ namespace UniGLTF.SpringBoneJobs
|
|||
#endif
|
||||
private struct InitCurrentTailsJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<BlittableSpring> Springs;
|
||||
|
||||
[ReadOnly] public NativeArray<BlittableJointImmutable> Logics;
|
||||
[ReadOnly] public NativeArray<BlittableTransform> Transforms;
|
||||
[WriteOnly] public NativeSlice<Vector3> CurrentTails;
|
||||
[WriteOnly] public NativeSlice<Vector3> PrevTails;
|
||||
[WriteOnly] public NativeSlice<Vector3> NextTails;
|
||||
[NativeDisableParallelForRestriction] public NativeSlice<Vector3> CurrentTails;
|
||||
[NativeDisableParallelForRestriction] public NativeSlice<Vector3> PrevTails;
|
||||
[NativeDisableParallelForRestriction] public NativeSlice<Vector3> NextTails;
|
||||
|
||||
public void Execute(int jointIndex)
|
||||
public void Execute(int springIndex)
|
||||
{
|
||||
var tailIndex = Logics[jointIndex].tailTransformIndex;
|
||||
if (tailIndex == -1)
|
||||
var spring = Springs[springIndex];
|
||||
for (int jointIndex = spring.logicSpan.startIndex; jointIndex < spring.logicSpan.EndIndex; ++jointIndex)
|
||||
{
|
||||
// tail 無い
|
||||
var tail = Transforms[Logics[jointIndex].headTransformIndex];
|
||||
CurrentTails[jointIndex] = tail.position;
|
||||
PrevTails[jointIndex] = tail.position;
|
||||
NextTails[jointIndex] = tail.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
var tail = Transforms[tailIndex];
|
||||
CurrentTails[jointIndex] = tail.position;
|
||||
PrevTails[jointIndex] = tail.position;
|
||||
NextTails[jointIndex] = tail.position;
|
||||
if (float.IsNaN(CurrentTails[jointIndex].x))
|
||||
{
|
||||
// Transsform の現状を使う。velocity を zero にする
|
||||
int tailIndex;
|
||||
if (Logics[jointIndex].tailTransformIndex == -1)
|
||||
{
|
||||
// tail 無い
|
||||
tailIndex = spring.transformIndexOffset + Logics[jointIndex].headTransformIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
tailIndex = spring.transformIndexOffset + Logics[jointIndex].tailTransformIndex;
|
||||
}
|
||||
|
||||
var tail = Transforms[tailIndex];
|
||||
CurrentTails[jointIndex] = tail.position;
|
||||
PrevTails[jointIndex] = tail.position;
|
||||
NextTails[jointIndex] = tail.position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transform から currentTail を更新。
|
||||
/// prevTail も同じ内容にする(速度0)。
|
||||
/// <summary>
|
||||
/// # CurrentTails[i] == NAN
|
||||
///
|
||||
/// Transforms から Current, Prev, Next を代入する。
|
||||
/// 速度 0 で初期化することになる。
|
||||
///
|
||||
/// # CurrentTails[i] != NAN
|
||||
///
|
||||
/// 本処理はスキップされて Current, Next の利用が継続されます。
|
||||
///
|
||||
/// # NAN
|
||||
///
|
||||
/// Batching 関数内の FastSpringBoneBuffer.RestoreCurrentTails にて backup の Current, Next が無かったときに
|
||||
/// 目印として NAN が代入されます。
|
||||
/// </summary>
|
||||
/// <param name="handle"></param>
|
||||
/// <returns></returns>
|
||||
public JobHandle InitCurrentTails(JobHandle handle)
|
||||
{
|
||||
return new InitCurrentTailsJob
|
||||
{
|
||||
Springs = Springs,
|
||||
|
||||
Logics = Logics,
|
||||
Transforms = Transforms,
|
||||
CurrentTails = CurrentTails,
|
||||
PrevTails = PrevTails,
|
||||
NextTails = NextTails,
|
||||
}.Schedule(Logics.Length, 1, handle);
|
||||
}.Schedule(Springs.Length, 1, handle);
|
||||
}
|
||||
|
||||
public void InitializeJointsLocalRotation(FastSpringBoneBuffer buffer)
|
||||
|
|
@ -379,9 +360,9 @@ namespace UniGLTF.SpringBoneJobs
|
|||
for (var i = 0; i < _batchedBuffers.Length; ++i)
|
||||
{
|
||||
var length = _batchedBufferLogicSizes[i];
|
||||
Debug.Assert(length == buffer.Logics.Length);
|
||||
if (_batchedBuffers[i] == buffer)
|
||||
{
|
||||
Debug.Assert(length == buffer.Logics.Length);
|
||||
for (var j = 0; j < length; ++j)
|
||||
{
|
||||
var logic = buffer.Logics[j];
|
||||
|
|
@ -401,22 +382,23 @@ namespace UniGLTF.SpringBoneJobs
|
|||
|
||||
public void DrawGizmos()
|
||||
{
|
||||
foreach (var collider in _colliders)
|
||||
{
|
||||
collider.DrawGizmo(_transforms[collider.transformIndex]);
|
||||
}
|
||||
|
||||
foreach (var spring in _springs)
|
||||
{
|
||||
for (int i = spring.colliderSpan.startIndex; i < spring.colliderSpan.EndIndex; ++i)
|
||||
{
|
||||
var collider = _colliders[i];
|
||||
collider.DrawGizmo(_transforms[spring.transformIndexOffset + collider.transformIndex]);
|
||||
}
|
||||
|
||||
for (int i = spring.logicSpan.startIndex; i < spring.logicSpan.EndIndex; ++i)
|
||||
{
|
||||
var joint = _logics[i];
|
||||
joint.DrawGizmo(_transforms[joint.tailTransformIndex], _joints[i]);
|
||||
joint.DrawGizmo(_transforms[spring.transformIndexOffset + joint.tailTransformIndex], _joints[i]);
|
||||
|
||||
Gizmos.matrix = Matrix4x4.identity;
|
||||
Gizmos.DrawLine(
|
||||
_transforms[joint.tailTransformIndex].position,
|
||||
_transforms[joint.headTransformIndex].position);
|
||||
_transforms[spring.transformIndexOffset + joint.tailTransformIndex].position,
|
||||
_transforms[spring.transformIndexOffset + joint.headTransformIndex].position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ namespace UniGLTF.SpringBoneJobs.InputPorts
|
|||
public NativeArray<BlittableJointMutable> Joints { get; }
|
||||
public NativeArray<BlittableCollider> Colliders { get; }
|
||||
public NativeArray<BlittableJointImmutable> Logics { get; }
|
||||
public NativeArray<BlittableTransform> BlittableTransforms { get; }
|
||||
private NativeArray<Vector3> _currentTailsBackup;
|
||||
private NativeArray<Vector3> _nextTailsBackup;
|
||||
public Transform[] Transforms { get; }
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Joint, Collider, Center の Transform のリスト
|
||||
|
|
@ -103,16 +103,6 @@ namespace UniGLTF.SpringBoneJobs.InputPorts
|
|||
Joints = new NativeArray<BlittableJointMutable>(blittableJoints.ToArray(), Allocator.Persistent);
|
||||
Colliders = new NativeArray<BlittableCollider>(blittableColliders.ToArray(), Allocator.Persistent);
|
||||
Logics = new NativeArray<BlittableJointImmutable>(blittableLogics.ToArray(), Allocator.Persistent);
|
||||
BlittableTransforms = new NativeArray<BlittableTransform>(Transforms.Select(transform => new BlittableTransform
|
||||
{
|
||||
position = transform.position,
|
||||
rotation = transform.rotation,
|
||||
localPosition = transform.localPosition,
|
||||
localRotation = transform.localRotation,
|
||||
localScale = transform.localScale,
|
||||
localToWorldMatrix = transform.localToWorldMatrix,
|
||||
worldToLocalMatrix = transform.worldToLocalMatrix
|
||||
}).ToArray(), Allocator.Persistent);
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
|
|
@ -151,15 +141,50 @@ namespace UniGLTF.SpringBoneJobs.InputPorts
|
|||
}
|
||||
}
|
||||
|
||||
public void BackupCurrentTails(NativeArray<Vector3> currentTails, NativeArray<Vector3> nextTails, int offset)
|
||||
{
|
||||
if (!Logics.IsCreated || Logics.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!_currentTailsBackup.IsCreated)
|
||||
{
|
||||
_currentTailsBackup = new(Logics.Length, Allocator.Persistent);
|
||||
}
|
||||
if (!_nextTailsBackup.IsCreated)
|
||||
{
|
||||
_nextTailsBackup = new(Logics.Length, Allocator.Persistent);
|
||||
}
|
||||
NativeArray<Vector3>.Copy(currentTails, offset, _currentTailsBackup, 0, Logics.Length);
|
||||
NativeArray<Vector3>.Copy(nextTails, offset, _nextTailsBackup, 0, Logics.Length);
|
||||
}
|
||||
|
||||
public void RestoreCurrentTails(NativeArray<Vector3> currentTails, NativeArray<Vector3> nextTails, int offset)
|
||||
{
|
||||
if (_currentTailsBackup.IsCreated)
|
||||
{
|
||||
NativeArray<Vector3>.Copy(_currentTailsBackup, 0, currentTails, offset, Logics.Length);
|
||||
NativeArray<Vector3>.Copy(_nextTailsBackup, 0, nextTails, offset, Logics.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
var end = offset + Logics.Length;
|
||||
for (int i = offset; i < end; ++i)
|
||||
{
|
||||
// mark velocity zero
|
||||
currentTails.GetSubArray(offset, Logics.Length).AsSpan().Fill(new Vector3(float.NaN, float.NaN, float.NaN));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (IsDisposed) return;
|
||||
IsDisposed = true;
|
||||
Springs.Dispose();
|
||||
Joints.Dispose();
|
||||
BlittableTransforms.Dispose();
|
||||
Colliders.Dispose();
|
||||
Logics.Dispose();
|
||||
if (Springs.IsCreated) Springs.Dispose();
|
||||
if (Joints.IsCreated) Joints.Dispose();
|
||||
if (Colliders.IsCreated) Colliders.Dispose();
|
||||
if (Logics.IsCreated) Logics.Dispose();
|
||||
if (_currentTailsBackup.IsCreated) _currentTailsBackup.Dispose();
|
||||
if (_nextTailsBackup.IsCreated) _nextTailsBackup.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniGLTF;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
|
@ -9,6 +12,7 @@ namespace VRM
|
|||
{
|
||||
private VRMSpringBone m_target;
|
||||
|
||||
private SerializedProperty m_script;
|
||||
private SerializedProperty m_commentProp;
|
||||
private SerializedProperty m_gizmoColorProp;
|
||||
private SerializedProperty m_stiffnessForceProp;
|
||||
|
|
@ -29,6 +33,7 @@ namespace VRM
|
|||
}
|
||||
m_target = (VRMSpringBone)target;
|
||||
|
||||
m_script = serializedObject.FindProperty("m_Script");
|
||||
m_commentProp = serializedObject.FindProperty(nameof(VRMSpringBone.m_comment));
|
||||
m_gizmoColorProp = serializedObject.FindProperty("m_gizmoColor");
|
||||
m_stiffnessForceProp = serializedObject.FindProperty(nameof(VRMSpringBone.m_stiffnessForce));
|
||||
|
|
@ -42,32 +47,54 @@ namespace VRM
|
|||
m_updateTypeProp = serializedObject.FindProperty(nameof(VRMSpringBone.m_updateType));
|
||||
}
|
||||
|
||||
public void OnSceneGUI()
|
||||
{
|
||||
foreach (var valiation in m_target.Validations)
|
||||
{
|
||||
var t = (Transform)valiation.Context.Context;
|
||||
if (t != null)
|
||||
{
|
||||
Handles.Label(t.position, "duplicate rootBone !");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
// header
|
||||
using (new EditorGUI.DisabledScope(true))
|
||||
{
|
||||
EditorGUILayout.PropertyField(m_script);
|
||||
}
|
||||
EditorGUILayout.PropertyField(m_commentProp);
|
||||
EditorGUILayout.PropertyField(m_gizmoColorProp);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
foreach (var validation in m_target.Validations)
|
||||
{
|
||||
validation.DrawGUI();
|
||||
}
|
||||
|
||||
// settings
|
||||
EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel);
|
||||
|
||||
LimitBreakSlider(m_stiffnessForceProp, 0.0f, 4.0f, 0.0f, Mathf.Infinity);
|
||||
LimitBreakSlider(m_gravityPowerProp, 0.0f, 2.0f, 0.0f, Mathf.Infinity);
|
||||
EditorGUILayout.PropertyField(m_gravityDirProp);
|
||||
EditorGUILayout.PropertyField(m_dragForceProp);
|
||||
EditorGUILayout.PropertyField(m_centerProp);
|
||||
EditorGUILayout.PropertyField(m_rootBonesProp);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// collision
|
||||
EditorGUILayout.LabelField("Collision", EditorStyles.boldLabel);
|
||||
|
||||
LimitBreakSlider(m_hitRadiusProp, 0.0f, 0.5f, 0.0f, Mathf.Infinity);
|
||||
EditorGUILayout.PropertyField(m_colliderGroupsProp);
|
||||
EditorGUILayout.PropertyField(m_updateTypeProp);
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// runtime
|
||||
EditorGUILayout.LabelField("Runtime", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(m_updateTypeProp);
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniGLTF;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRM
|
||||
|
|
@ -47,15 +49,52 @@ namespace VRM
|
|||
}
|
||||
[SerializeField] public SpringBoneUpdateType m_updateType = SpringBoneUpdateType.LateUpdate;
|
||||
|
||||
List<Transform> m_rootBonesNonNullUnique = new();
|
||||
List<Transform> RootBonesNonNullUnique
|
||||
{
|
||||
get
|
||||
{
|
||||
m_rootBonesNonNullUnique.Clear();
|
||||
m_rootBonesNonNullUnique.AddRange(RootBones.Where(x => x != null).Distinct());
|
||||
return m_rootBonesNonNullUnique;
|
||||
}
|
||||
}
|
||||
SpringBone.SpringBoneSystem m_system = new();
|
||||
|
||||
Dictionary<Transform, int> m_rootCount = new();
|
||||
List<Validation> m_validations = new();
|
||||
public List<Validation> Validations => m_validations;
|
||||
public void OnValidate()
|
||||
{
|
||||
Validations.Clear();
|
||||
m_rootCount.Clear();
|
||||
foreach (var root in RootBones)
|
||||
{
|
||||
if (m_rootCount.TryGetValue(root, out var count))
|
||||
{
|
||||
m_rootCount[root] = count + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rootCount.Add(root, 1);
|
||||
}
|
||||
}
|
||||
foreach (var (k, v) in m_rootCount)
|
||||
{
|
||||
if (v > 1)
|
||||
{
|
||||
Validations.Add(Validation.Error($"Duplicate rootBone: {k} => {v}", ValidationContext.Create(k)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
Setup();
|
||||
}
|
||||
|
||||
SpringBone.SceneInfo Scene => new(
|
||||
rootBones: RootBones,
|
||||
rootBones: RootBonesNonNullUnique,
|
||||
center: m_center,
|
||||
colliderGroups: ColliderGroups,
|
||||
externalForce: ExternalForce);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ namespace UniVRM10
|
|||
if (fastSpringBoneBuffer != null)
|
||||
{
|
||||
fastSpringBoneBuffer.Dispose();
|
||||
fastSpringBoneBuffer = null;
|
||||
}
|
||||
|
||||
Func<Transform, TransformState> GetOrAddDefaultTransformState = (Transform tf) =>
|
||||
|
|
@ -41,7 +42,7 @@ namespace UniVRM10
|
|||
|
||||
// create(Spring情報の再収集。設定変更の反映)
|
||||
var springs = vrm.SpringBone.Springs.Select(spring => new FastSpringBoneSpring
|
||||
{
|
||||
{
|
||||
center = spring.Center,
|
||||
colliders = spring.ColliderGroups
|
||||
.SelectMany(group => group.Colliders)
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ MonoBehaviour:
|
|||
m_Script: {fileID: 11500000, guid: bf2edee5c58d82540a51f03df9d42094, type: 3}
|
||||
m_Name: UniversalRenderPipelineAsset
|
||||
m_EditorClassIdentifier:
|
||||
k_AssetVersion: 9
|
||||
k_AssetPreviousVersion: 9
|
||||
k_AssetVersion: 11
|
||||
k_AssetPreviousVersion: 11
|
||||
m_RendererType: 1
|
||||
m_RendererData: {fileID: 0}
|
||||
m_RendererDataList:
|
||||
|
|
@ -23,13 +23,16 @@ MonoBehaviour:
|
|||
m_RequireOpaqueTexture: 0
|
||||
m_OpaqueDownsampling: 1
|
||||
m_SupportsTerrainHoles: 1
|
||||
m_StoreActionsOptimization: 0
|
||||
m_SupportsHDR: 1
|
||||
m_HDRColorBufferPrecision: 0
|
||||
m_MSAA: 4
|
||||
m_RenderScale: 1
|
||||
m_UpscalingFilter: 0
|
||||
m_FsrOverrideSharpness: 0
|
||||
m_FsrSharpness: 0.92
|
||||
m_EnableLODCrossFade: 1
|
||||
m_LODCrossFadeDitheringType: 1
|
||||
m_ShEvalMode: 0
|
||||
m_MainLightRenderingMode: 1
|
||||
m_MainLightShadowsSupported: 1
|
||||
m_MainLightShadowmapResolution: 2048
|
||||
|
|
@ -54,22 +57,58 @@ MonoBehaviour:
|
|||
m_SoftShadowsSupported: 1
|
||||
m_ConservativeEnclosingSphere: 0
|
||||
m_NumIterationsEnclosingSphere: 64
|
||||
m_SoftShadowQuality: 2
|
||||
m_AdditionalLightsCookieResolution: 2048
|
||||
m_AdditionalLightsCookieFormat: 3
|
||||
m_UseSRPBatcher: 1
|
||||
m_SupportsDynamicBatching: 0
|
||||
m_MixedLightingSupported: 1
|
||||
m_SupportsLightCookies: 1
|
||||
m_SupportsLightLayers: 0
|
||||
m_DebugLevel: 0
|
||||
m_StoreActionsOptimization: 0
|
||||
m_EnableRenderGraph: 0
|
||||
m_UseAdaptivePerformance: 1
|
||||
m_ColorGradingMode: 0
|
||||
m_ColorGradingLutSize: 32
|
||||
m_UseFastSRGBLinearConversion: 0
|
||||
m_SupportDataDrivenLensFlare: 1
|
||||
m_ShadowType: 1
|
||||
m_LocalShadowsSupported: 0
|
||||
m_LocalShadowsAtlasResolution: 256
|
||||
m_MaxPixelLights: 0
|
||||
m_ShadowAtlasResolution: 256
|
||||
m_ShaderVariantLogLevel: 0
|
||||
m_VolumeFrameworkUpdateMode: 0
|
||||
m_Textures:
|
||||
blueNoise64LTex: {fileID: 2800000, guid: e3d24661c1e055f45a7560c033dbb837, type: 3}
|
||||
bayerMatrixTex: {fileID: 2800000, guid: f9ee4ed84c1d10c49aabb9b210b0fc44, type: 3}
|
||||
m_PrefilteringModeMainLightShadows: 1
|
||||
m_PrefilteringModeAdditionalLight: 4
|
||||
m_PrefilteringModeAdditionalLightShadows: 1
|
||||
m_PrefilterXRKeywords: 0
|
||||
m_PrefilteringModeForwardPlus: 1
|
||||
m_PrefilteringModeDeferredRendering: 1
|
||||
m_PrefilteringModeScreenSpaceOcclusion: 1
|
||||
m_PrefilterDebugKeywords: 0
|
||||
m_PrefilterWriteRenderingLayers: 0
|
||||
m_PrefilterHDROutput: 0
|
||||
m_PrefilterSSAODepthNormals: 0
|
||||
m_PrefilterSSAOSourceDepthLow: 0
|
||||
m_PrefilterSSAOSourceDepthMedium: 0
|
||||
m_PrefilterSSAOSourceDepthHigh: 0
|
||||
m_PrefilterSSAOInterleaved: 0
|
||||
m_PrefilterSSAOBlueNoise: 0
|
||||
m_PrefilterSSAOSampleCountLow: 0
|
||||
m_PrefilterSSAOSampleCountMedium: 0
|
||||
m_PrefilterSSAOSampleCountHigh: 0
|
||||
m_PrefilterDBufferMRT1: 0
|
||||
m_PrefilterDBufferMRT2: 0
|
||||
m_PrefilterDBufferMRT3: 0
|
||||
m_PrefilterSoftShadowsQualityLow: 0
|
||||
m_PrefilterSoftShadowsQualityMedium: 0
|
||||
m_PrefilterSoftShadowsQualityHigh: 0
|
||||
m_PrefilterSoftShadows: 0
|
||||
m_PrefilterScreenCoord: 0
|
||||
m_PrefilterNativeRenderPass: 0
|
||||
m_ShaderVariantLogLevel: 0
|
||||
m_ShadowCascades: 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user