예제 #1
0
            // https://github.com/vrm-c/vrm-specification/pull/255
            // 1.0 では末端に7cmの遠さに joint を追加する動作をしなくなった。
            // その差異に対応して、7cmの遠さに node を追加する。
            SpringBoneJoint AddTail7cm(int lastIndex)
            {
                var last  = _gltf.nodes[lastIndex];
                var name  = last.name ?? "";
                var v1    = new UnityEngine.Vector3(last.translation[0], last.translation[1], last.translation[2]);
                var delta = v1.normalized * 0.07f; // 7cm
                var tail  = new UniGLTF.glTFNode
                {
                    name        = name + "_end",
                    translation = new float[] {
                        delta.x,
                        delta.y,
                        delta.z
                    },
                };
                var tail_index = _gltf.nodes.Count;

                _gltf.nodes.Add(tail);
                if (last.children != null && last.children.Length > 0)
                {
                    throw new System.Exception();
                }
                last.children = new[] { tail_index };

                // 1.0 では、head + tail のペアでスプリングを表し、
                // 揺れ挙動のパラメーターは head の方に入る。
                // 要するに 末端の joint では Node しか使われない。
                return(new SpringBoneJoint
                {
                    Node = tail_index,
                });
            }
예제 #2
0
        static void AddTail7cm(UniGLTF.glTF gltf, UniGLTF.glTFNode[] joints)
        {
            if (joints.Length < 2)
            {
                return;
            }
            var last = joints.Last();
            var name = last.name ?? "";
            var v1   = new UnityEngine.Vector3(last.translation[0], last.translation[1], last.translation[2]);
            // var last2 = joints[joints.Length - 2];
            // var v2 = new UnityEngine.Vector3(last2.translation[0], last2.translation[1], last2.translation[2]);
            var delta = v1.normalized * 0.07f; // 7cm
            var tail  = new UniGLTF.glTFNode
            {
                name        = name + "_end",
                translation = new float[] {
                    delta.x,
                    delta.y,
                    delta.z
                },
            };
            var tail_index = gltf.nodes.Count;

            gltf.nodes.Add(tail);
            if (last.children != null && last.children.Length > 0)
            {
                throw new System.Exception();
            }
            last.children = new[] { tail_index };
        }
예제 #3
0
            /// <summary>
            ///
            /// </summary>
            /// <param name="node"></param>
            /// <param name="level">children[0] のみカウントアップする。その他は0にリセットする</param>
            /// <param name="spring"></param>
            void CreateJointsRecursive(UniGLTF.glTFNode node, int level, Spring spring = null)
            {
                if (spring == null && level > 0)
                {
                    // 2番目以降の子ノードの子から新しい Spring を作る。
                    spring = CreateSpring();
                }
                if (spring != null)
                {
                    // level==0 のとき(2番目以降の兄弟ボーン)は飛ばす
                    spring.Joints.Add(CreateJoint(_gltf.nodes.IndexOf(node)));
                }

                if (node.children != null && node.children.Length > 0)
                {
                    for (int i = 0; i < node.children.Length; ++i)
                    {
                        var childIndex = node.children[i];
                        if (childIndex < 0 || childIndex >= _gltf.nodes.Count)
                        {
                            // -1 など?
                            continue;
                        }

                        if (i == 0)
                        {
                            // spring に joint を追加する
                            CreateJointsRecursive(_gltf.nodes[childIndex], level + 1, spring);
                        }
                        else
                        {
                            // 再帰
                            CreateJointsRecursive(_gltf.nodes[childIndex], 0);
                        }
                    }
                }
                else
                {
                    if (spring != null && spring.Joints.Count > 0)
                    {
                        var last = spring.Joints.Last().Node;
                        if (last.HasValue)
                        {
                            var tailJoint = AddTail7cm(last.Value);
                            spring.Joints.Add(tailJoint);
                        }
                    }
                }
            }
예제 #4
0
        public static Node CreateDrawable(int i, UniGLTF.glTFNode node)
        {
            var name     = $"[{i}]{node.name}";
            var drawable = new Node(name);

            if (node.matrix != null)
            {
                var m = new Matrix(node.matrix);
                //m.Transpose();
                drawable.LocalMatrix = m;
            }
            else
            {
                var t = Vector3.Zero;
                var r = Quaternion.Identity;
                var s = Vector3.One;

                if (node.translation != null)
                {
                    t.X = node.translation[0];
                    t.Y = node.translation[1];
                    t.Z = node.translation[2];
                }

                if (node.rotation != null)
                {
                    r.X = node.rotation[0];
                    r.Y = node.rotation[1];
                    r.Z = node.rotation[2];
                    r.W = node.rotation[3];
                }

                if (node.scale != null)
                {
                    s.X = node.scale[0];
                    s.Y = node.scale[1];
                    s.Z = node.scale[2];
                }

                var m = Matrix.Transformation(Vector3.Zero, Quaternion.Identity, s, Vector3.Zero, r, t);
                drawable.LocalMatrix = m;
            }

            return(drawable);
        }
        static IEnumerable <UniGLTF.glTFNode> EnumJoint(List <UniGLTF.glTFNode> nodes, UniGLTF.glTFNode node)
        {
            yield return(node);

            if (node.children != null && node.children.Length > 0)
            {
                foreach (var x in EnumJoint(nodes, nodes[node.children[0]]))
                {
                    yield return(x);
                }
            }
        }
예제 #6
0
        static IEnumerable <UniGLTF.glTFNode> TraverseFirstChild(List <UniGLTF.glTFNode> nodes, UniGLTF.glTFNode node)
        {
            yield return(node);

            if (node.children != null && node.children.Length > 0)
            {
                foreach (var x in TraverseFirstChild(nodes, nodes[node.children[0]]))
                {
                    yield return(x);
                }
            }
        }