Exemplo n.º 1
0
        static void Check(string name, JsonNode vrm0, UniGLTF.Extensions.VRMC_vrm.Expression vrm1,
                          MigrationVrm.MeshIndexToNodeIndexFunc meshToNode)
        {
            if (vrm0["binds"].GetArrayCount() == 0)
            {
                if (vrm1.MorphTargetBinds == null)
                {
                    // OK
                    return;
                }
                else
                {
                    throw new MigrationException($"expression.{name}.binds", "different count");
                }
            }

            foreach (var(l, r) in Enumerable.Zip(vrm0["binds"].ArrayItems(), vrm1.MorphTargetBinds, (x, y) => (x, y)))
            {
                var mesh = l["mesh"].GetInt32();
                var node = meshToNode(mesh);
                if (node != r.Node)
                {
                    throw new MigrationException($"expression.{name}.binds.node", $"{node} != {r.Node}");
                }

                var index = l["index"].GetInt32();
                if (index != r.Index)
                {
                    throw new MigrationException($"expression.{name}.binds.index", $"{index} != {r.Index}");
                }

                var weight = l["weight"].GetSingle() * 0.01f; // [0, 100] to [0, 1.0f]
                if (weight != r.Weight)
                {
                    throw new MigrationException($"expression.{name}.binds.weight", $"{weight} != {r.Weight}");
                }
            }
        }
Exemplo n.º 2
0
        static IEnumerable <UniGLTF.Extensions.VRMC_vrm.MorphTargetBind> ToMorphTargetBinds(JsonNode json,
                                                                                            MigrationVrm.MeshIndexToNodeIndexFunc meshToNode)
        {
            foreach (var x in json.ArrayItems())
            {
                var meshIndex        = x["mesh"].GetInt32();
                var morphTargetIndex = x["index"].GetInt32();
                var weight           = x["weight"].GetSingle();

                var bind = new UniGLTF.Extensions.VRMC_vrm.MorphTargetBind();

                // https://github.com/vrm-c/vrm-specification/pull/106
                // https://github.com/vrm-c/vrm-specification/pull/153
                var nodeIndex = meshToNode(meshIndex);
                if (nodeIndex == -1)
                {
                    // invalid data. skip
                    Debug.LogWarning($"[MigrationVrmExpression] node.mesh == {meshIndex} not found");
                    continue;
                }
                bind.Node  = nodeIndex;
                bind.Index = morphTargetIndex;
                // https://github.com/vrm-c/vrm-specification/issues/209
                bind.Weight = weight * 0.01f;

                yield return(bind);
            }
        }
Exemplo n.º 3
0
        public static void Check(JsonNode vrm0, UniGLTF.Extensions.VRMC_vrm.Expressions vrm1,
                                 MigrationVrm.MeshIndexToNodeIndexFunc meshToNode)
        {
            foreach (var blendShape in vrm0["blendShapeGroups"].ArrayItems())
            {
                var name = blendShape["presetName"].GetString().ToLower();
                switch (name)
                {
                case "a": Check(name, blendShape, vrm1.Preset.Aa, meshToNode); break;

                case "i": Check(name, blendShape, vrm1.Preset.Ih, meshToNode); break;

                case "u": Check(name, blendShape, vrm1.Preset.Ou, meshToNode); break;

                case "e": Check(name, blendShape, vrm1.Preset.Ee, meshToNode); break;

                case "o": Check(name, blendShape, vrm1.Preset.Oh, meshToNode); break;

                case "blink": Check(name, blendShape, vrm1.Preset.Blink, meshToNode); break;

                case "joy": Check(name, blendShape, vrm1.Preset.Happy, meshToNode); break;

                case "angry": Check(name, blendShape, vrm1.Preset.Angry, meshToNode); break;

                case "sorrow": Check(name, blendShape, vrm1.Preset.Sad, meshToNode); break;

                case "fun": Check(name, blendShape, vrm1.Preset.Relaxed, meshToNode); break;

                case "lookup": Check(name, blendShape, vrm1.Preset.LookUp, meshToNode); break;

                case "lookdown": Check(name, blendShape, vrm1.Preset.LookDown, meshToNode); break;

                case "lookleft": Check(name, blendShape, vrm1.Preset.LookLeft, meshToNode); break;

                case "lookright": Check(name, blendShape, vrm1.Preset.LookRight, meshToNode); break;

                case "blink_l": Check(name, blendShape, vrm1.Preset.BlinkLeft, meshToNode); break;

                case "blink_r": Check(name, blendShape, vrm1.Preset.BlinkRight, meshToNode); break;

                case "neutral": Check(name, blendShape, vrm1.Preset.Neutral, meshToNode); break;

                default:
                {
                    string found = default;
                    foreach (var kv in vrm1.Custom)
                    {
                        if (kv.Key.ToLower() == name)
                        {
                            Check(name, blendShape, kv.Value, meshToNode);
                            found = kv.Key;
                            break;
                        }
                    }
                    if (found == null)
                    {
                        throw new MigrationException(name, $"expression not migrated");
                    }
                    break;
                }
                }
            }
        }
Exemplo n.º 4
0
        public static IEnumerable <(ExpressionPreset, string, UniGLTF.Extensions.VRMC_vrm.Expression)> Migrate(UniGLTF.glTF gltf, JsonNode json,
                                                                                                               MigrationVrm.MeshIndexToNodeIndexFunc meshToNode)
        {
            foreach (var blendShapeClip in json["blendShapeGroups"].ArrayItems())
            {
                var name     = blendShapeClip["name"].GetString();
                var isBinary = false;
                if (blendShapeClip.TryGet("isBinary", out JsonNode isBinaryNode))
                {
                    isBinary = isBinaryNode.GetBoolean();
                }
                var preset     = ToPreset(blendShapeClip["presetName"], name);
                var expression = new UniGLTF.Extensions.VRMC_vrm.Expression
                {
                    IsBinary              = isBinary,
                    MorphTargetBinds      = new List <UniGLTF.Extensions.VRMC_vrm.MorphTargetBind>(),
                    MaterialColorBinds    = new List <UniGLTF.Extensions.VRMC_vrm.MaterialColorBind>(),
                    TextureTransformBinds = new List <UniGLTF.Extensions.VRMC_vrm.TextureTransformBind>(),
                };
                expression.MorphTargetBinds = ToMorphTargetBinds(blendShapeClip["binds"], meshToNode).ToList();

                if (blendShapeClip.TryGet("materialValues", out JsonNode materialValues))
                {
                    ToMaterialColorBinds(gltf, materialValues, expression);
                }

                yield return(preset, name, expression);
            }
        }