mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-14 22:50:08 -05:00
Merge pull request #304 from Kohei-Yanagida/reduce_blendshape_size
add VRM Export Option. Reduce BlendShape Size
This commit is contained in:
commit
c842e577c4
|
|
@ -106,13 +106,15 @@ namespace UniGLTF
|
|||
|
||||
static gltfMorphTarget ExportMorphTarget(glTF gltf, int bufferIndex,
|
||||
Mesh mesh, int j,
|
||||
bool useSparseAccessorForMorphTarget)
|
||||
bool useSparseAccessorForMorphTarget,
|
||||
bool exportOnlyBlendShapePosition)
|
||||
{
|
||||
var blendShapeVertices = mesh.vertices;
|
||||
var usePosition = blendShapeVertices != null && blendShapeVertices.Length > 0;
|
||||
|
||||
var blendShapeNormals = mesh.normals;
|
||||
var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length;
|
||||
// var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length && !exportOnlyBlendShapePosition;
|
||||
|
||||
var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray();
|
||||
//var useTangent = usePosition && blendShapeTangents != null && blendShapeTangents.Length == blendShapeVertices.Length;
|
||||
|
|
@ -228,7 +230,8 @@ namespace UniGLTF
|
|||
|
||||
public static void ExportMeshes(glTF gltf, int bufferIndex,
|
||||
List<MeshWithRenderer> unityMeshes, List<Material> unityMaterials,
|
||||
bool useSparseAccessorForMorphTarget)
|
||||
bool useSparseAccessorForMorphTarget,
|
||||
bool exportOnlyBlendShapePosition)
|
||||
{
|
||||
for (int i = 0; i < unityMeshes.Count; ++i)
|
||||
{
|
||||
|
|
@ -244,7 +247,8 @@ namespace UniGLTF
|
|||
{
|
||||
var morphTarget = ExportMorphTarget(gltf, bufferIndex,
|
||||
mesh, j,
|
||||
useSparseAccessorForMorphTarget);
|
||||
useSparseAccessorForMorphTarget,
|
||||
exportOnlyBlendShapePosition);
|
||||
|
||||
//
|
||||
// all primitive has same blendShape
|
||||
|
|
|
|||
|
|
@ -468,7 +468,7 @@ namespace UniGLTF
|
|||
{
|
||||
mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT,
|
||||
blendShape.Positions.ToArray(),
|
||||
(meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount) ? blendShape.Normals.ToArray() : null,
|
||||
(meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount && blendShape.Normals.Count() == blendShape.Positions.Count()) ? blendShape.Normals.ToArray() : null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,12 @@ namespace UniGLTF
|
|||
set;
|
||||
}
|
||||
|
||||
public bool ExportOnlyBlendShapePosition
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public GameObject Copy
|
||||
{
|
||||
get;
|
||||
|
|
@ -240,7 +246,7 @@ namespace UniGLTF
|
|||
return true;
|
||||
})
|
||||
.ToList();
|
||||
MeshExporter.ExportMeshes(gltf, bufferIndex, unityMeshes, Materials, useSparseAccessorForMorphTarget);
|
||||
MeshExporter.ExportMeshes(gltf, bufferIndex, unityMeshes, Materials, useSparseAccessorForMorphTarget, ExportOnlyBlendShapePosition);
|
||||
Meshes = unityMeshes.Select(x => x.Mesh).ToList();
|
||||
#endregion
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using UniGLTF;
|
|||
using System.IO;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -32,6 +33,8 @@ namespace VRM
|
|||
|
||||
public bool UseExperimentalExporter = true;
|
||||
|
||||
public bool ReduceBlendshapeSize = true;
|
||||
|
||||
public IEnumerable<string> CanExport()
|
||||
{
|
||||
if (Source == null)
|
||||
|
|
@ -142,7 +145,7 @@ namespace VRM
|
|||
var dstColliderGroup = dst.gameObject.AddComponent<VRMSpringBoneColliderGroup>();
|
||||
dstColliderGroup.Colliders = src.Colliders.Select(y =>
|
||||
{
|
||||
var offset = dst.worldToLocalMatrix.MultiplyPoint(src.transform.localToWorldMatrix.MultiplyPoint(y.Offset));
|
||||
var offset =dst.worldToLocalMatrix.MultiplyPoint(src.transform.localToWorldMatrix.MultiplyPoint(y.Offset));
|
||||
return new VRMSpringBoneColliderGroup.SphereCollider
|
||||
{
|
||||
Offset = offset,
|
||||
|
|
@ -164,11 +167,13 @@ namespace VRM
|
|||
{
|
||||
dst.m_center = map[src.m_center];
|
||||
}
|
||||
|
||||
dst.RootBones = src.RootBones.Select(x => map[x]).ToList();
|
||||
dst.m_hitRadius = src.m_hitRadius;
|
||||
if (src.ColliderGroups != null)
|
||||
{
|
||||
dst.ColliderGroups = src.ColliderGroups.Select(x => map[x.transform].GetComponent<VRMSpringBoneColliderGroup>()).ToArray();
|
||||
dst.ColliderGroups = src.ColliderGroups
|
||||
.Select(x => map[x.transform].GetComponent<VRMSpringBoneColliderGroup>()).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -270,6 +275,7 @@ namespace VRM
|
|||
destroy.Add(target);
|
||||
}
|
||||
}
|
||||
|
||||
if (PoseFreeze)
|
||||
{
|
||||
using (new RecordDisposer(target.transform.Traverse().ToArray(), "before normalize"))
|
||||
|
|
@ -281,9 +287,95 @@ namespace VRM
|
|||
}
|
||||
}
|
||||
|
||||
// remove unused blendShape
|
||||
if (ReduceBlendshapeSize)
|
||||
{
|
||||
var proxy = target.GetComponent<VRMBlendShapeProxy>();
|
||||
|
||||
// 元のBlendShapeClipに変更を加えないように複製
|
||||
var copyBlendShapeAvatar = GameObject.Instantiate(proxy.BlendShapeAvatar);
|
||||
var copyBlendShapClips = new List<BlendShapeClip>();
|
||||
|
||||
foreach (var clip in proxy.BlendShapeAvatar.Clips)
|
||||
{
|
||||
copyBlendShapClips.Add(GameObject.Instantiate(clip));
|
||||
}
|
||||
|
||||
var skinnedMeshRenderers = target.GetComponentsInChildren<SkinnedMeshRenderer>();
|
||||
|
||||
var names = new Dictionary<int, string>();
|
||||
var vs = new Dictionary<int, Vector3[]>();
|
||||
var ns = new Dictionary<int, Vector3[]>();
|
||||
var ts = new Dictionary<int, Vector3[]>();
|
||||
|
||||
foreach (SkinnedMeshRenderer smr in skinnedMeshRenderers)
|
||||
{
|
||||
Mesh mesh = smr.sharedMesh;
|
||||
if (mesh == null) continue;
|
||||
if (mesh.blendShapeCount == 0) continue;
|
||||
|
||||
var copyMesh = mesh.Copy(true);
|
||||
var vCount = copyMesh.vertexCount;
|
||||
names.Clear();
|
||||
|
||||
vs.Clear();
|
||||
ns.Clear();
|
||||
ts.Clear();
|
||||
|
||||
var usedBlendshapeIndexArray = copyBlendShapClips
|
||||
.SelectMany(clip => clip.Values)
|
||||
.Where(val => target.transform.Find(val.RelativePath) == smr.transform)
|
||||
.Select(val => val.Index)
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
foreach (var i in usedBlendshapeIndexArray)
|
||||
{
|
||||
var name = copyMesh.GetBlendShapeName(i);
|
||||
var vertices = new Vector3[vCount];
|
||||
var normals = new Vector3[vCount];
|
||||
var tangents = new Vector3[vCount];
|
||||
copyMesh.GetBlendShapeFrameVertices(i, 0, vertices, normals, tangents);
|
||||
|
||||
names.Add(i, name);
|
||||
vs.Add(i, vertices);
|
||||
ns.Add(i, normals);
|
||||
ts.Add(i, tangents);
|
||||
}
|
||||
|
||||
copyMesh.ClearBlendShapes();
|
||||
|
||||
foreach (var i in usedBlendshapeIndexArray)
|
||||
{
|
||||
copyMesh.AddBlendShapeFrame(names[i], 100f, vs[i], ns[i], ts[i]);
|
||||
}
|
||||
|
||||
var indexMapper = usedBlendshapeIndexArray
|
||||
.Select((x, i) => new {x, i})
|
||||
.ToDictionary(pair => pair.x, pair => pair.i);
|
||||
|
||||
foreach (var clip in copyBlendShapClips)
|
||||
{
|
||||
for (var i = 0; i < clip.Values.Length; ++i)
|
||||
{
|
||||
var value = clip.Values[i];
|
||||
if (target.transform.Find(value.RelativePath) != smr.transform) continue;
|
||||
value.Index = indexMapper[value.Index];
|
||||
clip.Values[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
copyBlendShapeAvatar.Clips = copyBlendShapClips;
|
||||
|
||||
proxy.BlendShapeAvatar = copyBlendShapeAvatar;
|
||||
|
||||
smr.sharedMesh = copyMesh;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
var vrm = VRMExporter.Export(target);
|
||||
var vrm = VRMExporter.Export(target, ReduceBlendshapeSize);
|
||||
vrm.extensions.VRM.meta.title = Title;
|
||||
vrm.extensions.VRM.meta.version = Version;
|
||||
vrm.extensions.VRM.meta.author = Author;
|
||||
|
|
@ -296,6 +388,12 @@ namespace VRM
|
|||
Debug.LogFormat("Export elapsed {0}", sw.Elapsed);
|
||||
}
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
PrefabUtility.RevertPrefabInstance(target, InteractionMode.AutomatedAction);
|
||||
#else
|
||||
PrefabUtility.RevertPrefabInstance(target);
|
||||
#endif
|
||||
|
||||
if (path.StartsWithUnityAssetPath())
|
||||
{
|
||||
AssetDatabase.ImportAsset(path.ToUnityRelativePath());
|
||||
|
|
@ -303,4 +401,4 @@ namespace VRM
|
|||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ namespace VRM
|
|||
gltf.extensions.VRM = new glTF_VRM_extensions();
|
||||
}
|
||||
|
||||
public new static glTF Export(GameObject go)
|
||||
public new static glTF Export(GameObject go, bool exportOnlyBlendShapePosition = false)
|
||||
{
|
||||
var gltf = new glTF();
|
||||
|
||||
|
|
@ -27,12 +27,14 @@ namespace VRM
|
|||
{
|
||||
#if VRM_EXPORTER_USE_SPARSE
|
||||
// experimental
|
||||
UseSparseAccessorForBlendShape=true
|
||||
UseSparseAccessorForBlendShape = true
|
||||
#endif
|
||||
ExportOnlyBlendShapePosition = exportOnlyBlendShapePosition
|
||||
})
|
||||
{
|
||||
_Export(gltf, exporter, go);
|
||||
}
|
||||
|
||||
return gltf;
|
||||
}
|
||||
|
||||
|
|
@ -60,6 +62,7 @@ namespace VRM
|
|||
// use description
|
||||
gltf.extensions.VRM.humanoid.Apply(description, nodes);
|
||||
}
|
||||
|
||||
if (isCreated)
|
||||
{
|
||||
GameObject.DestroyImmediate(description);
|
||||
|
|
@ -119,6 +122,7 @@ namespace VRM
|
|||
{
|
||||
gltf.extensions.VRM.meta.texture = TextureIO.ExportTexture(gltf, gltf.buffers.Count - 1, meta.Thumbnail, glTFTextureTypes.Unknown);
|
||||
}
|
||||
|
||||
gltf.extensions.VRM.meta.licenseType = meta.LicenseType;
|
||||
gltf.extensions.VRM.meta.otherLicenseUrl = meta.OtherLicenseUrl;
|
||||
gltf.extensions.VRM.meta.reference = meta.Reference;
|
||||
|
|
@ -208,4 +212,4 @@ namespace VRM
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user