Пример #1
0
        /// <summary>
        /// bone行列を更新します。
        /// </summary>
        protected void UpdateBoneMatrices(TMOFile tmo, TMOFrame tmo_frame)
        {
            if (tmo.nodes == null)
            {
                return;
            }

            if (tmo.w_hips_node != null)
            {
                //姉妹スライダによる変形
                Matrix local = Matrix.Scaling(slide_matrices.Local);

                //移動変位を設定
                local.M41 = translation.X;
                local.M42 = translation.Y;
                local.M43 = translation.Z;

                matrixStack.LoadMatrix(local);
                UpdateBoneMatrices(tmo.w_hips_node, tmo_frame);
            }
            foreach (TMONode tmo_node in tmo.root_nodes_except_w_hips)
            {
                //移動変位を設定
                Matrix local = Matrix.Translation(translation);

                matrixStack.LoadMatrix(local);
                UpdateBoneMatricesWithoutSlideMatrices(tmo_node, tmo_frame);
            }
        }
Пример #2
0
        /// <summary>
        /// フレームを補間します。
        /// </summary>
        /// <param name="frame0">フレーム0</param>
        /// <param name="frame1">フレーム1</param>
        /// <param name="frame2">フレーム2</param>
        /// <param name="frame3">フレーム3</param>
        /// <param name="length">分割数</param>
        /// <param name="p1">補間速度係数</param>
        /// <param name="id_pair">node idのペア</param>
        /// <returns></returns>
        public static TMOFrame[] Slerp(TMOFrame frame0, TMOFrame frame1, TMOFrame frame2, TMOFrame frame3, int length, float p1, int[] id_pair)
        {
            TMOFrame[] frames = new TMOFrame[length];

            for (int frame_index = 0; frame_index < length; frame_index++)
            {
                frames[frame_index]          = new TMOFrame(frame_index);
                frames[frame_index].matrices = new TMOMat[frame1.matrices.Length];
            }

            for (int i = 0; i < frame1.matrices.Length; i++)
            {
                TMOMat[] interpolated_matrices = TMOMat.Slerp(
                    frame0.matrices[i],
                    frame1.matrices[i],
                    frame2.matrices[id_pair[i]],
                    frame3.matrices[id_pair[i]],
                    length,
                    p1);

                for (int frame_index = 0; frame_index < length; frame_index++)
                {
                    frames[frame_index].matrices[i] = interpolated_matrices[frame_index];
                }
            }
            return(frames);
        }
Пример #3
0
        /// <summary>
        /// bone行列を更新します。
        /// </summary>
        protected void UpdateBoneMatrices(TMONode tmo_node, TMOFrame tmo_frame)
        {
            matrixStack.Push();

            if (tmo_frame != null)
            {
                // tmo animation
                tmo_node.TransformationMatrix = tmo_frame.matrices[tmo_node.Id].m;
            }
            Matrix m = tmo_node.TransformationMatrix;

            if (slider_matrix != null)
            {
                bool chichi_p = re_chichi.IsMatch(tmo_node.Name);

                if (chichi_p)
                {
                    slider_matrix.ScaleChichi(tmo_node, ref m);

                    if (slider_matrix.Flat())
                    {
                        if (clothed)
                        {
                            slider_matrix.TransformChichiFlatClothed(tmo_node, ref m);
                        }
                        else
                        {
                            slider_matrix.TransformChichiFlat(tmo_node, ref m);
                        }
                    }
                }
                else
                {
                    slider_matrix.TransformFace(tmo_node, ref m);
                }

                matrixStack.MultiplyMatrixLocal(m);
                m = matrixStack.Top;

                if (!chichi_p)
                {
                    slider_matrix.Scale(tmo_node, ref m);
                }
            }
            else
            {
                matrixStack.MultiplyMatrixLocal(m);
                m = matrixStack.Top;
            }

            tmo_node.combined_matrix = m;

            foreach (TMONode child_node in tmo_node.children)
            {
                UpdateBoneMatrices(child_node, tmo_frame);
            }

            matrixStack.Pop();
        }
Пример #4
0
        /// <summary>
        /// frame1の行列で構成された新たなframeを得ます。
        /// 新たなframeはframe0と同じnode並びとなります。
        /// </summary>
        /// <param name="frame0"></param>
        /// <param name="frame1"></param>
        /// <param name="id_pair">node idのペア</param>
        /// <returns>新たなframe</returns>
        public static TMOFrame Select(TMOFrame frame0, TMOFrame frame1, int[] id_pair)
        {
            TMOFrame ret = new TMOFrame(0);

            ret.matrices = new TMOMat[frame0.matrices.Length];
            for (int i = 0; i < frame0.matrices.Length; i++)
            {
                ret.matrices[i] = frame1.matrices[id_pair[i]];
            }
            return(ret);
        }
Пример #5
0
        /// <summary>
        /// 加減算の結果として新たなframeを得ます。
        /// 新たなframeはframe0と同じnode並びとなります。
        /// </summary>
        /// <param name="frame0">frame0</param>
        /// <param name="frame1">frame1</param>
        /// <param name="frame2">frame2</param>
        /// <param name="id_pair">node idのペア</param>
        /// <returns>新たなframe</returns>
        public static TMOFrame AddSub(TMOFrame frame0, TMOFrame frame1, TMOFrame frame2, int[] id_pair)
        {
            TMOFrame ret = new TMOFrame(0);

            ret.matrices = new TMOMat[frame0.matrices.Length];
            for (int i = 0; i < frame0.matrices.Length; i++)
            {
                ret.matrices[i] = TMOMat.AddSub(frame0.matrices[i], frame1.matrices[id_pair[i]], frame2.matrices[id_pair[i]]);
            }
            return(ret);
        }
Пример #6
0
        /// <summary>
        /// bone行列を更新します(体型変更なし)。
        /// </summary>
        /// <param name="forced">falseの場合frame indexに変更なければ更新しません。</param>
        public void UpdateBoneMatricesWithoutSlider(bool forced = false)
        {
            if (!forced && frame_index == current_frame_index)
            {
                return;
            }
            current_frame_index = frame_index;

            TMOFrame tmo_frame = GetTMOFrame();

            UpdateBoneMatricesWithoutSlider(tmo, tmo_frame);
        }
Пример #7
0
        /// <summary>
        /// bone行列を更新します。
        /// </summary>
        protected void UpdateBoneMatrices(TMONode tmo_node, TMOFrame tmo_frame)
        {
            if (tmo_frame != null)
            {
                // TMO animation
                tmo_node.TransformationMatrix = tmo_frame.matrices[tmo_node.ID].m;
            }
            Matrix m = tmo_node.TransformationMatrix;

            bool chichi_p = re_chichi.IsMatch(tmo_node.Name);

            if (chichi_p)
            {
                if (slider_matrix.Flat())
                {
                    slider_matrix.TransformChichiFlat(tmo_node, ref m);
                }
                else
                {
                    slider_matrix.TranslateChichi(ref m);
                }
            }
            else
            {
                // todo: face_p
                slider_matrix.TransformFace(tmo_node, ref m);
            }

            matrixStack.Push(m * matrixStack.Peek());
            m = matrixStack.Peek();

            if (chichi_p)
            {
                if (!slider_matrix.Flat())
                {
                    slider_matrix.ScaleChichi(ref m);
                }
            }
            else
            {
                // todo: scale1map
                slider_matrix.Scale(tmo_node, ref m);
            }

            tmo_node.combined_matrix = m;

            foreach (TMONode child_node in tmo_node.children)
            {
                UpdateBoneMatrices(child_node, tmo_frame);
            }

            matrixStack.Pop();
        }
Пример #8
0
        /// <summary>
        /// bone行列を更新します。
        /// </summary>
        /// <param name="forced">falseの場合frame indexに変更なければ更新しません。</param>
        public void UpdateBoneMatrices(bool forced)
        {
            if (!forced && frame_index == current_frame_index)
            {
                return;
            }
            current_frame_index = frame_index;

            TMOFrame tmo_frame = GetTMOFrame();

            UpdateBoneMatrices(tmo, tmo_frame);
        }
Пример #9
0
        /// <summary>
        /// bone行列を更新します。
        /// </summary>
        protected void UpdateBoneMatrices(TMONode tmo_node, TMOFrame tmo_frame)
        {
            matrixStack.Push();

            if (tmo_frame != null)
            {
                // TMO animation
                tmo_node.TransformationMatrix = tmo_frame.matrices[tmo_node.ID].m;
            }
            Matrix m = tmo_node.TransformationMatrix;

            bool is_chichi = re_chichi.IsMatch(tmo_node.Name);

            if (is_chichi)
            {
                if (slide_matrices.Flat())
                {
                    slide_matrices.TransformChichiFlat(tmo_node, ref m);
                }
            }
            else
            {
                slide_matrices.TransformFace(tmo_node, ref m);
            }

            matrixStack.MultiplyMatrixLocal(m);
            m = matrixStack.Top;

            if (is_chichi)
            {
                if (!slide_matrices.Flat())
                {
                    slide_matrices.ScaleChichi(ref m);
                }
            }
            else
            {
                slide_matrices.Scale(tmo_node, ref m);
            }

            tmo_node.combined_matrix = m;

            foreach (TMONode child_node in tmo_node.children)
            {
                UpdateBoneMatrices(child_node, tmo_frame);
            }

            matrixStack.Pop();
        }
Пример #10
0
        /// <summary>
        /// 指定tmoからフレームを追加します。
        /// </summary>
        /// <param name="motion">tmo</param>
        public void AppendFrameFrom(TMOFile motion)
        {
            int[] id_pair = CreateNodeIdPair(motion);

            TMOFrame source_frame = frames[0];
            int append_length = motion.frames.Length;
            TMOFrame[] append_frames = new TMOFrame[append_length];
            for (int i = 0; i < motion.frames.Length; i++)
                append_frames[i] = TMOFrame.Select(source_frame, motion.frames[i], id_pair);

            int old_length = frames.Length;
            Array.Resize(ref frames, frames.Length + append_length);
            Array.Copy(append_frames, 0, frames, old_length, append_length);
            this.opt0 = frames.Length-1;
        }
Пример #11
0
        /// <summary>
        /// bone行列を更新します。
        /// </summary>
        /// <param name="forced">falseの場合frame indexに変更なければ更新しません。</param>
        public void UpdateBoneMatrices(bool forced = false)
        {
            if (!forced && frame_index == current_frame_index)
            {
                return;
            }
            current_frame_index = frame_index;

            TMOFrame tmo_frame = GetTMOFrame();

            UpdateBoneMatrices(tmo, tmo_frame);

            if (UpdateBoneMatricesEvent != null)
            {
                UpdateBoneMatricesEvent(this, EventArgs.Empty);
            }
        }
Пример #12
0
        /// <summary>
        /// 指定ストリームから読み込みます。
        /// </summary>
        /// <param name="source_stream">ストリーム</param>
        public void Load(Stream source_stream)
        {
            this.reader = new BinaryReader(source_stream, System.Text.Encoding.Default);

            byte[] magic = reader.ReadBytes(4);

            if (magic[0] != (byte)'T' ||
                magic[1] != (byte)'M' ||
                magic[2] != (byte)'O' ||
                magic[3] != (byte)'1')
            {
                throw new Exception("File is not TMO");
            }

            this.header = reader.ReadBytes(8);
            this.opt0   = reader.ReadInt32();
            this.opt1   = reader.ReadInt32();

            int node_count = reader.ReadInt32();

            nodes = new TMONode[node_count];
            for (int i = 0; i < node_count; i++)
            {
                nodes[i] = new TMONode(i);
                nodes[i].Read(reader);
            }

            GenerateNodemapAndTree();

            int frame_count = reader.ReadInt32();

            frames = new TMOFrame[frame_count];

            for (int i = 0; i < frame_count; i++)
            {
                frames[i] = new TMOFrame(i);
                frames[i].Read(reader);
            }

            foreach (TMONode node in nodes)
            {
                node.LinkMatrices(frames);
            }

            this.footer = reader.ReadBytes(4);
        }
Пример #13
0
        /// <summary>
        /// bone行列を更新します(体型変更なし)。
        /// </summary>
        protected void UpdateBoneMatricesWithoutSlider(TMOFile tmo, TMOFrame tmo_frame)
        {
            if (tmo.nodes == null)
            {
                return;
            }

            if (tmo.w_hips_node != null)
            {
                matrixStack.LoadIdentity();
                UpdateBoneMatricesWithoutSlider(tmo.w_hips_node, tmo_frame);
            }
            foreach (TMONode tmo_node in tmo.root_nodes_except_w_hips)
            {
                matrixStack.LoadIdentity();
                UpdateBoneMatricesWithoutSlider(tmo_node, tmo_frame);
            }
        }
Пример #14
0
        /// <summary>
        /// 指定tmoからフレームを追加します。
        /// </summary>
        /// <param name="motion">tmo</param>
        public void AppendFrameFrom(TMOFile motion)
        {
            int[] id_pair = CreateNodeIdPair(motion);

            TMOFrame source_frame  = frames[0];
            int      append_length = motion.frames.Length;

            TMOFrame[] append_frames = new TMOFrame[append_length];
            for (int i = 0; i < motion.frames.Length; i++)
            {
                append_frames[i] = TMOFrame.Select(source_frame, motion.frames[i], id_pair);
            }

            int old_length = frames.Length;

            Array.Resize(ref frames, frames.Length + append_length);
            Array.Copy(append_frames, 0, frames, old_length, append_length);
            this.opt0 = frames.Length - 1;
        }
Пример #15
0
        public void CopyMotionFrom(TMOFile motion)
        {
            int[] index_pair = CreateNodeIdPair(motion);

            TMOFrame source_frame  = frames[0];
            TMOFrame motion_frame  = motion.frames[0];
            int      append_length = motion.frames.Length;

            TMOFrame[] interp_frames = new TMOFrame[append_length];
            for (int i = 0; i < motion.frames.Length; i++)
            {
                interp_frames[i] = TMOFrame.AddSub(source_frame, motion.frames[i], motion_frame, index_pair);
            }

            int old_length = frames.Length;

            Array.Resize(ref frames, frames.Length + append_length);
            Array.Copy(interp_frames, 0, frames, old_length, append_length);
            this.opt0 = frames.Length - 1;
        }
Пример #16
0
        //初期モーション行列値を保持する領域を確保します。
        private void CreateFrames()
        {
            if (tmo.frames == null)
            {
                return;
            }

            int frame_count = tmo.frames.Length;

            frames = new TMOFrame[frame_count];
            for (int i = 0; i < frame_count; i++)
            {
                int matrix_count = tmo.frames[i].matrices.Length;
                frames[i]          = new TMOFrame(i);
                frames[i].matrices = new TMOMat[matrix_count];
                for (int j = 0; j < matrix_count; j++)
                {
                    frames[i].matrices[j] = new TMOMat();
                }
            }
        }
Пример #17
0
        /// <summary>
        /// 指定tmoへフレームを補間します。
        /// </summary>
        /// <param name="motion">tmo</param>
        /// <param name="append_length">補間するフレーム長さ</param>
        /// <param name="p1">補間速度係数</param>
        public void SlerpFrameEndTo(TMOFile motion, int append_length, float p1)
        {
            int[] id_pair = CreateNodeIdPair(motion);

            int i0 = (frames.Length > 1) ? frames.Length - 1 - 1 : 0;
            int i1 = frames.Length - 1;
            int i2 = 0;
            int i3 = (motion.frames.Length > 1) ? 1 : 0;

            TMOFrame frame0 = frames[i0];
            TMOFrame frame1 = frames[i1];
            TMOFrame frame2 = motion.frames[i2];
            TMOFrame frame3 = motion.frames[i3];

            TMOFrame[] interp_frames = TMOFrame.Slerp(frame0, frame1, frame2, frame3, append_length, p1, id_pair);
            int        old_length    = frames.Length;

            Array.Resize(ref frames, frames.Length + append_length);
            Array.Copy(interp_frames, 0, frames, old_length, append_length);
            this.opt0 = frames.Length - 1;
        }
Пример #18
0
        /// <summary>
        /// bone行列を更新します。
        /// </summary>
        protected void UpdateBoneMatrices(TMOFile tmo, TMOFrame tmo_frame)
        {
            if (tmo.nodes == null)
            {
                return;
            }

            //先頭nodeをrootとみなす
            TMONode tmo_node = tmo.nodes[0];

            //姉妹スライダによる変形
            Matrix local = Matrix.Scaling(slide_matrices.Local);

            //移動変位を設定
            local.M41 = translation.X;
            local.M42 = translation.Y;
            local.M43 = translation.Z;

            matrixStack.LoadMatrix(local);
            UpdateBoneMatrices(tmo_node, tmo_frame);
        }
Пример #19
0
        /// <summary>
        /// 指定番号のフレームに含まれるモーション行列値を変形します。
        /// </summary>
        /// <param name="frame_index">フレーム番号</param>
        public void Transform(int frame_index)
        {
            if (ratio == 0)
            {
                return;
            }

            if (tmo.frames == null)
            {
                return;
            }

            TMOFrame frame = tmo.frames[frame_index];

            Debug.Assert(frame.matrices.Length == nodes.Length);
            for (int j = 0; j < frame.matrices.Length; j++)
            {
                TPONode node = nodes[j];
                TMOMat  mat  = frame.matrices[j];
                node.Transform(mat, ratio);
            }
        }
Пример #20
0
        /// <summary>
        /// bone行列を更新します(体型変更なし)。
        /// </summary>
        protected void UpdateBoneMatricesWithoutSlideMatrices(TMONode tmo_node, TMOFrame tmo_frame)
        {
            //matrixStack.Push();

            if (tmo_frame != null)
            {
                // TMO animation
                tmo_node.TransformationMatrix = tmo_frame.matrices[tmo_node.ID].m;
            }
            Matrix m = tmo_node.TransformationMatrix;

            matrixStack.Push(m * matrixStack.Peek());
            m = matrixStack.Peek();

            tmo_node.combined_matrix = m;

            foreach (TMONode child_node in tmo_node.children)
            {
                UpdateBoneMatrices(child_node, tmo_frame);
            }

            matrixStack.Pop();
        }
Пример #21
0
        /// <summary>
        /// bone行列を更新します(体型変更なし)。
        /// </summary>
        protected void UpdateBoneMatricesWithoutSlider(TMONode tmo_node, TMOFrame tmo_frame)
        {
            matrixStack.Push();

            if (tmo_frame != null)
            {
                // tmo animation
                tmo_node.TransformationMatrix = tmo_frame.matrices[tmo_node.Id].m;
            }
            Matrix m = tmo_node.TransformationMatrix;

            matrixStack.MultiplyMatrixLocal(m);
            m = matrixStack.Top;

            tmo_node.combined_matrix = m;

            foreach (TMONode child_node in tmo_node.children)
            {
                UpdateBoneMatricesWithoutSlider(child_node, tmo_frame);
            }

            matrixStack.Pop();
        }
Пример #22
0
        /// <summary>
        /// bone行列を更新します(体型変更なし)。
        /// </summary>
        protected void UpdateBoneMatricesWithoutSlider(TMOFile tmo, TMOFrame tmo_frame)
        {
            if (tmo.nodes == null)
            {
                return;
            }

            if (tmo.w_hips_node != null)
            {
                //移動変位を設定
                Matrix local = Matrix.Translation(translation);

                matrixStack.LoadMatrix(local);
                UpdateBoneMatricesWithoutSlider(tmo.w_hips_node, tmo_frame);
            }
            foreach (TMONode tmo_node in tmo.root_nodes_except_w_hips)
            {
                //移動変位を設定
                Matrix local = Matrix.Translation(translation);

                matrixStack.LoadMatrix(local);
                UpdateBoneMatricesWithoutSlider(tmo_node, tmo_frame);
            }
        }
Пример #23
0
        //初期モーション行列値を保持する領域を確保します。
        private void CreateFrames()
        {
            if (tmo.frames == null)
            return;

            int frame_count = tmo.frames.Length;
            frames = new TMOFrame[frame_count];
            for (int i = 0; i < frame_count; i++)
            {
            int matrix_count = tmo.frames[i].matrices.Length;
            frames[i] = new TMOFrame(i);
            frames[i].matrices = new TMOMat[matrix_count];
            for (int j = 0; j < matrix_count; j++)
            {
                frames[i].matrices[j] = new TMOMat();
            }
            }
        }
Пример #24
0
        public void Load(Stream source_stream)
        {
            this.reader = new BinaryReader(source_stream, System.Text.Encoding.Default);

            byte[] magic = reader.ReadBytes(4);

            if (magic[0] != (byte)'T' ||
                magic[1] != (byte)'M' ||
                magic[2] != (byte)'O' ||
                magic[3] != (byte)'1')
            {
                throw new Exception("File is not TMO");
            }

            this.header = reader.ReadBytes(8);
            this.opt0   = reader.ReadInt32();
            this.opt1   = reader.ReadInt32();

            int node_count = reader.ReadInt32();

            nodes   = new TMONode[node_count];
            nodemap = new Dictionary <string, TMONode>();

            for (int i = 0; i < node_count; i++)
            {
                nodes[i]       = new TMONode();
                nodes[i].id    = i;
                nodes[i].name  = ReadString();
                nodes[i].sname = nodes[i].name.Substring(nodes[i].name.LastIndexOf('|') + 1);
                nodemap.Add(nodes[i].name, nodes[i]);

                //Console.WriteLine(i + ": " + nodes[i].name);
            }

            for (int i = 0; i < node_count; i++)
            {
                int index = nodes[i].name.LastIndexOf('|');
                if (index <= 0)
                {
                    continue;
                }
                string pname = nodes[i].name.Substring(0, index);
                nodes[i].parent = nodemap[pname];
                nodes[i].parent.children.Add(nodes[i]);
            }

            int frame_count = reader.ReadInt32();

            frames = new TMOFrame[frame_count];

            for (int i = 0; i < frame_count; i++)
            {
                frames[i]    = new TMOFrame();
                frames[i].id = i;

                int matrix_count = reader.ReadInt32();
                frames[i].matrices = new TMOMat[matrix_count];

                for (int j = 0; j < matrix_count; j++)
                {
                    frames[i].matrices[j] = new TMOMat(ReadMatrix());
                    nodes[j].frame_matrices.Add(frames[i].matrices[j]);

                    //Console.WriteLine(frames[i].matrices[j].m);
                }
            }

            this.footer = reader.ReadBytes(4);

            reader.Close();
        }
Пример #25
0
        /// <summary>
        /// bone行列を更新します。
        /// </summary>
        protected void UpdateBoneMatrices(TMONode tmo_node, TMOFrame tmo_frame)
        {
            matrixStack.Push();

            if (tmo_frame != null)
            {
                // TMO animation
                tmo_node.TransformationMatrix = tmo_frame.matrices[tmo_node.ID].m;
            }
            Matrix m = tmo_node.TransformationMatrix;

            bool is_chichi = re_chichi.IsMatch(tmo_node.Name);

            if (is_chichi && slide_matrices.Flat())
            {
                switch (tmo_node.Name)
                {
                case "Chichi_Right1":
                    m *= slide_matrices.ChichiR1;
                    break;

                case "Chichi_Right2":
                    m *= slide_matrices.ChichiR2;
                    break;

                case "Chichi_Right3":
                    m *= slide_matrices.ChichiR3;
                    break;

                case "Chichi_Right4":
                    m *= slide_matrices.ChichiR4;
                    break;

                case "Chichi_Right5":
                    m *= slide_matrices.ChichiR5;
                    break;

                case "Chichi_Right5_end":
                    m *= slide_matrices.ChichiR5E;
                    break;

                case "Chichi_Left1":
                    m *= slide_matrices.ChichiL1;
                    break;

                case "Chichi_Left2":
                    m *= slide_matrices.ChichiL2;
                    break;

                case "Chichi_Left3":
                    m *= slide_matrices.ChichiL3;
                    break;

                case "Chichi_Left4":
                    m *= slide_matrices.ChichiL4;
                    break;

                case "Chichi_Left5":
                    m *= slide_matrices.ChichiL5;
                    break;

                case "Chichi_Left5_End":
                    m *= slide_matrices.ChichiL5E;
                    break;
                }

                // translationを維持する必要があるため
                // translationに対してscalingを打ち消す演算を行う。
                Vector3 scaling = slide_matrices.Chichi;

                m.M41 /= scaling.X;
                m.M42 /= scaling.Y;
                m.M43 /= scaling.Z;

                switch (tmo_node.Name)
                {
                case "Chichi_Right1":
                case "Chichi_Left1":
                    m *= Matrix.Scaling(scaling);
                    break;
                }
            }

            switch (tmo_node.Name)
            {
            case "face_oya":
                Scale1(ref m, slide_matrices.FaceOya);
                break;

            case "eyeline_sita_L":
            case "L_eyeline_oya_L":
            case "Me_Right_Futi":
                m *= slide_matrices.EyeR;
                break;

            case "eyeline_sita_R":
            case "R_eyeline_oya_R":
            case "Me_Left_Futi":
                m *= slide_matrices.EyeL;
                break;
            }

            matrixStack.MultiplyMatrixLocal(m);
            m = matrixStack.Top;

            // スライダによる体型変更
            // translationを維持する必要があるため
            // このscalingはmatrixStackに適用しない。
            switch (tmo_node.Name)
            {
            case "W_Spine_Dummy":
                Scale1(ref m, slide_matrices.SpineDummy);
                break;

            case "W_Spine1":
            case "W_Spine2":
                Scale1(ref m, slide_matrices.Spine1);
                break;

            case "W_LeftHips_Dummy":
            case "W_RightHips_Dummy":
                Scale1(ref m, slide_matrices.HipsDummy);
                break;

            case "W_LeftUpLeg":
            case "W_RightUpLeg":
                Scale1(ref m, slide_matrices.UpLeg);
                break;

            case "W_LeftUpLegRoll":
            case "W_RightUpLegRoll":
            case "W_LeftLeg":
            case "W_RightLeg":
                Scale1(ref m, slide_matrices.UpLegRoll);
                break;

            case "W_LeftLegRoll":
            case "W_RightLegRoll":
            case "W_LeftFoot":
            case "W_RightFoot":
            case "W_LeftToeBase":
            case "W_RightToeBase":
                Scale1(ref m, slide_matrices.LegRoll);
                break;

            case "W_LeftArm_Dummy":
            case "W_RightArm_Dummy":
                Scale1(ref m, slide_matrices.ArmDummy);
                break;

            case "W_LeftArm":
            case "W_RightArm":
            case "W_LeftArmRoll":
            case "W_RightArmRoll":
            case "W_LeftForeArm":
            case "W_RightForeArm":
            case "W_LeftForeArmRoll":
            case "W_RightForeArmRoll":
                Scale1(ref m, slide_matrices.Arm);
                break;
            }

            if (is_chichi && !slide_matrices.Flat())
            {
                Scale1(ref m, slide_matrices.Chichi);
            }

            tmo_node.combined_matrix = m;

            foreach (TMONode child_node in tmo_node.children)
            {
                UpdateBoneMatrices(child_node, tmo_frame);
            }

            matrixStack.Pop();
        }
Пример #26
0
 /// <summary>
 /// frame1の行列で構成された新たなframeを得ます。
 /// 新たなframeはframe0と同じnode並びとなります。
 /// </summary>
 /// <param name="frame0"></param>
 /// <param name="frame1"></param>
 /// <param name="id_pair">node idのペア</param>
 /// <returns>新たなframe</returns>
 public static TMOFrame Select(TMOFrame frame0, TMOFrame frame1, int[] id_pair)
 {
     TMOFrame ret = new TMOFrame(0);
     ret.matrices = new TMOMat[frame0.matrices.Length];
     for (int i = 0; i < frame0.matrices.Length; i++)
     {
         ret.matrices[i] = frame1.matrices[id_pair[i]];
     }
     return ret;
 }
Пример #27
0
        /// <summary>
        /// bone行列を更新します(体型変更なし)。
        /// </summary>
        protected void UpdateBoneMatricesWithoutSlideMatrices(TMONode tmo_node, TMOFrame tmo_frame)
        {
            //matrixStack.Push();

            if (tmo_frame != null)
            {
            // TMO animation
            tmo_node.TransformationMatrix = tmo_frame.matrices[tmo_node.ID].m;
            }
            Matrix m = tmo_node.TransformationMatrix;

            matrixStack.Push(m * matrixStack.Peek());
            m = matrixStack.Peek();

            tmo_node.combined_matrix = m;

            foreach (TMONode child_node in tmo_node.children)
            UpdateBoneMatrices(child_node, tmo_frame);

            matrixStack.Pop();
        }
Пример #28
0
        /// <summary>
        /// bone行列を更新します。
        /// </summary>
        protected void UpdateBoneMatrices(TMONode tmo_node, TMOFrame tmo_frame)
        {
            if (tmo_frame != null)
            {
            // TMO animation
            tmo_node.TransformationMatrix = tmo_frame.matrices[tmo_node.ID].m;
            }
            Matrix m = tmo_node.TransformationMatrix;

            bool chichi_p = re_chichi.IsMatch(tmo_node.Name);

            if (chichi_p)
            {
            if (slider_matrix.Flat())
                slider_matrix.TransformChichiFlat(tmo_node, ref m);
            else
                slider_matrix.TranslateChichi(ref m);
            }
            else
            // todo: face_p
            slider_matrix.TransformFace(tmo_node, ref m);

            matrixStack.Push(m * matrixStack.Peek());
            m = matrixStack.Peek();

            if (chichi_p)
            {
            if (! slider_matrix.Flat())
            {
                slider_matrix.ScaleChichi(ref m);
            }
            }
            else
            // todo: scale1map
            slider_matrix.Scale(tmo_node, ref m);

            tmo_node.combined_matrix = m;

            foreach (TMONode child_node in tmo_node.children)
            UpdateBoneMatrices(child_node, tmo_frame);

            matrixStack.Pop();
        }
Пример #29
0
 public static void Write(BinaryWriter bw, TMOFrame item)
 {
     Write(bw, item.matrices);
 }
Пример #30
0
 /// <summary>
 /// 加減算の結果として新たなframeを得ます。
 /// 新たなframeはframe0と同じnode並びとなります。
 /// </summary>
 /// <param name="frame0">frame0</param>
 /// <param name="frame1">frame1</param>
 /// <param name="frame2">frame2</param>
 /// <param name="id_pair">node idのペア</param>
 /// <returns>新たなframe</returns>
 public static TMOFrame AddSub(TMOFrame frame0, TMOFrame frame1, TMOFrame frame2, int[] id_pair)
 {
     TMOFrame ret = new TMOFrame(0);
     ret.matrices = new TMOMat[frame0.matrices.Length];
     for (int i = 0; i < frame0.matrices.Length; i++)
     {
         ret.matrices[i] = TMOMat.AddSub( frame0.matrices[i], frame1.matrices[id_pair[i]], frame2.matrices[id_pair[i]] );
     }
     return ret;
 }
Пример #31
0
        /// <summary>
        /// 指定tmoのモーション(開始フレームからの変位)を複写します。
        /// </summary>
        /// <param name="motion">tmo</param>
        public void CopyMotionFrom(TMOFile motion)
        {
            int[] id_pair = CreateNodeIdPair(motion);

            TMOFrame source_frame = frames[0];
            TMOFrame motion_frame = motion.frames[0];
            int append_length = motion.frames.Length;
            TMOFrame[] interp_frames = new TMOFrame[append_length];
            for (int i = 0; i < motion.frames.Length; i++)
                interp_frames[i] = TMOFrame.AddSub(source_frame, motion.frames[i], motion_frame, id_pair);

            int old_length = frames.Length;
            Array.Resize(ref frames, frames.Length + append_length);
            Array.Copy(interp_frames, 0, frames, old_length, append_length);
            this.opt0 = frames.Length-1;
        }
Пример #32
0
 /// <summary>
 /// 行列をリンクします。
 /// </summary>
 public void LinkMatrices(TMOFrame[] frames)
 {
     this.matrices.Clear();
     foreach (TMOFrame frame in frames)
         this.matrices.Add(frame.matrices[id]);
 }
Пример #33
0
        /// <summary>
        /// 指定ストリームから読み込みます。
        /// </summary>
        /// <param name="source_stream">ストリーム</param>
        public void Load(Stream source_stream)
        {
            this.reader = new BinaryReader(source_stream, System.Text.Encoding.Default);

            byte[] magic = reader.ReadBytes(4);

            if (magic[0] != (byte)'T' || magic[1] != (byte)'M' || magic[2] != (byte)'O' || magic[3] != (byte)'1')
                throw new Exception("File is not TMO");

            this.header = reader.ReadBytes(8);
            this.opt0 = reader.ReadInt32();
            this.opt1 = reader.ReadInt32();

            int node_count = reader.ReadInt32();
            nodes = new TMONode[node_count];
            for (int i = 0; i < node_count; i++)
            {
                nodes[i] = new TMONode(i);
                nodes[i].Read(reader);
            }

            GenerateNodemapAndTree();

            int frame_count = reader.ReadInt32();
            frames = new TMOFrame[frame_count];

            for (int i = 0; i < frame_count; i++)
            {
                frames[i] = new TMOFrame(i);
                frames[i].Read(reader);
            }

            foreach (TMONode node in nodes)
                node.LinkMatrices(frames);

            this.footer = reader.ReadBytes(4);
        }
Пример #34
0
        /// <summary>
        /// bone行列を更新します。
        /// </summary>
        protected void UpdateBoneMatrices(TMOFile tmo, TMOFrame tmo_frame)
        {
            if (tmo.nodes == null)
            return;

            if (tmo.w_hips_node != null)
            {
            //姉妹スライダによる変形
            Matrix local = Matrix.Scaling(slider_matrix.Local);

            //移動変位を設定
            local.M41 = translation.X;
            local.M42 = translation.Y;
            local.M43 = translation.Z;

            matrixStack.Push(local);
            UpdateBoneMatrices(tmo.w_hips_node, tmo_frame);
            }
            foreach (TMONode tmo_node in tmo.root_nodes_except_w_hips)
            {
            //移動変位を設定
            Matrix local = Matrix.Translation(translation);

            matrixStack.Push(local);
            UpdateBoneMatricesWithoutSlideMatrices(tmo_node, tmo_frame);
            }
        }
Пример #35
0
        /// <summary>
        /// フレームを補間します。
        /// </summary>
        /// <param name="frame0">フレーム0</param>
        /// <param name="frame1">フレーム1</param>
        /// <param name="frame2">フレーム2</param>
        /// <param name="frame3">フレーム3</param>
        /// <param name="length">分割数</param>
        /// <param name="p1">補間速度係数</param>
        /// <param name="id_pair">node idのペア</param>
        /// <returns></returns>
        public static TMOFrame[] Slerp(TMOFrame frame0, TMOFrame frame1, TMOFrame frame2, TMOFrame frame3, int length, float p1, int[] id_pair)
        {
            TMOFrame[] frames = new TMOFrame[length];

            for (int frame_index = 0; frame_index < length; frame_index++)
            {
                frames[frame_index] = new TMOFrame(frame_index);
                frames[frame_index].matrices = new TMOMat[frame1.matrices.Length];
            }

            for (int i = 0; i < frame1.matrices.Length; i++)
            {
                TMOMat[] interpolated_matrices = TMOMat.Slerp(
                        frame0.matrices[i],
                        frame1.matrices[i],
                        frame2.matrices[id_pair[i]],
                        frame3.matrices[id_pair[i]],
                        length,
                        p1);

                for (int frame_index = 0; frame_index < length; frame_index++)
                    frames[frame_index].matrices[i] = interpolated_matrices[frame_index];
            }
            return frames;
        }