mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-20 01:25:45 -05:00
bake 時に SpringBone と LookAt に反映する実装
This commit is contained in:
@@ -208,8 +208,11 @@ namespace VRM
|
||||
|
||||
if (settings.PoseFreeze)
|
||||
{
|
||||
// 正規化
|
||||
VRMBoneNormalizer.Execute(target, settings.ForceTPose, settings.FreezeMeshUseCurrentBlendShapeWeight);
|
||||
using (var backup = new VrmGeometryBackup(target))
|
||||
{
|
||||
// 正規化
|
||||
VRMBoneNormalizer.Execute(target, settings.ForceTPose, settings.FreezeMeshUseCurrentBlendShapeWeight);
|
||||
}
|
||||
}
|
||||
|
||||
// 元のBlendShapeClipに変更を加えないように複製
|
||||
|
||||
92
Assets/VRM/Runtime/IO/VrmGeometryBackup.cs
Normal file
92
Assets/VRM/Runtime/IO/VrmGeometryBackup.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UniGLTF;
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
/// <summary>
|
||||
/// SpringBone, LookAt の座標を記録しておき、Dispose で復帰する。
|
||||
/// </summary>
|
||||
public class VrmGeometryBackup : IDisposable
|
||||
{
|
||||
struct VrmSpringBoneColliderBackup
|
||||
{
|
||||
struct Collider
|
||||
{
|
||||
Vector3 _offsetInWorld;
|
||||
float _radiusMultLossyScale;
|
||||
|
||||
public Collider(Transform transform, VRMSpringBoneColliderGroup.SphereCollider collider)
|
||||
{
|
||||
_offsetInWorld = transform.TransformPoint(collider.Offset);
|
||||
_radiusMultLossyScale = transform.UniformedLossyScale() * collider.Radius;
|
||||
}
|
||||
|
||||
public void Restore(Transform transform, VRMSpringBoneColliderGroup.SphereCollider collider)
|
||||
{
|
||||
collider.Offset = transform.worldToLocalMatrix.MultiplyPoint(_offsetInWorld);
|
||||
collider.Radius = _radiusMultLossyScale / transform.UniformedLossyScale();
|
||||
}
|
||||
}
|
||||
Collider[] _colliers;
|
||||
|
||||
public VrmSpringBoneColliderBackup(VRMSpringBoneColliderGroup colliderGroup)
|
||||
{
|
||||
_colliers = colliderGroup.Colliders.Select(x => new Collider(colliderGroup.transform, x)).ToArray();
|
||||
}
|
||||
|
||||
public void Restore(VRMSpringBoneColliderGroup colliderGroup)
|
||||
{
|
||||
for (int i = 0; i < colliderGroup.Colliders.Length; ++i)
|
||||
{
|
||||
_colliers[i].Restore(colliderGroup.transform, colliderGroup.Colliders[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct VrmSpringBoneBackup
|
||||
{
|
||||
Vector3 _gravityDirInWorld;
|
||||
float _radiusMultLossyScale;
|
||||
|
||||
public VrmSpringBoneBackup(VRMSpringBone springBone)
|
||||
{
|
||||
_gravityDirInWorld = springBone.transform.TransformDirection(springBone.m_gravityDir);
|
||||
_radiusMultLossyScale = springBone.transform.UniformedLossyScale() * springBone.m_hitRadius;
|
||||
}
|
||||
public void Restore(VRMSpringBone springBone)
|
||||
{
|
||||
springBone.m_gravityDir = springBone.transform.worldToLocalMatrix.MultiplyVector(_gravityDirInWorld);
|
||||
springBone.m_hitRadius = _radiusMultLossyScale / springBone.transform.UniformedLossyScale();
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<VRMSpringBoneColliderGroup, VrmSpringBoneColliderBackup> _springBoneColliders;
|
||||
Dictionary<VRMSpringBone, VrmSpringBoneBackup> _springBones;
|
||||
VRMFirstPerson _firstPerson;
|
||||
Vector3 _firstPersonOffsetInWorld;
|
||||
|
||||
public VrmGeometryBackup(GameObject root)
|
||||
{
|
||||
_springBoneColliders = root.GetComponentsInChildren<VRMSpringBoneColliderGroup>().ToDictionary(x => x, x => new VrmSpringBoneColliderBackup(x));
|
||||
_springBones = root.GetComponentsInChildren<VRMSpringBone>().ToDictionary(x => x, x => new VrmSpringBoneBackup(x));
|
||||
_firstPerson = root.GetComponent<VRMFirstPerson>();
|
||||
_firstPersonOffsetInWorld = _firstPerson.transform.TransformPoint(_firstPerson.FirstPersonOffset);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var (k, v) in _springBoneColliders)
|
||||
{
|
||||
v.Restore(k);
|
||||
}
|
||||
foreach (var (k, v) in _springBones)
|
||||
{
|
||||
v.Restore(k);
|
||||
}
|
||||
_firstPerson.FirstPersonOffset = _firstPerson.transform.worldToLocalMatrix.MultiplyPoint(_firstPersonOffsetInWorld);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/VRM/Runtime/IO/VrmGeometryBackup.cs.meta
Normal file
11
Assets/VRM/Runtime/IO/VrmGeometryBackup.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 349a17edf9cddac469f1bd6a26cd0610
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -293,15 +293,18 @@ namespace UniVRM10
|
||||
disposer.Push(copy);
|
||||
root = copy;
|
||||
|
||||
// Transform の回転とスケールを Mesh に適用します。
|
||||
// - BlendShape は現状がbakeされます
|
||||
// - 回転とスケールが反映された新しい Mesh が作成されます
|
||||
// - Transform の回転とスケールはクリアされます。world position を維持します
|
||||
var newMeshMap = BoneNormalizer.NormalizeHierarchyFreezeMesh(root, m_settings.FreezeMeshUseCurrentBlendShapeWeight);
|
||||
using (var backup = new Vrm10GeometryBackup(root))
|
||||
{
|
||||
// Transform の回転とスケールを Mesh に適用します。
|
||||
// - BlendShape は現状がbakeされます
|
||||
// - 回転とスケールが反映された新しい Mesh が作成されます
|
||||
// - Transform の回転とスケールはクリアされます。world position を維持します
|
||||
var newMeshMap = BoneNormalizer.NormalizeHierarchyFreezeMesh(root, m_settings.FreezeMeshUseCurrentBlendShapeWeight);
|
||||
|
||||
// SkinnedMeshRenderer.sharedMesh と MeshFilter.sharedMesh を新しいMeshで置き換える
|
||||
BoneNormalizer.Replace(root, newMeshMap, m_settings.FreezeMeshKeepRotation);
|
||||
}
|
||||
// SkinnedMeshRenderer.sharedMesh と MeshFilter.sharedMesh を新しいMeshで置き換える
|
||||
BoneNormalizer.Replace(root, newMeshMap, m_settings.FreezeMeshKeepRotation);
|
||||
}
|
||||
}
|
||||
|
||||
var converter = new UniVRM10.ModelExporter();
|
||||
var model = converter.Export(arrayManager, root);
|
||||
|
||||
75
Assets/VRM10/Runtime/IO/Vrm10GeometryBackup.cs
Normal file
75
Assets/VRM10/Runtime/IO/Vrm10GeometryBackup.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UniGLTF;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
/// <summary>
|
||||
/// SpringBone, LookAt の座標を記録しておき、Dispose で復帰する。
|
||||
/// </summary>
|
||||
public class Vrm10GeometryBackup : IDisposable
|
||||
{
|
||||
struct Vrm10SpringBoneColliderBackup
|
||||
{
|
||||
Vector3 _offsetInWorld;
|
||||
float _radiusMultLossyScale;
|
||||
|
||||
public Vrm10SpringBoneColliderBackup(VRM10SpringBoneCollider collider)
|
||||
{
|
||||
_offsetInWorld = collider.transform.TransformPoint(collider.Offset);
|
||||
_radiusMultLossyScale = collider.transform.UniformedLossyScale() * collider.Radius;
|
||||
}
|
||||
|
||||
public void Restore(VRM10SpringBoneCollider collider)
|
||||
{
|
||||
collider.Offset = collider.transform.worldToLocalMatrix.MultiplyPoint(_offsetInWorld);
|
||||
collider.Radius = _radiusMultLossyScale / collider.transform.UniformedLossyScale();
|
||||
}
|
||||
}
|
||||
|
||||
struct Vrm10SpringBoneJointBackup
|
||||
{
|
||||
Vector3 _gravityDirInWorld;
|
||||
float _radiusMultLossyScale;
|
||||
|
||||
public Vrm10SpringBoneJointBackup(VRM10SpringBoneJoint joint)
|
||||
{
|
||||
_gravityDirInWorld = joint.transform.TransformDirection(joint.m_gravityDir);
|
||||
_radiusMultLossyScale = joint.transform.UniformedLossyScale() * joint.m_jointRadius;
|
||||
}
|
||||
public void Restore(VRM10SpringBoneJoint joint)
|
||||
{
|
||||
joint.m_gravityDir = joint.transform.worldToLocalMatrix.MultiplyVector(_gravityDirInWorld);
|
||||
joint.m_jointRadius = _radiusMultLossyScale / joint.transform.UniformedLossyScale();
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<VRM10SpringBoneCollider, Vrm10SpringBoneColliderBackup> _springBoneColliders;
|
||||
Dictionary<VRM10SpringBoneJoint, Vrm10SpringBoneJointBackup> _springBoneJoints;
|
||||
Vrm10Instance _vrm;
|
||||
Vector3 _lookAtOffsetInWorld;
|
||||
|
||||
public Vrm10GeometryBackup(GameObject root)
|
||||
{
|
||||
_springBoneColliders = root.GetComponentsInChildren<VRM10SpringBoneCollider>().ToDictionary(x => x, x => new Vrm10SpringBoneColliderBackup(x));
|
||||
_springBoneJoints = root.GetComponentsInChildren<VRM10SpringBoneJoint>().ToDictionary(x => x, x => new Vrm10SpringBoneJointBackup(x));
|
||||
_vrm = root.GetComponent<Vrm10Instance>();
|
||||
_lookAtOffsetInWorld = _vrm.transform.TransformPoint(_vrm.Vrm.LookAt.OffsetFromHead);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var (k, v) in _springBoneColliders)
|
||||
{
|
||||
v.Restore(k);
|
||||
}
|
||||
foreach (var (k, v) in _springBoneJoints)
|
||||
{
|
||||
v.Restore(k);
|
||||
}
|
||||
_vrm.Vrm.LookAt.OffsetFromHead = _vrm.transform.worldToLocalMatrix.MultiplyPoint(_lookAtOffsetInWorld);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/VRM10/Runtime/IO/Vrm10GeometryBackup.cs.meta
Normal file
11
Assets/VRM10/Runtime/IO/Vrm10GeometryBackup.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38fed05921b6c5c428e73312b6f18891
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user