mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-13 22:09:53 -05:00
Merge pull request #2363 from ousttrue/feature/springbone_pause
add BlittableExternalData.Paused
This commit is contained in:
commit
4e7bd4b4af
|
|
@ -1,11 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniGLTF;
|
||||
using UniGLTF.Utils;
|
||||
using UnityEngine;
|
||||
using UniVRM10.FastSpringBones.Blittables;
|
||||
using UniVRM10.FastSpringBones.System;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
|
|
@ -23,11 +17,6 @@ namespace UniVRM10
|
|||
{
|
||||
private readonly Vrm10Instance m_instance;
|
||||
private readonly Transform m_head;
|
||||
private readonly FastSpringBoneService m_fastSpringBoneService;
|
||||
private readonly IReadOnlyDictionary<Transform, TransformState> m_defaultTransformStates;
|
||||
|
||||
private FastSpringBoneBuffer m_fastSpringBoneBuffer;
|
||||
private BlittableExternalData m_externalData;
|
||||
|
||||
/// <summary>
|
||||
/// Control Rig may be null.
|
||||
|
|
@ -38,17 +27,14 @@ namespace UniVRM10
|
|||
public IVrm10Constraint[] Constraints { get; }
|
||||
public Vrm10RuntimeExpression Expression { get; }
|
||||
public Vrm10RuntimeLookAt LookAt { get; }
|
||||
|
||||
public Vrm10RuntimeSpringBone SpringBone { get; }
|
||||
public IVrm10Animation VrmAnimation { get; set; }
|
||||
|
||||
[Obsolete("use Vrm10Runtime.SpringBone.ExternalForce")]
|
||||
public Vector3 ExternalForce
|
||||
{
|
||||
get => m_externalData.ExternalForce;
|
||||
set
|
||||
{
|
||||
m_externalData.ExternalForce = value;
|
||||
m_fastSpringBoneBuffer.ExternalData = m_externalData;
|
||||
}
|
||||
get { return SpringBone.ExternalForce; }
|
||||
set { SpringBone.ExternalForce = value; }
|
||||
}
|
||||
|
||||
public Vrm10Runtime(Vrm10Instance instance, bool useControlRig)
|
||||
|
|
@ -72,117 +58,20 @@ namespace UniVRM10
|
|||
Constraints = instance.GetComponentsInChildren<IVrm10Constraint>();
|
||||
LookAt = new Vrm10RuntimeLookAt(instance.Vrm.LookAt, instance.Humanoid, ControlRig);
|
||||
Expression = new Vrm10RuntimeExpression(instance, LookAt.EyeDirectionApplicable);
|
||||
|
||||
var gltfInstance = instance.GetComponent<RuntimeGltfInstance>();
|
||||
if (gltfInstance != null)
|
||||
{
|
||||
// ランタイムインポートならここに到達してゼロコストになる
|
||||
m_defaultTransformStates = gltfInstance.InitialTransformStates;
|
||||
}
|
||||
else
|
||||
{
|
||||
// エディタでプレハブ配置してる奴ならこっちに到達して収集する
|
||||
m_defaultTransformStates = instance.GetComponentsInChildren<Transform>()
|
||||
.ToDictionary(tf => tf, tf => new TransformState(tf));
|
||||
}
|
||||
|
||||
// NOTE: FastSpringBoneService は UnitTest などでは動作しない
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
m_fastSpringBoneService = FastSpringBoneService.Instance;
|
||||
m_fastSpringBoneBuffer = CreateFastSpringBoneBuffer(m_instance.SpringBone);
|
||||
m_fastSpringBoneService.BufferCombiner.Register(m_fastSpringBoneBuffer);
|
||||
}
|
||||
SpringBone = new Vrm10RuntimeSpringBone(instance);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ControlRig?.Dispose();
|
||||
m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer);
|
||||
m_fastSpringBoneBuffer.Dispose();
|
||||
SpringBone.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// このVRMに紐づくSpringBone関連のバッファを再構築する
|
||||
/// ランタイム実行時にSpringBoneに対して変更を行いたいときは、このメソッドを明示的に呼ぶ必要がある
|
||||
/// </summary>
|
||||
[Obsolete("use Vrm10Runtime.SpringBone.ReconstructSpringBone")]
|
||||
public void ReconstructSpringBone()
|
||||
{
|
||||
m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer);
|
||||
|
||||
m_fastSpringBoneBuffer.Dispose();
|
||||
m_fastSpringBoneBuffer = CreateFastSpringBoneBuffer(m_instance.SpringBone);
|
||||
|
||||
m_fastSpringBoneService.BufferCombiner.Register(m_fastSpringBoneBuffer);
|
||||
SpringBone.ReconstructSpringBone();
|
||||
}
|
||||
|
||||
private FastSpringBoneBuffer CreateFastSpringBoneBuffer(Vrm10InstanceSpringBone springBone)
|
||||
{
|
||||
return new FastSpringBoneBuffer(
|
||||
springBone.Springs.Select(spring => new FastSpringBoneSpring
|
||||
{
|
||||
center = spring.Center,
|
||||
colliders = spring.ColliderGroups
|
||||
.SelectMany(group => group.Colliders)
|
||||
.Select(collider => new FastSpringBoneCollider
|
||||
{
|
||||
Transform = collider.transform,
|
||||
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 BlittableJoint
|
||||
{
|
||||
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(),
|
||||
m_externalData);
|
||||
}
|
||||
|
||||
private TransformState GetOrAddDefaultTransformState(Transform tf)
|
||||
{
|
||||
if (m_defaultTransformStates.TryGetValue(tf, out var defaultTransformState))
|
||||
{
|
||||
return defaultTransformState;
|
||||
}
|
||||
|
||||
Debug.LogWarning($"{tf.name} does not exist on load.");
|
||||
return new TransformState(null);
|
||||
}
|
||||
|
||||
private static BlittableColliderType TranslateColliderType(VRM10SpringBoneColliderTypes colliderType)
|
||||
{
|
||||
switch (colliderType)
|
||||
{
|
||||
case VRM10SpringBoneColliderTypes.Sphere:
|
||||
return BlittableColliderType.Sphere;
|
||||
case VRM10SpringBoneColliderTypes.Capsule:
|
||||
return BlittableColliderType.Capsule;
|
||||
case VRM10SpringBoneColliderTypes.Plane:
|
||||
return BlittableColliderType.Plane;
|
||||
case VRM10SpringBoneColliderTypes.SphereInside:
|
||||
return BlittableColliderType.SphereInside;
|
||||
case VRM10SpringBoneColliderTypes.CapsuleInside:
|
||||
return BlittableColliderType.CapsuleInside;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 毎フレーム関連コンポーネントを解決する
|
||||
///
|
||||
|
|
@ -241,4 +130,4 @@ namespace UniVRM10
|
|||
Expression.Process(eyeDirection);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniGLTF;
|
||||
using UniGLTF.Utils;
|
||||
using UnityEngine;
|
||||
using UniVRM10.FastSpringBones.Blittables;
|
||||
using UniVRM10.FastSpringBones.System;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public class Vrm10RuntimeSpringBone : IDisposable
|
||||
{
|
||||
private readonly Vrm10Instance m_instance;
|
||||
private readonly IReadOnlyDictionary<Transform, TransformState> m_defaultTransformStates;
|
||||
private readonly FastSpringBoneService m_fastSpringBoneService;
|
||||
private FastSpringBoneSpring[] m_springs;
|
||||
private Quaternion[] m_initialLocalRotations;
|
||||
private FastSpringBoneBuffer m_fastSpringBoneBuffer;
|
||||
public Vector3 ExternalForce
|
||||
{
|
||||
get => m_fastSpringBoneBuffer.ExternalForce;
|
||||
set => m_fastSpringBoneBuffer.ExternalForce = value;
|
||||
}
|
||||
public bool IsSpringBoneEnabled
|
||||
{
|
||||
get => m_fastSpringBoneBuffer.IsSpringBoneEnabled;
|
||||
set => m_fastSpringBoneBuffer.IsSpringBoneEnabled = value;
|
||||
}
|
||||
|
||||
internal Vrm10RuntimeSpringBone(Vrm10Instance instance)
|
||||
{
|
||||
m_instance = instance;
|
||||
|
||||
var gltfInstance = instance.GetComponent<RuntimeGltfInstance>();
|
||||
if (gltfInstance != null)
|
||||
{
|
||||
// ランタイムインポートならここに到達してゼロコストになる
|
||||
m_defaultTransformStates = gltfInstance.InitialTransformStates;
|
||||
}
|
||||
else
|
||||
{
|
||||
// エディタでプレハブ配置してる奴ならこっちに到達して収集する
|
||||
m_defaultTransformStates = instance.GetComponentsInChildren<Transform>()
|
||||
.ToDictionary(tf => tf, tf => new TransformState(tf));
|
||||
}
|
||||
|
||||
// NOTE: FastSpringBoneService は UnitTest などでは動作しない
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
m_fastSpringBoneService = FastSpringBoneService.Instance;
|
||||
ReconstructSpringBone();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer);
|
||||
m_fastSpringBoneBuffer.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// このVRMに紐づくSpringBone関連のバッファを再構築する
|
||||
/// ランタイム実行時にSpringBoneに対して変更を行いたいときは、このメソッドを明示的に呼ぶ必要がある
|
||||
/// </summary>
|
||||
public void ReconstructSpringBone()
|
||||
{
|
||||
// rerelase
|
||||
if (m_fastSpringBoneBuffer != null)
|
||||
{
|
||||
m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer);
|
||||
m_fastSpringBoneBuffer.Dispose();
|
||||
}
|
||||
|
||||
// create(Spring情報の再収集。設定変更の反映)
|
||||
m_springs = m_instance.SpringBone.Springs.Select(spring => new FastSpringBoneSpring
|
||||
{
|
||||
center = spring.Center,
|
||||
colliders = spring.ColliderGroups
|
||||
.SelectMany(group => group.Colliders)
|
||||
.Select(collider => new FastSpringBoneCollider
|
||||
{
|
||||
Transform = collider.transform,
|
||||
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 BlittableJoint
|
||||
{
|
||||
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();
|
||||
|
||||
// DOTS buffer 構築
|
||||
m_fastSpringBoneBuffer = new FastSpringBoneBuffer(m_springs);
|
||||
m_fastSpringBoneService.BufferCombiner.Register(m_fastSpringBoneBuffer);
|
||||
// reset 用の初期状態の記録
|
||||
m_initialLocalRotations = m_fastSpringBoneBuffer.Transforms.Select(x => x.localRotation).ToArray();
|
||||
}
|
||||
|
||||
private TransformState GetOrAddDefaultTransformState(Transform tf)
|
||||
{
|
||||
if (m_defaultTransformStates.TryGetValue(tf, out var defaultTransformState))
|
||||
{
|
||||
return defaultTransformState;
|
||||
}
|
||||
|
||||
Debug.LogWarning($"{tf.name} does not exist on load.");
|
||||
return new TransformState(null);
|
||||
}
|
||||
|
||||
private static BlittableColliderType TranslateColliderType(VRM10SpringBoneColliderTypes colliderType)
|
||||
{
|
||||
switch (colliderType)
|
||||
{
|
||||
case VRM10SpringBoneColliderTypes.Sphere:
|
||||
return BlittableColliderType.Sphere;
|
||||
case VRM10SpringBoneColliderTypes.Capsule:
|
||||
return BlittableColliderType.Capsule;
|
||||
case VRM10SpringBoneColliderTypes.Plane:
|
||||
return BlittableColliderType.Plane;
|
||||
case VRM10SpringBoneColliderTypes.SphereInside:
|
||||
return BlittableColliderType.SphereInside;
|
||||
case VRM10SpringBoneColliderTypes.CapsuleInside:
|
||||
return BlittableColliderType.CapsuleInside;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void RestoreInitialTransform()
|
||||
{
|
||||
// Spring の joint に対応する transform の回転を初期状態
|
||||
for (int i = 0; i < m_fastSpringBoneBuffer.Transforms.Length; ++i)
|
||||
{
|
||||
var transform = m_fastSpringBoneBuffer.Transforms[i];
|
||||
transform.localRotation = m_initialLocalRotations[i];
|
||||
}
|
||||
|
||||
// 初期状態にしたtransformを使って spring logic を構築
|
||||
List<BlittableLogic> blittableLogics = new();
|
||||
foreach (var spring in m_springs)
|
||||
{
|
||||
blittableLogics.AddRange(
|
||||
FastSpringBoneBuffer.LogicFromTransform(m_fastSpringBoneBuffer.Transforms, spring));
|
||||
}
|
||||
// DOTS バッファーを更新
|
||||
m_fastSpringBoneBuffer.SyncAndZeroVelocity(blittableLogics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2f3312577381e824eac9514c892e3cbc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -8,5 +8,10 @@ namespace UniVRM10.FastSpringBones.Blittables
|
|||
public struct BlittableExternalData
|
||||
{
|
||||
public Vector3 ExternalForce;
|
||||
|
||||
/// <summary>
|
||||
/// if false, spring bone is paused.
|
||||
/// </summary>
|
||||
public bool IsSpringBoneEnabled;
|
||||
}
|
||||
}
|
||||
|
|
@ -26,24 +26,39 @@ namespace UniVRM10.FastSpringBones.System
|
|||
// NOTE: これは更新頻度が高くバッチングが難しいため、ランダムアクセスを許容してメモリへ直接アクセスする
|
||||
// 生のヒープ領域は扱いにくいので長さ1のNativeArrayで代用
|
||||
private NativeArray<BlittableExternalData> _externalData;
|
||||
|
||||
public BlittableExternalData ExternalData
|
||||
public Vector3 ExternalForce
|
||||
{
|
||||
get => _externalData[0];
|
||||
set => _externalData[0] = value;
|
||||
get => _externalData[0].ExternalForce;
|
||||
set
|
||||
{
|
||||
_externalData[0] = new BlittableExternalData
|
||||
{
|
||||
ExternalForce = value,
|
||||
IsSpringBoneEnabled = _externalData[0].IsSpringBoneEnabled,
|
||||
};
|
||||
}
|
||||
}
|
||||
public bool IsSpringBoneEnabled
|
||||
{
|
||||
get => _externalData[0].IsSpringBoneEnabled;
|
||||
set
|
||||
{
|
||||
_externalData[0] = new BlittableExternalData
|
||||
{
|
||||
ExternalForce = _externalData[0].ExternalForce,
|
||||
IsSpringBoneEnabled = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe FastSpringBoneBuffer(IReadOnlyList<FastSpringBoneSpring> springs,
|
||||
BlittableExternalData externalData,
|
||||
bool simulateLastBone = false)
|
||||
/// <summary>
|
||||
/// Joint, Collider, Center の Transform のリスト
|
||||
/// - 重複を除去
|
||||
/// </summary>
|
||||
/// <param name="springs"></param>
|
||||
/// <returns></returns>
|
||||
static Transform[] MakeFlattenTransformList(FastSpringBoneSpring[] springs)
|
||||
{
|
||||
Profiler.BeginSample("FastSpringBone.ConstructBuffers");
|
||||
|
||||
_externalData = new NativeArray<BlittableExternalData>(1, Allocator.Persistent);
|
||||
ExternalData = externalData;
|
||||
|
||||
// Transformの列挙
|
||||
Profiler.BeginSample("FastSpringBone.ConstructBuffers.ConstructTransformBuffer");
|
||||
var transformHashSet = new HashSet<Transform>();
|
||||
foreach (var spring in springs)
|
||||
{
|
||||
|
|
@ -60,19 +75,26 @@ namespace UniVRM10.FastSpringBones.System
|
|||
|
||||
if (spring.center != null) transformHashSet.Add(spring.center);
|
||||
}
|
||||
var Transforms = transformHashSet.ToArray();
|
||||
return Transforms;
|
||||
}
|
||||
|
||||
var transforms = transformHashSet.ToArray();
|
||||
var transformIndexDictionary = transforms.Select((trs, index) => (trs, index))
|
||||
.ToDictionary(tuple => tuple.trs, tuple => tuple.index);
|
||||
Profiler.EndSample();
|
||||
|
||||
// 各種bufferの構築
|
||||
Profiler.BeginSample("FastSpringBone.ConstructBuffers.ConstructBuffers");
|
||||
var blittableColliders = new List<BlittableCollider>();
|
||||
var blittableJoints = new List<BlittableJoint>();
|
||||
var blittableSprings = new List<BlittableSpring>();
|
||||
var blittableLogics = new List<BlittableLogic>();
|
||||
public unsafe FastSpringBoneBuffer(FastSpringBoneSpring[] springs)
|
||||
{
|
||||
Profiler.BeginSample("FastSpringBone.ConstructBuffers.BufferBuilder");
|
||||
Transforms = MakeFlattenTransformList(springs);
|
||||
_externalData = new NativeArray<BlittableExternalData>(1, Allocator.Persistent);
|
||||
_externalData[0] = new BlittableExternalData
|
||||
{
|
||||
ExternalForce = Vector3.zero,
|
||||
IsSpringBoneEnabled = true,
|
||||
};
|
||||
|
||||
var externalDataPtr = (BlittableExternalData*)_externalData.GetUnsafePtr();
|
||||
List<BlittableSpring> blittableSprings = new();
|
||||
List<BlittableJoint> blittableJoints = new();
|
||||
List<BlittableCollider> blittableColliders = new();
|
||||
List<BlittableLogic> blittableLogics = new();
|
||||
foreach (var spring in springs)
|
||||
{
|
||||
var blittableSpring = new BlittableSpring
|
||||
|
|
@ -85,91 +107,95 @@ namespace UniVRM10.FastSpringBones.System
|
|||
logicSpan = new BlittableSpan
|
||||
{
|
||||
startIndex = blittableJoints.Count,
|
||||
count = simulateLastBone ? spring.joints.Length : spring.joints.Length - 1,
|
||||
count = spring.joints.Length - 1,
|
||||
},
|
||||
centerTransformIndex = spring.center ? transformIndexDictionary[spring.center] : -1,
|
||||
ExternalData = (BlittableExternalData*) _externalData.GetUnsafePtr()
|
||||
centerTransformIndex = Array.IndexOf(Transforms, spring.center),
|
||||
ExternalData = externalDataPtr,
|
||||
};
|
||||
blittableSprings.Add(blittableSpring);
|
||||
|
||||
blittableColliders.AddRange(spring.colliders.Select(collider =>
|
||||
{
|
||||
var blittable = collider.Collider;
|
||||
blittable.transformIndex = transformIndexDictionary[collider.Transform];
|
||||
blittable.transformIndex = Array.IndexOf(Transforms, collider.Transform);
|
||||
return blittable;
|
||||
}));
|
||||
blittableJoints.AddRange(spring.joints
|
||||
.Take(simulateLastBone ? spring.joints.Length : spring.joints.Length - 1).Select(joint =>
|
||||
.Take(spring.joints.Length - 1).Select(joint =>
|
||||
{
|
||||
var blittable = joint.Joint;
|
||||
return blittable;
|
||||
}));
|
||||
|
||||
for (var i = 0; i < (simulateLastBone ? spring.joints.Length : spring.joints.Length - 1); ++i)
|
||||
{
|
||||
var joint = spring.joints[i];
|
||||
var tailJoint = i + 1 < spring.joints.Length ? spring.joints[i + 1] : (FastSpringBoneJoint?) null;
|
||||
var parentJoint = i - 1 >= 0 ? spring.joints[i - 1] : (FastSpringBoneJoint?) null;
|
||||
var localPosition = Vector3.zero;
|
||||
if (tailJoint.HasValue)
|
||||
{
|
||||
localPosition = tailJoint.Value.Transform.localPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parentJoint.HasValue)
|
||||
{
|
||||
var delta = joint.Transform.position - parentJoint.Value.Transform.position;
|
||||
localPosition =
|
||||
joint.Transform.worldToLocalMatrix.MultiplyPoint(joint.Transform.position + delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
localPosition = Vector3.down;
|
||||
}
|
||||
}
|
||||
|
||||
var scale = tailJoint.HasValue ? tailJoint.Value.Transform.lossyScale : joint.Transform.lossyScale;
|
||||
var localChildPosition =
|
||||
new Vector3(
|
||||
localPosition.x * scale.x,
|
||||
localPosition.y * scale.y,
|
||||
localPosition.z * scale.z
|
||||
);
|
||||
|
||||
var worldChildPosition = joint.Transform.TransformPoint(localChildPosition);
|
||||
var currentTail = spring.center != null
|
||||
? spring.center.InverseTransformPoint(worldChildPosition)
|
||||
: worldChildPosition;
|
||||
var parent = joint.Transform.parent;
|
||||
blittableLogics.Add(new BlittableLogic
|
||||
{
|
||||
headTransformIndex = transformIndexDictionary[joint.Transform],
|
||||
parentTransformIndex = parent != null ? transformIndexDictionary[parent] : -1,
|
||||
currentTail = currentTail,
|
||||
prevTail = currentTail,
|
||||
localRotation = joint.DefaultLocalRotation,
|
||||
boneAxis = localChildPosition.normalized,
|
||||
length = localChildPosition.magnitude
|
||||
});
|
||||
}
|
||||
blittableLogics.AddRange(LogicFromTransform(Transforms, spring));
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
|
||||
// 各種bufferの初期化
|
||||
Profiler.BeginSample("FastSpringBone.ConstructBuffers.ConstructNativeArrays");
|
||||
Springs = new NativeArray<BlittableSpring>(blittableSprings.ToArray(), Allocator.Persistent);
|
||||
|
||||
Joints = new NativeArray<BlittableJoint>(blittableJoints.ToArray(), Allocator.Persistent);
|
||||
Colliders = new NativeArray<BlittableCollider>(blittableColliders.ToArray(), Allocator.Persistent);
|
||||
Logics = new NativeArray<BlittableLogic>(blittableLogics.ToArray(), Allocator.Persistent);
|
||||
|
||||
BlittableTransforms = new NativeArray<BlittableTransform>(transforms.Length, Allocator.Persistent);
|
||||
Transforms = transforms.ToArray();
|
||||
BlittableTransforms = new NativeArray<BlittableTransform>(Transforms.Length, Allocator.Persistent);
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
/// <summary>
|
||||
/// Transform の現状から Logic を作成する。
|
||||
/// </summary>
|
||||
/// <param name="Transforms"></param>
|
||||
/// <param name="spring"></param>
|
||||
/// <param name="i">joint index</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<BlittableLogic> LogicFromTransform(Transform[] Transforms, FastSpringBoneSpring spring)
|
||||
{
|
||||
// vrm-1.0 では末端の joint は tail で処理対象でないのに注意!
|
||||
for (int i = 0; i < spring.joints.Length - 1; ++i)
|
||||
{
|
||||
var joint = spring.joints[i];
|
||||
var tailJoint = i + 1 < spring.joints.Length ? spring.joints[i + 1] : (FastSpringBoneJoint?)null;
|
||||
var parentJoint = i - 1 >= 0 ? spring.joints[i - 1] : (FastSpringBoneJoint?)null;
|
||||
var localPosition = Vector3.zero;
|
||||
if (tailJoint.HasValue)
|
||||
{
|
||||
localPosition = tailJoint.Value.Transform.localPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parentJoint.HasValue)
|
||||
{
|
||||
var delta = joint.Transform.position - parentJoint.Value.Transform.position;
|
||||
localPosition =
|
||||
joint.Transform.worldToLocalMatrix.MultiplyPoint(joint.Transform.position + delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
localPosition = Vector3.down;
|
||||
}
|
||||
}
|
||||
|
||||
var scale = tailJoint.HasValue ? tailJoint.Value.Transform.lossyScale : joint.Transform.lossyScale;
|
||||
var localChildPosition = new Vector3(
|
||||
localPosition.x * scale.x,
|
||||
localPosition.y * scale.y,
|
||||
localPosition.z * scale.z
|
||||
);
|
||||
|
||||
var worldChildPosition = joint.Transform.TransformPoint(localChildPosition);
|
||||
var currentTail = spring.center != null
|
||||
? spring.center.InverseTransformPoint(worldChildPosition)
|
||||
: worldChildPosition;
|
||||
var parent = joint.Transform.parent;
|
||||
|
||||
yield return new BlittableLogic
|
||||
{
|
||||
headTransformIndex = Array.IndexOf(Transforms, joint.Transform),
|
||||
parentTransformIndex = Array.IndexOf(Transforms, parent),
|
||||
currentTail = currentTail,
|
||||
prevTail = currentTail, // same with currentTail. velocity zero.
|
||||
localRotation = joint.DefaultLocalRotation,
|
||||
boneAxis = localChildPosition.normalized,
|
||||
length = localChildPosition.magnitude
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
@ -183,5 +209,16 @@ namespace UniVRM10.FastSpringBones.System
|
|||
Logics.Dispose();
|
||||
_externalData.Dispose();
|
||||
}
|
||||
|
||||
public void SyncAndZeroVelocity(IReadOnlyList<BlittableLogic> logics)
|
||||
{
|
||||
var dst = Logics;
|
||||
for (int i = 0; i < logics.Count; ++i)
|
||||
{
|
||||
var l = logics[i];
|
||||
l.prevTail = l.currentTail;
|
||||
dst[i] = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -147,8 +147,16 @@ namespace UniVRM10.FastSpringBones.System
|
|||
headTransform.localRotation = headTransform.rotation;
|
||||
}
|
||||
|
||||
// 値をバッファに戻す
|
||||
Transforms[logic.headTransformIndex + transformIndexOffset] = headTransform;
|
||||
if (spring.ExternalData->IsSpringBoneEnabled)
|
||||
{
|
||||
// SpringBone の結果を Transform に反映する
|
||||
Transforms[logic.headTransformIndex + transformIndexOffset] = headTransform;
|
||||
}
|
||||
else
|
||||
{
|
||||
// SpringBone の結果を Transform に反映しないが logic の更新は継続する。
|
||||
// 再開したときに暴れない。
|
||||
}
|
||||
Logics[logicIndex] = logic;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using UniGLTF;
|
||||
using UniGLTF.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10.VRM10Viewer
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ RectTransform:
|
|||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 14
|
||||
m_RootOrder: 16
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -773,7 +773,7 @@ RectTransform:
|
|||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 4
|
||||
m_RootOrder: 3
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -1236,13 +1236,15 @@ RectTransform:
|
|||
- {fileID: 1621794411}
|
||||
- {fileID: 2009818432}
|
||||
- {fileID: 168425995}
|
||||
- {fileID: 1307084561}
|
||||
- {fileID: 224350191}
|
||||
- {fileID: 1791103379}
|
||||
- {fileID: 1311520909}
|
||||
- {fileID: 1557052150}
|
||||
- {fileID: 1767706907}
|
||||
- {fileID: 1307084561}
|
||||
- {fileID: 974864191}
|
||||
- {fileID: 1767706907}
|
||||
- {fileID: 1557052150}
|
||||
- {fileID: 1728528388}
|
||||
- {fileID: 704896193}
|
||||
- {fileID: 597950322}
|
||||
- {fileID: 935566651}
|
||||
- {fileID: 634488421}
|
||||
|
|
@ -1822,7 +1824,7 @@ RectTransform:
|
|||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 10
|
||||
m_RootOrder: 12
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -1903,7 +1905,7 @@ RectTransform:
|
|||
- {fileID: 154330168}
|
||||
- {fileID: 1954133885}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 16
|
||||
m_RootOrder: 18
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -1990,7 +1992,7 @@ RectTransform:
|
|||
- {fileID: 2010083454}
|
||||
- {fileID: 1081455630}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 12
|
||||
m_RootOrder: 14
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -2246,6 +2248,128 @@ MonoBehaviour:
|
|||
m_ChildScaleWidth: 0
|
||||
m_ChildScaleHeight: 0
|
||||
m_ReverseArrangement: 0
|
||||
--- !u!1 &704896192
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 704896193}
|
||||
- component: {fileID: 704896196}
|
||||
- component: {fileID: 704896195}
|
||||
- component: {fileID: 704896194}
|
||||
m_Layer: 5
|
||||
m_Name: ResetSpringBone
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &704896193
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 704896192}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 983782643}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 11
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 162, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &704896194
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 704896192}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Highlighted
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 704896195}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!114 &704896195
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 704896192}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!222 &704896196
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 704896192}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &773923918
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
@ -3397,7 +3521,7 @@ RectTransform:
|
|||
- {fileID: 175751363}
|
||||
- {fileID: 1904789319}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 11
|
||||
m_RootOrder: 13
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -3435,7 +3559,7 @@ RectTransform:
|
|||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 9
|
||||
m_RootOrder: 7
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -3484,6 +3608,88 @@ CanvasRenderer:
|
|||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 974864190}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &983782642
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 983782643}
|
||||
- component: {fileID: 983782645}
|
||||
- component: {fileID: 983782644}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &983782643
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 983782642}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 704896193}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &983782644
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 983782642}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: 'ResetSpring
|
||||
|
||||
'
|
||||
--- !u!222 &983782645
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 983782642}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &1007924635
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
@ -4600,6 +4806,86 @@ CanvasRenderer:
|
|||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1242458542}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &1258907230
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1258907231}
|
||||
- component: {fileID: 1258907233}
|
||||
- component: {fileID: 1258907232}
|
||||
m_Layer: 5
|
||||
m_Name: Label
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1258907231
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1258907230}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1728528388}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 9, y: -0.5}
|
||||
m_SizeDelta: {x: -28, y: -3}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1258907232
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1258907230}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 0
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: PauseSpringBone
|
||||
--- !u!222 &1258907233
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1258907230}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &1268276254
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
@ -4869,7 +5155,7 @@ RectTransform:
|
|||
m_Children:
|
||||
- {fileID: 910859648}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 3
|
||||
m_RootOrder: 6
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -5066,7 +5352,7 @@ RectTransform:
|
|||
- {fileID: 1866921958}
|
||||
- {fileID: 1767669911}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 6
|
||||
m_RootOrder: 5
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -5363,7 +5649,7 @@ RectTransform:
|
|||
- {fileID: 452923209}
|
||||
- {fileID: 2090837017}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 15
|
||||
m_RootOrder: 17
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -5498,6 +5784,83 @@ CanvasRenderer:
|
|||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1476033060}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &1519258557
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1519258558}
|
||||
- component: {fileID: 1519258560}
|
||||
- component: {fileID: 1519258559}
|
||||
m_Layer: 5
|
||||
m_Name: Background
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1519258558
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1519258557}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 2055567529}
|
||||
m_Father: {fileID: 1728528388}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 10, y: -10}
|
||||
m_SizeDelta: {x: 20, y: 20}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1519258559
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1519258557}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!222 &1519258560
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1519258557}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &1557052149
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
@ -5510,7 +5873,7 @@ GameObject:
|
|||
- component: {fileID: 1557052152}
|
||||
- component: {fileID: 1557052151}
|
||||
m_Layer: 5
|
||||
m_Name: _
|
||||
m_Name: _SpringBone_
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
|
|
@ -5529,7 +5892,7 @@ RectTransform:
|
|||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 7
|
||||
m_RootOrder: 9
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -5569,7 +5932,7 @@ MonoBehaviour:
|
|||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text:
|
||||
m_Text: SpringBone
|
||||
--- !u!222 &1557052152
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
@ -5920,6 +6283,93 @@ CanvasRenderer:
|
|||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1636340563}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &1728528387
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1728528388}
|
||||
- component: {fileID: 1728528389}
|
||||
m_Layer: 5
|
||||
m_Name: PauseSpringBone
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1728528388
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1728528387}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 1519258558}
|
||||
- {fileID: 1258907231}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 10
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 160, y: 20}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1728528389
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1728528387}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 1519258559}
|
||||
toggleTransition: 1
|
||||
graphic: {fileID: 2055567530}
|
||||
m_Group: {fileID: 0}
|
||||
onValueChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_IsOn: 0
|
||||
--- !u!1 &1761414315
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
@ -6199,7 +6649,7 @@ RectTransform:
|
|||
- {fileID: 62367395}
|
||||
- {fileID: 1037763549}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 13
|
||||
m_RootOrder: 15
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -6373,6 +6823,8 @@ MonoBehaviour:
|
|||
m_openMotion: {fileID: 168425996}
|
||||
m_pastePose: {fileID: 1307084564}
|
||||
m_showBoxMan: {fileID: 1767706908}
|
||||
m_pauseSpringBone: {fileID: 1728528389}
|
||||
m_resetSpringBone: {fileID: 704896194}
|
||||
m_enableLipSync: {fileID: 935566650}
|
||||
m_enableAutoBlink: {fileID: 634488422}
|
||||
m_enableAutoExpression: {fileID: 1767738855}
|
||||
|
|
@ -6431,7 +6883,7 @@ RectTransform:
|
|||
- {fileID: 1166391799}
|
||||
- {fileID: 1140410864}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 5
|
||||
m_RootOrder: 4
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
|
|
@ -7243,6 +7695,82 @@ CanvasRenderer:
|
|||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2010083453}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &2055567528
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2055567529}
|
||||
- component: {fileID: 2055567531}
|
||||
- component: {fileID: 2055567530}
|
||||
m_Layer: 5
|
||||
m_Name: Checkmark
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2055567529
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2055567528}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1519258558}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 20, y: 20}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &2055567530
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2055567528}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10901, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!222 &2055567531
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2055567528}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &2090837016
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@ namespace UniVRM10.VRM10Viewer
|
|||
[SerializeField]
|
||||
Toggle m_showBoxMan = default;
|
||||
|
||||
[SerializeField]
|
||||
Toggle m_pauseSpringBone = default;
|
||||
|
||||
[SerializeField]
|
||||
Button m_resetSpringBone = default;
|
||||
|
||||
[SerializeField]
|
||||
Toggle m_enableLipSync = default;
|
||||
|
||||
|
|
@ -252,6 +258,7 @@ namespace UniVRM10.VRM10Viewer
|
|||
m_openModel = buttons.First(x => x.name == "OpenModel");
|
||||
m_openMotion = buttons.First(x => x.name == "OpenMotion");
|
||||
m_pastePose = buttons.First(x => x.name == "PastePose");
|
||||
m_resetSpringBone = buttons.First(x => x.name == "ResetSpringBone");
|
||||
|
||||
#if UNITY_2022_3_OR_NEWER
|
||||
var toggles = GameObject.FindObjectsByType<Toggle>(FindObjectsSortMode.InstanceID);
|
||||
|
|
@ -259,6 +266,7 @@ namespace UniVRM10.VRM10Viewer
|
|||
var toggles = GameObject.FindObjectsOfType<Toggle>();
|
||||
#endif
|
||||
m_showBoxMan = toggles.First(x => x.name == "ShowBoxMan");
|
||||
m_pauseSpringBone = toggles.First(x => x.name == "PauseSpringBone");
|
||||
m_enableLipSync = toggles.First(x => x.name == "EnableLipSync");
|
||||
m_enableAutoBlink = toggles.First(x => x.name == "EnableAutoBlink");
|
||||
m_enableAutoExpression = toggles.First(x => x.name == "EnableAutoExpression");
|
||||
|
|
@ -347,6 +355,7 @@ namespace UniVRM10.VRM10Viewer
|
|||
m_openModel.onClick.AddListener(OnOpenModelClicked);
|
||||
m_openMotion.onClick.AddListener(OnOpenMotionClicked);
|
||||
m_pastePose.onClick.AddListener(OnPastePoseClicked);
|
||||
m_resetSpringBone.onClick.AddListener(OnResetSpringBoneClicked);
|
||||
|
||||
// load initial bvh
|
||||
if (m_motion != null)
|
||||
|
|
@ -393,18 +402,20 @@ namespace UniVRM10.VRM10Viewer
|
|||
m_loaded.EnableLipSyncValue = m_enableLipSync.isOn;
|
||||
m_loaded.EnableBlinkValue = m_enableAutoBlink.isOn;
|
||||
m_loaded.EnableAutoExpressionValue = m_enableAutoExpression.isOn;
|
||||
}
|
||||
|
||||
if (m_loaded != null)
|
||||
{
|
||||
if (m_ui.IsTPose)
|
||||
if (m_loaded.Runtime != null)
|
||||
{
|
||||
m_loaded.Runtime.VrmAnimation = TPose;
|
||||
}
|
||||
else if (Motion != null)
|
||||
{
|
||||
// Automatically retarget in Vrm10Runtime.Process
|
||||
m_loaded.Runtime.VrmAnimation = Motion;
|
||||
if (m_ui.IsTPose)
|
||||
{
|
||||
m_loaded.Runtime.VrmAnimation = TPose;
|
||||
}
|
||||
else if (Motion != null)
|
||||
{
|
||||
// Automatically retarget in Vrm10Runtime.Process
|
||||
m_loaded.Runtime.VrmAnimation = Motion;
|
||||
}
|
||||
|
||||
m_loaded.Runtime.SpringBone.IsSpringBoneEnabled = !m_pauseSpringBone.isOn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -484,6 +495,17 @@ namespace UniVRM10.VRM10Viewer
|
|||
}
|
||||
}
|
||||
|
||||
void OnResetSpringBoneClicked()
|
||||
{
|
||||
if (m_loaded != null)
|
||||
{
|
||||
if (m_loaded.Runtime != null)
|
||||
{
|
||||
m_loaded.Runtime.SpringBone.RestoreInitialTransform();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static IMaterialDescriptorGenerator GetVrmMaterialDescriptorGenerator(bool useUrp)
|
||||
{
|
||||
if (useUrp)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user