-
Notifications
You must be signed in to change notification settings - Fork 424
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2436 from ousttrue/feature/vrm1_springbone_runtime
[vrm-1.0][SpringBone] import 時に springbone 実装をスイッチする IVrm10SpringBoneRuntime インターフェース
- Loading branch information
Showing
13 changed files
with
757 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
166 changes: 166 additions & 0 deletions
166
Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
using System; | ||
using System.Linq; | ||
using UniGLTF; | ||
using UniGLTF.Utils; | ||
using UnityEngine; | ||
using UniGLTF.SpringBoneJobs.Blittables; | ||
using UniGLTF.SpringBoneJobs.InputPorts; | ||
using UniGLTF.SpringBoneJobs; | ||
|
||
namespace UniVRM10 | ||
{ | ||
/// <summary> | ||
/// FastSpringbone(job) で動作します。 | ||
/// FastSpringBoneService(Singleton)を経由せずに直接実行します。 | ||
/// | ||
/// シーンに2体以上の vrm-1.0 モデルがある場合は FastSpringBoneService でバッチングする方が効率的です。 | ||
/// </summary> | ||
public class Vrm10FastSpringboneRuntimeStandalone : IVrm10SpringBoneRuntime | ||
{ | ||
private Vrm10Instance m_instance; | ||
private FastSpringBoneSpring[] m_springs; | ||
private Quaternion[] m_initialLocalRotations; | ||
private FastSpringBoneBuffer m_fastSpringBoneBuffer; | ||
public FastSpringBoneBufferCombiner m_bufferCombiner = new(); | ||
private FastSpringBoneScheduler m_fastSpringBoneScheduler; | ||
|
||
public Vector3 ExternalForce | ||
{ | ||
get => m_fastSpringBoneBuffer.ExternalForce; | ||
set => m_fastSpringBoneBuffer.ExternalForce = value; | ||
} | ||
public bool IsSpringBoneEnabled | ||
{ | ||
get => m_fastSpringBoneBuffer.IsSpringBoneEnabled; | ||
set => m_fastSpringBoneBuffer.IsSpringBoneEnabled = value; | ||
} | ||
|
||
public float DeltaTime => Time.deltaTime; | ||
|
||
public Vrm10FastSpringboneRuntimeStandalone() | ||
{ | ||
m_fastSpringBoneScheduler = new(m_bufferCombiner); | ||
} | ||
|
||
/// <param name="initialTransform">VRMの初期姿勢(T-Pose)状態。instanceがT-Poseから変化していても大丈夫</param> | ||
public void Initialize(Vrm10Instance instance) | ||
{ | ||
m_instance = instance; | ||
|
||
// NOTE: FastSpringBoneService は UnitTest などでは動作しない | ||
if (Application.isPlaying) | ||
{ | ||
ReconstructSpringBone(); | ||
} | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
m_bufferCombiner.Unregister(m_fastSpringBoneBuffer); | ||
m_fastSpringBoneBuffer.Dispose(); | ||
|
||
m_fastSpringBoneScheduler.Dispose(); | ||
m_bufferCombiner.Dispose(); | ||
} | ||
|
||
/// <summary> | ||
/// このVRMに紐づくSpringBone関連のバッファを再構築する | ||
/// ランタイム実行時にSpringBoneに対して変更を行いたいときは、このメソッドを明示的に呼ぶ必要がある | ||
/// </summary> | ||
public void ReconstructSpringBone() | ||
{ | ||
// release | ||
if (m_fastSpringBoneBuffer != null) | ||
{ | ||
m_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 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(); | ||
|
||
// DOTS buffer 構築 | ||
m_fastSpringBoneBuffer = new FastSpringBoneBuffer(m_springs); | ||
m_bufferCombiner.Register(m_fastSpringBoneBuffer); | ||
// reset 用の初期状態の記録 | ||
m_initialLocalRotations = m_fastSpringBoneBuffer.Transforms.Select(x => x.localRotation).ToArray(); | ||
} | ||
|
||
private TransformState GetOrAddDefaultTransformState(Transform tf) | ||
{ | ||
if (m_instance.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]; | ||
} | ||
|
||
// TODO: | ||
} | ||
|
||
public void Process() | ||
{ | ||
m_fastSpringBoneScheduler.Schedule(DeltaTime).Complete(); | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.