mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-20 09:34:42 -05:00
Merge pull request #2712 from ousttrue/fix/unique_morphname
[importer] blendshape の名前重複をリネームする
This commit is contained in:
@@ -83,6 +83,7 @@ namespace UniGLTF
|
||||
RestoreOlderVersionValues(json, GLTF);
|
||||
|
||||
FixMeshNameUnique(GLTF);
|
||||
FixBlendShapeNameUnique(GLTF);
|
||||
foreach (var image in GLTF.images)
|
||||
{
|
||||
image.uri = PrepareUri(image.uri);
|
||||
@@ -121,6 +122,61 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/vrm-c/UniVRM/issues/2619
|
||||
private static void FixBlendShapeNameUnique(glTF GLTF)
|
||||
{
|
||||
foreach (var mesh in GLTF.meshes)
|
||||
{
|
||||
/// https://github.com/KhronosGroup/glTF/pull/1631/files
|
||||
if (gltf_mesh_extras_targetNames.TryGet(mesh, out var targetNames))
|
||||
{
|
||||
var used = new HashSet<string>();
|
||||
int rename = 0;
|
||||
for (int i = 0; i < targetNames.Count; ++i)
|
||||
{
|
||||
var target_name = targetNames[i];
|
||||
if (string.IsNullOrEmpty(target_name))
|
||||
{
|
||||
// no name
|
||||
targetNames[i] = $"__{i}__";
|
||||
UniGLTFLogger.Log($"rename blendshape: {mesh.name}[{i}]{target_name} => {targetNames[i]}");
|
||||
rename += 1;
|
||||
}
|
||||
else if (used.Contains(target_name))
|
||||
{
|
||||
// rename
|
||||
var uname = $"__{i}__{target_name}";
|
||||
targetNames[i] = uname;
|
||||
UniGLTFLogger.Log($"rename blendshape: {mesh.name}[{i}]{target_name} => {targetNames[i]}");
|
||||
rename += 1;
|
||||
}
|
||||
used.Add(targetNames[i]);
|
||||
}
|
||||
if (rename > 0)
|
||||
{
|
||||
|
||||
// var extrans = new Dictionary<string, JsonNode>()
|
||||
// {
|
||||
// {"targetNames", targetNames },
|
||||
var f = new JsonFormatter();
|
||||
f.BeginMap();
|
||||
f.Key("targetNames");
|
||||
{
|
||||
f.BeginList();
|
||||
foreach (var name in targetNames)
|
||||
{
|
||||
f.Value(name);
|
||||
}
|
||||
f.EndList();
|
||||
}
|
||||
f.EndMap();
|
||||
var json = f.ToString();
|
||||
mesh.extras = new UniGLTF.glTFExtensionImport(JsonParser.Parse(json));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RenameImageFromTexture(glTF GLTF, int i)
|
||||
{
|
||||
foreach (var texture in GLTF.textures)
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace UniJSON
|
||||
}
|
||||
|
||||
default:
|
||||
throw new ParserException(segment + " is not valid json start");
|
||||
throw new ParserException(segment + " is not valid json start(maybe invalid ',')");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -233,5 +233,103 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.khronos.org/glTF-Tutorials/gltfTutorial/gltfTutorial_017_SimpleMorphTarget.html
|
||||
[Test]
|
||||
public void Preprocess_AutoNodeName()
|
||||
{
|
||||
var json = @"
|
||||
{
|
||||
""scene"": 0,
|
||||
""scenes"" : [
|
||||
{
|
||||
""nodes"" : [ 0 ]
|
||||
}
|
||||
],
|
||||
|
||||
""nodes"" : [
|
||||
{
|
||||
""mesh"" : 0
|
||||
}
|
||||
],
|
||||
|
||||
""meshes"" : [
|
||||
{
|
||||
""primitives"" : [ {
|
||||
""attributes"" : {
|
||||
""POSITION"" : 1
|
||||
},
|
||||
""indices"" : 0
|
||||
} ]
|
||||
}
|
||||
],
|
||||
|
||||
""buffers"" : [
|
||||
{
|
||||
""uri"" : ""data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA="",
|
||||
""byteLength"" : 44
|
||||
}
|
||||
],
|
||||
""bufferViews"" : [
|
||||
{
|
||||
""buffer"" : 0,
|
||||
""byteOffset"" : 0,
|
||||
""byteLength"" : 6,
|
||||
""target"" : 34963
|
||||
},
|
||||
{
|
||||
""buffer"" : 0,
|
||||
""byteOffset"" : 8,
|
||||
""byteLength"" : 36,
|
||||
""target"" : 34962
|
||||
}
|
||||
],
|
||||
""accessors"" : [
|
||||
{
|
||||
""bufferView"" : 0,
|
||||
""byteOffset"" : 0,
|
||||
""componentType"" : 5123,
|
||||
""count"" : 3,
|
||||
""type"" : ""SCALAR"",
|
||||
""max"" : [ 2 ],
|
||||
""min"" : [ 0 ]
|
||||
},
|
||||
{
|
||||
""bufferView"" : 1,
|
||||
""byteOffset"" : 0,
|
||||
""componentType"" : 5126,
|
||||
""count"" : 3,
|
||||
""type"" : ""VEC3"",
|
||||
""max"" : [ 1.0, 1.0, 0.0 ],
|
||||
""min"" : [ 0.0, 0.0, 0.0 ]
|
||||
}
|
||||
],
|
||||
|
||||
""asset"" : {
|
||||
""version"" : ""2.0""
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
var gltf = GlbLowLevelParser.ParseGltf("tmp", json, null, null, default);
|
||||
Assert.AreEqual(1, gltf.GLTF.nodes.Count);
|
||||
Assert.AreEqual("0", gltf.GLTF.nodes[0].name);
|
||||
}
|
||||
|
||||
// https://github.khronos.org/glTF-Tutorials/gltfTutorial/gltfTutorial_017_SimpleMorphTarget.html
|
||||
[Test]
|
||||
public void Preprocess_DupMorphTargetName()
|
||||
{
|
||||
var asset = UnityEditor.AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/UniGLTF/Tests/UniGLTF/gltfTutorial_017_SimpleMorphTarget.txt");
|
||||
Assert.True(asset);
|
||||
var gltf = GlbLowLevelParser.ParseGltf("tmp", asset.text, null, null, default);
|
||||
Assert.AreEqual(1, gltf.GLTF.nodes.Count);
|
||||
Assert.AreEqual("0", gltf.GLTF.nodes[0].name);
|
||||
Assert.True(gltf_mesh_extras_targetNames.TryGet(gltf.GLTF.meshes[0], out List<string> targetNames));
|
||||
// [dup_name, dup_name] => [dup_name, __1__dup_name]
|
||||
Assert.AreEqual(2, targetNames.Count);
|
||||
Assert.AreEqual("dup_name", targetNames[0]);
|
||||
Assert.AreEqual("__1__dup_name", targetNames[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
{
|
||||
"scene": 0,
|
||||
"scenes":[
|
||||
{
|
||||
"nodes":[
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes":[
|
||||
{
|
||||
"mesh":0
|
||||
}
|
||||
],
|
||||
"meshes":[
|
||||
{
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":1
|
||||
},
|
||||
"targets":[
|
||||
{
|
||||
"POSITION":2
|
||||
},
|
||||
{
|
||||
"POSITION":3
|
||||
}
|
||||
],
|
||||
"indices":0
|
||||
}
|
||||
],
|
||||
"weights":[
|
||||
1.0,
|
||||
0.5
|
||||
],
|
||||
"extras":{
|
||||
"targetNames": [
|
||||
"dup_name",
|
||||
"dup_name"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"animations":[
|
||||
{
|
||||
"samplers":[
|
||||
{
|
||||
"input":4,
|
||||
"interpolation":"LINEAR",
|
||||
"output":5
|
||||
}
|
||||
],
|
||||
"channels":[
|
||||
{
|
||||
"sampler":0,
|
||||
"target":{
|
||||
"node":0,
|
||||
"path":"weights"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
"buffers":[
|
||||
{
|
||||
"uri":"data:application/gltf-buffer;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIC/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAAAA=",
|
||||
"byteLength":116
|
||||
},
|
||||
{
|
||||
"uri":"data:application/gltf-buffer;base64,AAAAAAAAgD8AAABAAABAQAAAgEAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAA",
|
||||
"byteLength":60
|
||||
}
|
||||
],
|
||||
"bufferViews":[
|
||||
{
|
||||
"buffer":0,
|
||||
"byteOffset":0,
|
||||
"byteLength":6,
|
||||
"target":34963
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteOffset":8,
|
||||
"byteLength":108,
|
||||
"byteStride":12,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":1,
|
||||
"byteOffset":0,
|
||||
"byteLength":20
|
||||
},
|
||||
{
|
||||
"buffer":1,
|
||||
"byteOffset":20,
|
||||
"byteLength":40
|
||||
}
|
||||
],
|
||||
"accessors":[
|
||||
{
|
||||
"bufferView":0,
|
||||
"byteOffset":0,
|
||||
"componentType":5123,
|
||||
"count":3,
|
||||
"type":"SCALAR",
|
||||
"max":[
|
||||
2
|
||||
],
|
||||
"min":[
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"bufferView":1,
|
||||
"byteOffset":0,
|
||||
"componentType":5126,
|
||||
"count":3,
|
||||
"type":"VEC3",
|
||||
"max":[
|
||||
1.0,
|
||||
0.5,
|
||||
0.0
|
||||
],
|
||||
"min":[
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"bufferView":1,
|
||||
"byteOffset":36,
|
||||
"componentType":5126,
|
||||
"count":3,
|
||||
"type":"VEC3",
|
||||
"max":[
|
||||
0.0,
|
||||
1.0,
|
||||
0.0
|
||||
],
|
||||
"min":[
|
||||
-1.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"bufferView":1,
|
||||
"byteOffset":72,
|
||||
"componentType":5126,
|
||||
"count":3,
|
||||
"type":"VEC3",
|
||||
"max":[
|
||||
1.0,
|
||||
1.0,
|
||||
0.0
|
||||
],
|
||||
"min":[
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"bufferView":2,
|
||||
"byteOffset":0,
|
||||
"componentType":5126,
|
||||
"count":5,
|
||||
"type":"SCALAR",
|
||||
"max":[
|
||||
4.0
|
||||
],
|
||||
"min":[
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"bufferView":3,
|
||||
"byteOffset":0,
|
||||
"componentType":5126,
|
||||
"count":10,
|
||||
"type":"SCALAR",
|
||||
"max":[
|
||||
1.0
|
||||
],
|
||||
"min":[
|
||||
0.0
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
"asset":{
|
||||
"version":"2.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff5b21eda4deae14583275d904ae3d08
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user