Beispiel #1
0
        /// <summary>
        /// 補間を行います。
        /// </summary>
        /// <param name="mat0">行列0</param>
        /// <param name="mat1">行列1</param>
        /// <param name="mat2">行列2</param>
        /// <param name="mat3">行列3</param>
        /// <param name="length">分割数</param>
        /// <param name="p1">補間速度係数</param>
        /// <returns>分割数だけTMOMatを持つ配列</returns>
        public static TMOMat[] Slerp(TMOMat mat0, TMOMat mat1, TMOMat mat2, TMOMat mat3, int length, float p1)
        {
            TMOMat[] ret = new TMOMat[length];

            Matrix m1 = mat1.m;
            Matrix m2 = mat2.m;

            Vector3 scaling1;
            Vector3 scaling2;
            Vector3 v1 = Helper.DecomposeMatrix(ref m1, out scaling1);
            Vector3 v2 = Helper.DecomposeMatrix(ref m2, out scaling2);

            Quaternion q1 = Quaternion.RotationMatrix(m1);
            Quaternion q2 = Quaternion.RotationMatrix(m2);

            Vector3 v0 = new Vector3(mat0.m.M41, mat0.m.M42, mat0.m.M43);
            //Vector3 v1 = new Vector3(mat1.m.M41, mat1.m.M42, mat1.m.M43);
            //Vector3 v2 = new Vector3(mat2.m.M41, mat2.m.M42, mat2.m.M43);
            Vector3 v3 = new Vector3(mat3.m.M41, mat3.m.M42, mat3.m.M43);

            float p0 = 0.0f;
            float p2 = 1.0f;
            float dt = 1.0f / length;

            for (int i = 0; i < length; i++)
            {
                float  t = dt * i;
                float  p = t * t * (p2 - 2 * p1 + p0) + t * (2 * p1 - 2 * p0) + p0;
                Matrix m = Matrix.Scaling(Vector3.Lerp(scaling1, scaling2, p)) * Matrix.RotationQuaternion(Quaternion.Slerp(q1, q2, p)) * Matrix.Translation(Vector3.CatmullRom(v0, v1, v2, v3, p));
                ret[i] = new TMOMat(ref m);
            }
            return(ret);
        }
Beispiel #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);
        }
Beispiel #3
0
        /// <summary>
        /// 補間を行います。
        /// </summary>
        /// <param name="mat0">行列0</param>
        /// <param name="mat1">行列1</param>
        /// <param name="mat2">行列2</param>
        /// <param name="mat3">行列3</param>
        /// <param name="length">分割数</param>
        /// <param name="p1">補間速度係数</param>
        /// <returns>分割数だけTMOMatを持つ配列</returns>
        public static TMOMat[] Slerp(TMOMat mat0, TMOMat mat1, TMOMat mat2, TMOMat mat3, int length, float p1)
        {
            TMOMat[] ret = new TMOMat[length];

            Quaternion q1 = Quaternion.RotationMatrix(mat1.m);
            Quaternion q2 = Quaternion.RotationMatrix(mat2.m);

            Vector3 v0 = new Vector3(mat0.m.M41, mat0.m.M42, mat0.m.M43);
            Vector3 v1 = new Vector3(mat1.m.M41, mat1.m.M42, mat1.m.M43);
            Vector3 v2 = new Vector3(mat2.m.M41, mat2.m.M42, mat2.m.M43);
            Vector3 v3 = new Vector3(mat3.m.M41, mat3.m.M42, mat3.m.M43);

            float p0 = 0.0f;
            float p2 = 1.0f;
            float dt = 1.0f / length;

            for (int i = 0; i < length; i++)
            {
                float  t = dt * i;
                float  p = t * t * (p2 - 2 * p1 + p0) + t * (2 * p1 - 2 * p0) + p0;
                Matrix m = Matrix.RotationQuaternion(Quaternion.Slerp(q1, q2, p)) * Matrix.Translation(Vector3.CatmullRom(v0, v1, v2, v3, p));
                ret[i] = new TMOMat(ref m);
            }
            return(ret);
        }
Beispiel #4
0
        void Translate2(ref Matrix m, Matrix transformation)
        {
            Vector3 t = TMOMat.DecomposeMatrix(ref transformation);

            m.M41 = t.X + m.M41;
            m.M42 = t.Y + m.M42;
            m.M43 = t.Z + m.M43;
        }
Beispiel #5
0
        private void LimitRotationZXY(TMONode node)
        {
            TMOConstraintItem item   = constraint_zxy.GetItem(node.Name);
            Vector3           angle1 = TMOMat.ToAngleZXY(node.Rotation);
            Vector3           angle0 = item.Limit(angle1);

            node.Rotation = TMOMat.ToQuaternionZXY(angle0);
            //Console.WriteLine("node {0} x {1:F2} y {2:F2} z {3:F2}", node.Name, angle0.X, angle0.Y, angle0.Z);
        }
Beispiel #6
0
        public static void Write(BinaryWriter bw, TMOMat item)
        {
            Matrix m = item.m;

            bw.Write(m.M11); bw.Write(m.M12); bw.Write(m.M13); bw.Write(m.M14);
            bw.Write(m.M21); bw.Write(m.M22); bw.Write(m.M23); bw.Write(m.M24);
            bw.Write(m.M31); bw.Write(m.M32); bw.Write(m.M33); bw.Write(m.M34);
            bw.Write(m.M41); bw.Write(m.M42); bw.Write(m.M43); bw.Write(m.M44);
        }
Beispiel #7
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);
        }
Beispiel #8
0
        /// <summary>
        /// 加減算を行います。
        /// </summary>
        /// <param name="mat0">行列0</param>
        /// <param name="mat1">行列1</param>
        /// <param name="mat2">行列2</param>
        /// <returns>行列1 - 行列2 + 行列0</returns>
        public static TMOMat AddSub(TMOMat mat0, TMOMat mat1, TMOMat mat2)
        {
            Matrix  m0 = mat0.m;
            Matrix  m1 = mat1.m;
            Matrix  m2 = mat2.m;
            Vector3 t0 = Helper.DecomposeMatrix(ref m0);
            Vector3 t1 = Helper.DecomposeMatrix(ref m1);
            Vector3 t2 = Helper.DecomposeMatrix(ref m2);
            Matrix  m  = m1 * Matrix.Invert(m2) * m0 * Matrix.Translation(t1 - t2 + t0);

            return(new TMOMat(ref m));
        }
Beispiel #9
0
        /// <summary>
        /// モーション行列を指定比率で変形します。
        /// </summary>
        /// <param name="mat">モーション行列</param>
        /// <param name="ratio">比率</param>
        public void Transform(TMOMat mat, float ratio)
        {
            foreach (TPOCommand command in commands)
            {
                Matrix scaling = Matrix.Identity;
                switch (command.type)
                {
                case TPOCommandType.Scale:
                case TPOCommandType.Scale1:
                case TPOCommandType.Scale0:
                    Vector3 v;
                    v.X     = (float)Math.Pow(command.X, ratio);
                    v.Y     = (float)Math.Pow(command.Y, ratio);
                    v.Z     = (float)Math.Pow(command.Z, ratio);
                    scaling = Matrix.Scaling(v);
                    break;
                }
                switch (command.type)
                {
                case TPOCommandType.Scale:
                    mat.Scale(scaling);
                    break;

                case TPOCommandType.Scale1:
                    mat.Scale1(scaling);
                    break;

                case TPOCommandType.Scale0:
                    mat.Scale0(scaling);
                    break;

                case TPOCommandType.Rotate:
                    mat.RotateX(command.X * ratio);
                    mat.RotateY(command.Y * ratio);
                    mat.RotateZ(command.Z * ratio);
                    break;

                case TPOCommandType.Rotate2:
                    mat.RotateX2(command.X * ratio);
                    mat.RotateY2(command.Y * ratio);
                    mat.RotateZ2(command.Z * ratio);
                    break;

                case TPOCommandType.Move:
                    mat.Move(command.GetVector3() * ratio);
                    break;
                }
            }
        }
Beispiel #10
0
        public static int DisplayTranslation(string source_file)
        {
            TMOFile tmo = new TMOFile();

            try
            {
                tmo.Load(source_file);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return(-1);
            }

            if (tmo.nodes[0].ShortName != "W_Hips")
            {
                Console.WriteLine("Passed: root node is not W_Hips");
                return(1);
            }

            Dictionary <string, TMONode> nodes = new Dictionary <string, TMONode>();

            foreach (TMONode node in tmo.nodes)
            {
                try {
                    nodes.Add(node.ShortName, node);
                } catch (ArgumentException) {
                    Console.WriteLine("node {0} already exists.", node.ShortName);
                }
            }

            try {
                TMONode node;

                node = nodes["W_Hips"];
                TMOMat mat = node.frame_matrices[0];
                Matrix m   = mat.m;
                Console.WriteLine("{0} {1} {2}", m.M41, m.M42, m.M43);
            } catch (KeyNotFoundException) {
                Console.WriteLine("node not found.");
            }

            return(0);
        }
Beispiel #11
0
        public void Transform(TPONode node)
        {
            for (int i = 0; i < tmo.frames.Length; i++)
            {
                TMOMat mat = tmo.GetTMOMat(node.name, i);

                Matrix  m       = mat.m;
                Vector3 scaling = Vector3.Empty;
                Vector3 t       = TMOMat.DecomposeMatrix(ref m, out scaling);

                scaling.X *= (float)Math.Pow(node.Scaling.X, ratio);
                scaling.Y *= (float)Math.Pow(node.Scaling.Y, ratio);
                scaling.Z *= (float)Math.Pow(node.Scaling.Z, ratio);
                m         *= node.RotationMatrix(m, ratio);
                t         += node.Translation * ratio;

                mat.m = Matrix.Scaling(scaling) * m * Matrix.Translation(t);
            }
        }
Beispiel #12
0
        public static TMOMat[] Slerp(TMOMat mat0, TMOMat mat1, TMOMat mat2, TMOMat mat3, int length)
        {
            TMOMat[] ret = new TMOMat[length];

            Quaternion q1 = Quaternion.RotationMatrix(mat1.m);
            Quaternion q2 = Quaternion.RotationMatrix(mat2.m);

            Vector3 v0 = new Vector3(mat0.m.M41, mat0.m.M42, mat0.m.M43);
            Vector3 v1 = new Vector3(mat1.m.M41, mat1.m.M42, mat1.m.M43);
            Vector3 v2 = new Vector3(mat2.m.M41, mat2.m.M42, mat2.m.M43);
            Vector3 v3 = new Vector3(mat3.m.M41, mat3.m.M42, mat3.m.M43);

            float dt = 1.0f / length;

            for (int i = 0; i < length; i++)
            {
                ret[i] = new TMOMat(Matrix.RotationQuaternion(Quaternion.Slerp(q1, q2, dt * i)) * Matrix.Translation(Vector3.CatmullRom(v0, v1, v2, v3, dt * i)));
            }
            return(ret);
        }
Beispiel #13
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);
            }
        }
Beispiel #14
0
 /// <summary>
 /// モーション行列を指定比率で変形します。
 /// </summary>
 /// <param name="mat">モーション行列</param>
 /// <param name="ratio">比率</param>
 public void Transform(TMOMat mat, float ratio)
 {
     foreach (TPOCommand command in commands)
     {
     Matrix scaling = Matrix.Identity;
     switch (command.type)
     {
         case TPOCommandType.Scale:
         case TPOCommandType.Scale1:
         case TPOCommandType.Scale0:
             Vector3 v;
             v.X = (float)Math.Pow(command.X, ratio);
             v.Y = (float)Math.Pow(command.Y, ratio);
             v.Z = (float)Math.Pow(command.Z, ratio);
             scaling = Matrix.Scaling(v);
             break;
     }
     switch (command.type)
     {
         case TPOCommandType.Scale:
             mat.Scale(scaling);
             break;
         case TPOCommandType.Scale1:
             mat.Scale1(scaling);
             break;
         case TPOCommandType.Scale0:
             mat.Scale0(scaling);
             break;
         case TPOCommandType.Rotate:
             mat.RotateX(command.X * ratio);
             mat.RotateY(command.Y * ratio);
             mat.RotateZ(command.Z * ratio);
             break;
         case TPOCommandType.Move:
             mat.Move(command.GetVector3() * ratio);
             break;
     }
     }
 }
Beispiel #15
0
        void Transform2(ref Matrix m, Matrix transformation)
        {
            Vector3 t = TMOMat.DecomposeMatrix(ref transformation);

            m = transformation * m;
        }
Beispiel #16
0
 /// <summary>
 /// 補間を行います。
 /// </summary>
 /// <param name="mat0">行列0</param>
 /// <param name="mat1">行列1</param>
 /// <param name="mat2">行列2</param>
 /// <param name="mat3">行列3</param>
 /// <param name="length">分割数</param>
 /// <returns>分割数だけTMOMatを持つ配列</returns>
 public static TMOMat[] Slerp(TMOMat mat0, TMOMat mat1, TMOMat mat2, TMOMat mat3, int length)
 {
     return(Slerp(mat0, mat1, mat2, mat3, length, 0.5f));
 }
Beispiel #17
0
 /// <summary>
 /// 加減算を行います。
 /// </summary>
 /// <param name="mat0">行列0</param>
 /// <param name="mat1">行列1</param>
 /// <param name="mat2">行列2</param>
 /// <returns>行列1 - 行列2 + 行列0</returns>
 public static TMOMat AddSub(TMOMat mat0, TMOMat mat1, TMOMat mat2)
 {
     Matrix m0 = mat0.m;
     Matrix m1 = mat1.m;
     Matrix m2 = mat2.m;
     Vector3 t0 = Helper.DecomposeMatrix(ref m0);
     Vector3 t1 = Helper.DecomposeMatrix(ref m1);
     Vector3 t2 = Helper.DecomposeMatrix(ref m2);
     Matrix m = m1 * Matrix.Invert(m2) * m0 * Matrix.Translation(t1 - t2 + t0);
     return new TMOMat(ref m);
 }
Beispiel #18
0
 /// <summary>
 /// 補間を行います。
 /// </summary>
 /// <param name="mat0">行列0</param>
 /// <param name="mat1">行列1</param>
 /// <param name="mat2">行列2</param>
 /// <param name="mat3">行列3</param>
 /// <param name="length">分割数</param>
 /// <returns>分割数だけTMOMatを持つ配列</returns>
 public static TMOMat[] Slerp(TMOMat mat0, TMOMat mat1, TMOMat mat2, TMOMat mat3, int length)
 {
     return Slerp(mat0, mat1, mat2, mat3, length, 0.5f);
 }
Beispiel #19
0
        /// <summary>
        /// 補間を行います。
        /// </summary>
        /// <param name="mat0">行列0</param>
        /// <param name="mat1">行列1</param>
        /// <param name="mat2">行列2</param>
        /// <param name="mat3">行列3</param>
        /// <param name="length">分割数</param>
        /// <param name="p1">補間速度係数</param>
        /// <returns>分割数だけTMOMatを持つ配列</returns>
        public static TMOMat[] Slerp(TMOMat mat0, TMOMat mat1, TMOMat mat2, TMOMat mat3, int length, float p1)
        {
            TMOMat[] ret = new TMOMat[length];

            Matrix m1 = mat1.m;
            Matrix m2 = mat2.m;

            Vector3 scaling1;
            Vector3 scaling2;
            Vector3 v1 = Helper.DecomposeMatrix(ref m1, out scaling1);
            Vector3 v2 = Helper.DecomposeMatrix(ref m2, out scaling2);

            Quaternion q1 = Quaternion.RotationMatrix(m1);
            Quaternion q2 = Quaternion.RotationMatrix(m2);

            Vector3 v0 = new Vector3(mat0.m.M41, mat0.m.M42, mat0.m.M43);
            //Vector3 v1 = new Vector3(mat1.m.M41, mat1.m.M42, mat1.m.M43);
            //Vector3 v2 = new Vector3(mat2.m.M41, mat2.m.M42, mat2.m.M43);
            Vector3 v3 = new Vector3(mat3.m.M41, mat3.m.M42, mat3.m.M43);

            float p0 = 0.0f;
            float p2 = 1.0f;
            float dt = 1.0f/length;
            for (int i = 0; i < length; i++)
            {
                float t = dt*i;
                float p = t*t*(p2-2*p1+p0) + t*(2*p1-2*p0) + p0;
                Matrix m = Matrix.Scaling(Vector3.Lerp(scaling1, scaling2, p)) * Matrix.RotationQuaternion(Quaternion.Slerp(q1, q2, p)) * Matrix.Translation(Vector3.CatmullRom(v0, v1, v2, v3, p));
                ret[i] = new TMOMat(ref m);
            }
            return ret;
        }
Beispiel #20
0
        /// <summary>
        /// tmoファイルを含むディレクトリから要素を追加します。
        /// </summary>
        /// <param name="source_file">tmoファイルを含むディレクトリ名</param>
        public void AddItemFromTMODirectory(string source_file)
        {
            TMOFile tmo = new TMOFile();

            Dictionary <string, Vector3> min1_dic = new Dictionary <string, Vector3>();
            Dictionary <string, Vector3> max1_dic = new Dictionary <string, Vector3>();

            Dictionary <string, Vector3> min2_dic = new Dictionary <string, Vector3>();
            Dictionary <string, Vector3> max2_dic = new Dictionary <string, Vector3>();

            string[] files = Directory.GetFiles(source_file, "*.tmo");
            foreach (string file in files)
            {
                tmo.Load(file);
                foreach (TMONode node in tmo.nodes)
                {
                    TMOMat mat = node.matrices[0];

                    string  name   = node.Name;
                    Vector3 angle1 = Helper.ToAngleXYZ(mat.m);
                    Vector3 angle2 = angle1;

                    if (angle2.X < 0)
                    {
                        angle2.X += 360;
                    }
                    if (angle2.Y < 0)
                    {
                        angle2.Y += 360;
                    }
                    if (angle2.Z < 0)
                    {
                        angle2.Z += 360;
                    }

                    if (!min1_dic.ContainsKey(name))
                    {
                        min1_dic[name] = new Vector3(+180.0f, +180.0f, +180.0f);
                    }
                    if (!max1_dic.ContainsKey(name))
                    {
                        max1_dic[name] = new Vector3(-180.0f, -180.0f, -180.0f);
                    }

                    Vector3 min1 = min1_dic[name];
                    Vector3 max1 = max1_dic[name];

                    if (angle1.X < min1_dic[name].X)
                    {
                        min1.X = angle1.X;
                    }
                    if (angle1.X > max1_dic[name].X)
                    {
                        max1.X = angle1.X;
                    }

                    if (angle1.Y < min1_dic[name].Y)
                    {
                        min1.Y = angle1.Y;
                    }
                    if (angle1.Y > max1_dic[name].Y)
                    {
                        max1.Y = angle1.Y;
                    }

                    if (angle1.Z < min1_dic[name].Z)
                    {
                        min1.Z = angle1.Z;
                    }
                    if (angle1.Z > max1_dic[name].Z)
                    {
                        max1.Z = angle1.Z;
                    }

                    min1_dic[name] = min1;
                    max1_dic[name] = max1;

                    if (!min2_dic.ContainsKey(name))
                    {
                        min2_dic[name] = new Vector3(360.0f, 360.0f, 360.0f);
                    }
                    if (!max2_dic.ContainsKey(name))
                    {
                        max2_dic[name] = new Vector3(0.0f, 0.0f, 0.0f);
                    }

                    Vector3 min2 = min2_dic[name];
                    Vector3 max2 = max2_dic[name];

                    if (angle2.X < min2_dic[name].X)
                    {
                        min2.X = angle2.X;
                    }
                    if (angle2.X > max2_dic[name].X)
                    {
                        max2.X = angle2.X;
                    }

                    if (angle2.Y < min2_dic[name].Y)
                    {
                        min2.Y = angle2.Y;
                    }
                    if (angle2.Y > max2_dic[name].Y)
                    {
                        max2.Y = angle2.Y;
                    }

                    if (angle2.Z < min2_dic[name].Z)
                    {
                        min2.Z = angle2.Z;
                    }
                    if (angle2.Z > max2_dic[name].Z)
                    {
                        max2.Z = angle2.Z;
                    }

                    min2_dic[name] = min2;
                    max2_dic[name] = max2;
                }
            }

            foreach (string name in min1_dic.Keys)
            {
                TMOConstraintItem item = new TMOConstraintItem();
                item.Name = name;

                Vector3 min1 = min1_dic[name];
                Vector3 max1 = max1_dic[name];

                Vector3 min2 = min2_dic[name];
                Vector3 max2 = max2_dic[name];

                Vector3 sub1 = max1 - min1;
                Vector3 sub2 = max2 - min2;

                Vector3 min;
                Vector3 max;

                if (sub1.X <= sub2.X)
                {
                    min.X        = min1.X;
                    max.X        = max1.X;
                    item.SectorX = 1;
                }
                else
                {
                    min.X        = min2.X;
                    max.X        = max2.X;
                    item.SectorX = 2;
                }

                if (sub1.Y <= sub2.Y)
                {
                    min.Y        = min1.Y;
                    max.Y        = max1.Y;
                    item.SectorY = 1;
                }
                else
                {
                    min.Y        = min2.Y;
                    max.Y        = max2.Y;
                    item.SectorY = 2;
                }

                if (sub1.Z <= sub2.Z)
                {
                    min.Z        = min1.Z;
                    max.Z        = max1.Z;
                    item.SectorZ = 1;
                }
                else
                {
                    min.Z        = min2.Z;
                    max.Z        = max2.Z;
                    item.SectorZ = 2;
                }
                item.Min = min;
                item.Max = max;

                items.Add(item);
            }
        }
Beispiel #21
0
        /// <summary>
        /// 指定ライタに行列を書き出します。
        /// </summary>
        /// <param name="bw">ライタ</param>
        /// <param name="item">行列</param>
        public static void Write(BinaryWriter bw, TMOMat item)
        {
            Matrix m = item.m;

            Write(bw, ref m);
        }