mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-10 04:49:28 -05:00
node rename 作り直し。parse 終了時に rename が完了している方がよい。
vrm-0.x, vrm-1.0, vrma に対して実装した。
This commit is contained in:
@@ -2,52 +2,70 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace UniGLTF.Utils
|
||||
{
|
||||
public class ForceTransformUniqueName
|
||||
{
|
||||
public delegate string GetNameFunc<T>(T t);
|
||||
public delegate void SetNameFunc<T>(T t, string newName);
|
||||
public delegate string GetLeafNameFunc<T>(T t);
|
||||
|
||||
HashSet<string> m_uniqueNameSet = new HashSet<string>();
|
||||
int m_counter = 1;
|
||||
|
||||
public static void Process(Transform root)
|
||||
{
|
||||
var uniqueName = new ForceTransformUniqueName();
|
||||
var transforms = root.GetComponentsInChildren<Transform>();
|
||||
Process(transforms,
|
||||
t => t.name,
|
||||
(t, name) => t.name = name,
|
||||
(t) => (t.parent != null && t.childCount == 0) ? $"{t.parent.name}-{t.name}" : null);
|
||||
}
|
||||
|
||||
public static void Process<T>(IReadOnlyList<T> transforms,
|
||||
GetNameFunc<T> getName,
|
||||
SetNameFunc<T> setName,
|
||||
GetLeafNameFunc<T> getLeafName)
|
||||
{
|
||||
var uniqueName = new ForceTransformUniqueName();
|
||||
foreach (var t in transforms)
|
||||
{
|
||||
uniqueName.RenameIfDupName(t);
|
||||
uniqueName.RenameIfDupName(t,
|
||||
getName,
|
||||
setName,
|
||||
getLeafName
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoRename(Transform t, string newName)
|
||||
public void RenameIfDupName<T>(T t,
|
||||
GetNameFunc<T> getName,
|
||||
SetNameFunc<T> setName,
|
||||
GetLeafNameFunc<T> getLeafName)
|
||||
{
|
||||
UniGLTFLogger.Warning($"force rename !!: {t.name} => {newName}");
|
||||
t.name = newName;
|
||||
m_uniqueNameSet.Add(newName);
|
||||
}
|
||||
|
||||
public void RenameIfDupName(Transform t)
|
||||
{
|
||||
if (!m_uniqueNameSet.Contains(t.name))
|
||||
if (!m_uniqueNameSet.Contains(getName(t)))
|
||||
{
|
||||
m_uniqueNameSet.Add(t.name);
|
||||
m_uniqueNameSet.Add(getName(t));
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.parent != null && t.childCount == 0)
|
||||
{
|
||||
/// AvatarBuilder:BuildHumanAvatar で同名の Transform があるとエラーになる。
|
||||
///
|
||||
/// AvatarBuilder 'GLTF': Ambiguous Transform '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/neck_1/neck_2/head/ENDSITE' and '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/l_shoulder/l_up_arm/l_low_arm/l_hand/ENDSITE' found in hierarchy for human bone 'Head'. Transform name mapped to a human bone must be unique.
|
||||
/// UnityEngine.AvatarBuilder:BuildHumanAvatar (UnityEngine.GameObject,UnityEngine.HumanDescription)
|
||||
///
|
||||
/// 主に BVH の EndSite 由来の GameObject 名が重複することへの対策
|
||||
/// ex: parent-ENDSITE
|
||||
var newName = $"{t.parent.name}-{t.name}";
|
||||
if (!m_uniqueNameSet.Contains(newName))
|
||||
var leafName = getLeafName(t);
|
||||
if (!string.IsNullOrEmpty(leafName))
|
||||
{
|
||||
DoRename(t, newName);
|
||||
return;
|
||||
/// AvatarBuilder:BuildHumanAvatar で同名の Transform があるとエラーになる。
|
||||
///
|
||||
/// AvatarBuilder 'GLTF': Ambiguous Transform '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/neck_1/neck_2/head/ENDSITE' and '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/l_shoulder/l_up_arm/l_low_arm/l_hand/ENDSITE' found in hierarchy for human bone 'Head'. Transform name mapped to a human bone must be unique.
|
||||
/// UnityEngine.AvatarBuilder:BuildHumanAvatar (UnityEngine.GameObject,UnityEngine.HumanDescription)
|
||||
///
|
||||
/// 主に BVH の EndSite 由来の GameObject 名が重複することへの対策
|
||||
/// ex: parent-ENDSITE
|
||||
if (!m_uniqueNameSet.Contains(leafName))
|
||||
{
|
||||
DoRename(t, getName, setName, leafName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,15 +73,25 @@ namespace UniGLTF.Utils
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
// ex: name.1
|
||||
var newName = $"{t.name}{m_counter++}";
|
||||
var newName = $"{getName(t)}{m_counter++}";
|
||||
if (!m_uniqueNameSet.Contains(newName))
|
||||
{
|
||||
DoRename(t, newName);
|
||||
DoRename(t, getName, setName, newName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void DoRename<T>(T t,
|
||||
GetNameFunc<T> getName,
|
||||
SetNameFunc<T> setName,
|
||||
string newName)
|
||||
{
|
||||
UniGLTFLogger.Warning($"force rename !!: {getName(t)} => {newName}");
|
||||
setName(t, newName);
|
||||
m_uniqueNameSet.Add(newName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
using UniGLTF;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UniGLTF;
|
||||
using UniGLTF.Utils;
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
@@ -18,6 +21,26 @@ namespace VRM
|
||||
VrmExtension = vrm;
|
||||
|
||||
UpdateMigrationFlags(Data.MigrationFlags, VrmExtension.exporterVersion);
|
||||
|
||||
// ヒューマノイド向け
|
||||
Func<glTFNode, glTFNode> getParent = (node) =>
|
||||
{
|
||||
var index = Data.GLTF.nodes.IndexOf(node);
|
||||
return Data.GLTF.nodes.FirstOrDefault(x => x.children != null && x.children.Contains(index));
|
||||
};
|
||||
|
||||
ForceTransformUniqueName.Process(Data.GLTF.nodes,
|
||||
node => node.name,
|
||||
(node, name) => node.name = name,
|
||||
node =>
|
||||
{
|
||||
var parent = getParent(node);
|
||||
if (parent != null && node.children != null && node.children.Length == 0)
|
||||
{
|
||||
return $"{parent.name}-{node.name}";
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private static void UpdateMigrationFlags(MigrationFlags migrationFlags, string exportedVrmVersionString)
|
||||
|
||||
@@ -39,24 +39,27 @@ namespace UniVRM10
|
||||
.ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value);
|
||||
|
||||
using (var data = new AutoGltfFileParser(assetPath).Parse())
|
||||
using (var loader = new VrmAnimationImporter(data, extractedObjects))
|
||||
{
|
||||
var loaded = loader.Load();
|
||||
|
||||
loaded.TransferOwnership((k, o) =>
|
||||
var vrmaData = new VrmAnimationData(data);
|
||||
using (var loader = new VrmAnimationImporter(vrmaData, extractedObjects))
|
||||
{
|
||||
context.AddObjectToAsset(k.Name, o);
|
||||
});
|
||||
var loaded = loader.Load();
|
||||
|
||||
var root = loaded.Root;
|
||||
GameObject.DestroyImmediate(loaded);
|
||||
loaded.TransferOwnership((k, o) =>
|
||||
{
|
||||
context.AddObjectToAsset(k.Name, o);
|
||||
});
|
||||
|
||||
// var vrma = root.GetComponent<Vrm10AnimationInstance>();
|
||||
// context.AddObjectToAsset("__boxman_mesh__", vrma.BoxMan.sharedMesh);
|
||||
// context.AddObjectToAsset("__boxman_mesh__material__", vrma.BoxMan.sharedMaterial);
|
||||
var root = loaded.Root;
|
||||
GameObject.DestroyImmediate(loaded);
|
||||
|
||||
context.AddObjectToAsset(root.name, root, AssetIcon);
|
||||
context.SetMainObject(root);
|
||||
// var vrma = root.GetComponent<Vrm10AnimationInstance>();
|
||||
// context.AddObjectToAsset("__boxman_mesh__", vrma.BoxMan.sharedMesh);
|
||||
// context.AddObjectToAsset("__boxman_mesh__material__", vrma.BoxMan.sharedMaterial);
|
||||
|
||||
context.AddObjectToAsset(root.name, root, AssetIcon);
|
||||
context.SetMainObject(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,8 @@ namespace UniVRM10
|
||||
new FileSystemStorage("_dummy_root_"), // .gltf file has resource path at file system.
|
||||
new MigrationFlags()
|
||||
);
|
||||
using var loader = new VrmAnimationImporter(data);
|
||||
var vrmaData = new VrmAnimationData(data);
|
||||
using var loader = new VrmAnimationImporter(vrmaData);
|
||||
var gltfInstance = await loader.LoadAsync(new ImmediateCaller());
|
||||
var instance = gltfInstance.GetComponentOrThrow<Vrm10AnimationInstance>();
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using UniGLTF;
|
||||
using UniGLTF.Extensions.VRMC_vrm;
|
||||
using UniGLTF.Utils;
|
||||
using UniJSON;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -17,6 +18,26 @@ namespace UniVRM10
|
||||
{
|
||||
Data = data;
|
||||
VrmExtension = vrm;
|
||||
|
||||
// ヒューマノイド向け
|
||||
Func<glTFNode, glTFNode> getParent = (node) =>
|
||||
{
|
||||
var index = Data.GLTF.nodes.IndexOf(node);
|
||||
return Data.GLTF.nodes.FirstOrDefault(x => x.children != null && x.children.Contains(index));
|
||||
};
|
||||
|
||||
ForceTransformUniqueName.Process(Data.GLTF.nodes,
|
||||
node => node.name,
|
||||
(node, name) => node.name = name,
|
||||
node =>
|
||||
{
|
||||
var parent = getParent(node);
|
||||
if (parent != null && node.children != null && node.children.Length == 0)
|
||||
{
|
||||
return $"{parent.name}-{node.name}";
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
37
Assets/VRM10/Runtime/IO/VrmAnimationData.cs
Normal file
37
Assets/VRM10/Runtime/IO/VrmAnimationData.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UniGLTF;
|
||||
using UniGLTF.Utils;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public class VrmAnimationData
|
||||
{
|
||||
public GltfData Data { get; }
|
||||
|
||||
public VrmAnimationData(GltfData data)
|
||||
{
|
||||
Data = data;
|
||||
|
||||
// ヒューマノイド向け
|
||||
Func<glTFNode, glTFNode> getParent = (node) =>
|
||||
{
|
||||
var index = Data.GLTF.nodes.IndexOf(node);
|
||||
return Data.GLTF.nodes.FirstOrDefault(x => x.children != null && x.children.Contains(index));
|
||||
};
|
||||
|
||||
ForceTransformUniqueName.Process(Data.GLTF.nodes,
|
||||
node => node.name,
|
||||
(node, name) => node.name = name,
|
||||
node =>
|
||||
{
|
||||
var parent = getParent(node);
|
||||
if (parent != null && node.children != null && node.children.Length == 0)
|
||||
{
|
||||
return $"{parent.name}-{node.name}";
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/VRM10/Runtime/IO/VrmAnimationData.cs.meta
Normal file
11
Assets/VRM10/Runtime/IO/VrmAnimationData.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 384f2feacbf53ae4abfb7d291837d48d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -17,11 +17,11 @@ namespace UniVRM10
|
||||
ExpressionInfo[] m_expressions;
|
||||
Material m_defaultMaterial;
|
||||
|
||||
public VrmAnimationImporter(GltfData data,
|
||||
public VrmAnimationImporter(VrmAnimationData data,
|
||||
IReadOnlyDictionary<SubAssetKey, UnityEngine.Object> externalObjectMap = null,
|
||||
ITextureDeserializer textureDeserializer = null,
|
||||
IMaterialDescriptorGenerator materialGenerator = null)
|
||||
: base(data, externalObjectMap, textureDeserializer, materialGenerator, new ImporterContextSettings(invertAxis: Axes.X))
|
||||
: base(data.Data, externalObjectMap, textureDeserializer, materialGenerator, new ImporterContextSettings(invertAxis: Axes.X))
|
||||
{
|
||||
m_vrma = GetExtension(Data);
|
||||
}
|
||||
|
||||
@@ -279,7 +279,8 @@ namespace UniVRM10.Cloth.Viewer
|
||||
|
||||
// gltf, glb etc...
|
||||
using GltfData data = new AutoGltfFileParser(path).Parse();
|
||||
using var loader = new VrmAnimationImporter(data);
|
||||
var vrmaData = new VrmAnimationData(data);
|
||||
using var loader = new VrmAnimationImporter(vrmaData);
|
||||
var instance = await loader.LoadAsync(new ImmediateCaller());
|
||||
Motion = instance.GetComponent<Vrm10AnimationInstance>();
|
||||
instance.GetComponent<Animation>().Play();
|
||||
|
||||
@@ -54,7 +54,8 @@ public class SimpleVrma : MonoBehaviour
|
||||
{
|
||||
// load vrma
|
||||
using GltfData data = new AutoGltfFileParser(path).Parse();
|
||||
using var loader = new VrmAnimationImporter(data);
|
||||
var vrmaData = new VrmAnimationData(data);
|
||||
using var loader = new VrmAnimationImporter(vrmaData);
|
||||
var instance = await loader.LoadAsync(new ImmediateCaller());
|
||||
|
||||
Vrma = instance.GetComponent<Vrm10AnimationInstance>();
|
||||
|
||||
@@ -192,7 +192,8 @@ namespace UniVRM10.VRM10Viewer
|
||||
|
||||
// gltf, glb etc...
|
||||
using GltfData data = new AutoGltfFileParser(path).Parse();
|
||||
using var loader = new VrmAnimationImporter(data);
|
||||
var vrmaData = new VrmAnimationData(data);
|
||||
using var loader = new VrmAnimationImporter(vrmaData);
|
||||
var instance = await loader.LoadAsync(new ImmediateCaller());
|
||||
Motion = instance.GetComponent<Vrm10AnimationInstance>();
|
||||
instance.GetComponent<Animation>().Play();
|
||||
|
||||
Reference in New Issue
Block a user