Esempio n. 1
0
        /// <summary>
        /// * Position, Normal の Z座標に -1 を乗算する
        /// * Rotation => Axis Angle に分解 => Axis の Z座標に -1 を乗算。Angle に -1 を乗算
        /// * Triangle の index を 0, 1, 2 から 2, 1, 0 に反転する
        /// </summary>
        static void ReverseAxisAndFlipTriangle(this Model model, Reverser reverser, bool ignoreVrm)
        {
            foreach (var g in model.MeshGroups)
            {
                foreach (var m in g.Meshes)
                {
                    foreach (var(k, v) in m.VertexBuffer)
                    {
                        if (k == VertexBuffer.PositionKey || k == VertexBuffer.NormalKey)
                        {
                            reverser.ReverseBuffer(v);
                        }
                        else if (k == VertexBuffer.TangentKey)
                        {
                            // I don't know
                        }
                    }

                    switch (m.IndexBuffer.ComponentType)
                    {
                    case AccessorValueType.UNSIGNED_BYTE:
                        FlipTriangle(SpanLike.Wrap <Byte>(m.IndexBuffer.Bytes));
                        break;

                    case AccessorValueType.UNSIGNED_SHORT:
                        FlipTriangle(SpanLike.Wrap <UInt16>(m.IndexBuffer.Bytes));
                        break;

                    case AccessorValueType.UNSIGNED_INT:
                        FlipTriangle(SpanLike.Wrap <UInt32>(m.IndexBuffer.Bytes));
                        break;

                    default:
                        throw new NotImplementedException();
                    }

                    foreach (var mt in m.MorphTargets)
                    {
                        foreach (var(k, v) in mt.VertexBuffer)
                        {
                            if (k == VertexBuffer.PositionKey || k == VertexBuffer.NormalKey)
                            {
                                reverser.ReverseBuffer(v);
                            }
                            if (k == VertexBuffer.TangentKey)
                            {
                                // I don't know
                            }
                        }
                    }
                }
            }

            // 親から順に処理する
            // Rootは原点決め打ちのノード(GLTFに含まれない)
            foreach (var n in model.Root.Traverse().Skip(1))
            {
                n.SetMatrix(reverser.ReverseMatrix(n.Matrix), false);
            }
            // 親から順に処理したので不要
            // model.Root.CalcWorldMatrix();

            foreach (var s in model.Skins)
            {
                if (s.InverseMatrices != null)
                {
                    reverser.ReverseBuffer(s.InverseMatrices);
                }
            }

            foreach (var a in model.Animations)
            {
                // TODO:
            }
        }
        /// <summary>
        /// * Position, Normal の Z座標に -1 を乗算する
        /// * Rotation => Axis Angle に分解 => Axis の Z座標に -1 を乗算。Angle に -1 を乗算
        /// * Triangle の index を 0, 1, 2 から 2, 1, 0 に反転する
        /// </summary>
        static void ReverseAxisAndFlipTriangle(this Model model, Reverser reverser, bool ignoreVrm)
        {
            foreach (var g in model.MeshGroups)
            {
                foreach (var m in g.Meshes)
                {
                    foreach (var(k, v) in m.VertexBuffer)
                    {
                        if (k == VertexBuffer.PositionKey || k == VertexBuffer.NormalKey)
                        {
                            reverser.ReverseBuffer(v);
                        }
                        else if (k == VertexBuffer.TangentKey)
                        {
                            // I don't know
                        }
                    }

                    switch (m.IndexBuffer.ComponentType)
                    {
                    case AccessorValueType.UNSIGNED_BYTE:
                        FlipTriangle(SpanLike.Wrap <Byte>(m.IndexBuffer.Bytes));
                        break;

                    case AccessorValueType.UNSIGNED_SHORT:
                        FlipTriangle(SpanLike.Wrap <UInt16>(m.IndexBuffer.Bytes));
                        break;

                    case AccessorValueType.UNSIGNED_INT:
                        FlipTriangle(SpanLike.Wrap <UInt32>(m.IndexBuffer.Bytes));
                        break;

                    default:
                        throw new NotImplementedException();
                    }

                    foreach (var mt in m.MorphTargets)
                    {
                        foreach (var(k, v) in mt.VertexBuffer)
                        {
                            if (k == VertexBuffer.PositionKey || k == VertexBuffer.NormalKey)
                            {
                                reverser.ReverseBuffer(v);
                            }
                            if (k == VertexBuffer.TangentKey)
                            {
                                // I don't know
                            }
                        }
                    }
                }
            }

            // 親から順に処理する
            // Rootは原点決め打ちのノード(GLTFに含まれない)
            foreach (var n in model.Root.Traverse().Skip(1))
            {
                n.SetMatrix(reverser.ReverseMatrix(n.Matrix), false);
            }
            // 親から順に処理したので不要
            // model.Root.CalcWorldMatrix();

            foreach (var s in model.Skins)
            {
                if (s.InverseMatrices != null)
                {
                    reverser.ReverseBuffer(s.InverseMatrices);
                }
            }

            foreach (var a in model.Animations)
            {
                // TODO:
            }

            if (model.Vrm != null)
            {
                if (!ignoreVrm)
                {
                    // LookAt
                    if (model.Vrm.LookAt != null)
                    {
                        model.Vrm.LookAt.OffsetFromHeadBone = reverser.ReverseVector3(model.Vrm.LookAt.OffsetFromHeadBone);
                    }

                    // SpringBone
                    if (model.Vrm.SpringBone != null)
                    {
                        foreach (var b in model.Vrm.SpringBone.Springs)
                        {
                            foreach (var c in b.Colliders)
                            {
                                for (int i = 0; i < c.Colliders.Count; ++i)
                                {
                                    var s = c.Colliders[i];
                                    switch (s.ColliderType)
                                    {
                                    case VrmSpringBoneColliderTypes.Sphere:
                                        c.Colliders[i] = VrmSpringBoneCollider.CreateSphere(reverser.ReverseVector3(s.Offset), s.Radius);
                                        break;

                                    case VrmSpringBoneColliderTypes.Capsule:
                                        c.Colliders[i] = VrmSpringBoneCollider.CreateCapsule(reverser.ReverseVector3(s.Offset), s.Radius, reverser.ReverseVector3(s.CapsuleTail));
                                        break;

                                    default:
                                        throw new NotImplementedException();
                                    }
                                }
                            }

                            foreach (var j in b.Joints)
                            {
                                j.GravityDir = reverser.ReverseVector3(j.GravityDir);
                            }
                        }
                    }
                }
            }
        }