Esempio n. 1
0
 /// <summary>
 /// Compares the given anim's joints with the joints provided by the user returns true if the anim contains atleast one
 /// </summary>
 private bool ReadSEanimForJoint(SEAnim anim)
 {
     if (anim.Bones.Count < 1)
     {
         return(false);
     }
     else
     {
         if (Joints.Count < 2)
         {
             for (int i = 0; i < anim.Bones.Count; i++)
             {
                 if (anim.Bones.ElementAt(i).CompareTo(Joints.ElementAt(0)) == 0)
                 {
                     return(true);
                 }
             }
         }
         else
         {
             for (int j = 0; j < Joints.Count; j++)
             {
                 for (int y = 0; y < anim.Bones.Count; y++)
                 {
                     if (anim.Bones.ElementAt(y).CompareTo(Joints.ElementAt(j)) == 0)
                     {
                         return(true);
                     }
                 }
             }
         }
     }
     return(false);
 }
Esempio n. 2
0
        private static void ConvertAnimation(Stream animStream, string path, bool convertAnims, FindLogic.Combo.AnimationInfoNew animationInfo)
        {
            teAnimation parsedAnimation = new teAnimation(animStream, true);

            string animationDirectory =
                Path.Combine(path, "Animations", parsedAnimation.Header.Priority.ToString());

            if (convertAnims)
            {
                SEAnim seAnim     = new SEAnim(parsedAnimation);
                string animOutput = Path.Combine(animationDirectory,
                                                 animationInfo.GetNameIndex() + "." + seAnim.Extension);
                CreateDirectoryFromFile(animOutput);
                using (Stream fileStream = new FileStream(animOutput, FileMode.Create)) {
                    seAnim.Write(fileStream);
                }
            }
            else
            {
                string rawAnimOutput = Path.Combine(animationDirectory,
                                                    $"{animationInfo.GetNameIndex()}.{teResourceGUID.Type(animationInfo.GUID):X3}");
                CreateDirectoryFromFile(rawAnimOutput);
                using (Stream fileStream = new FileStream(rawAnimOutput, FileMode.Create)) {
                    animStream.CopyTo(fileStream);
                }
            }
        }
Esempio n. 3
0
        private SMDFile()
        {
            Bones     = new List <SEModelBone>();
            Meshes    = new List <SEModelMesh>();
            Materials = new List <SEModelMaterial>();

            Animation = new SEAnim {
                AnimType = AnimationType.Absolute
            };
            Namespaces = new List <string>();
        }
Esempio n. 4
0
        public static void TestAnimation()
        {
            using (Stream stream = OpenFile(0xA000000000042D9)) {  // ANCR_base_3p_ohHai_POTG
                teAnimation animation = new teAnimation(stream);

                SEAnim seAnim = new SEAnim(animation);

                using (Stream file = File.OpenWrite($"test.{seAnim.Extension}")) {
                    seAnim.Write(file);
                }
            }
        }
Esempio n. 5
0
        public static void SaveAnimation(string FileName, Animation anim, STSkeleton skeleton)
        {
            anim.SetFrame(anim.FrameCount - 1);       //from last frame
            for (int f = 0; f < anim.FrameCount; ++f) //go through each frame with nextFrame
            {
                anim.NextFrame(skeleton);
            }
            anim.NextFrame(skeleton);  //go on first frame

            SEAnim seAnim = new SEAnim();

            seAnim.Looping  = anim.CanLoop;
            seAnim.AnimType = AnimationType.Absolute;
            //Reset active animation to 0
            anim.SetFrame(0);
            for (int frame = 0; frame < anim.FrameCount; frame++)
            {
                anim.NextFrame(skeleton, false, true);

                foreach (Animation.KeyNode boneAnim in anim.Bones)
                {
                    if (boneAnim.HasKeyedFrames(frame))
                    {
                        STBone bone = skeleton.GetBone(boneAnim.Text);
                        if (bone == null)
                        {
                            continue;
                        }

                        Vector3    position = bone.GetPosition();
                        Quaternion rotation = bone.GetRotation();
                        Vector3    scale    = bone.GetScale();

                        seAnim.AddTranslationKey(boneAnim.Text, frame, position.X, position.Y, position.Z);
                        seAnim.AddRotationKey(boneAnim.Text, frame, rotation.X, rotation.Y, rotation.Z, rotation.W);
                        seAnim.AddScaleKey(boneAnim.Text, frame, scale.X, scale.Y, scale.Z);
                    }
                }
            }

            seAnim.Write(FileName);
        }
Esempio n. 6
0
        public static void ExportIOAnimation(string FileName, IOAnimation animData)
        {
            SEAnim seOut = new SEAnim();                //init new SEAnim

            foreach (IOAnimNode node in animData.Nodes) //iterate through each node
            {
                for (int i = 0; i < animData.FrameCount; i++)
                {
                    OpenTK.Vector3    pos = node.GetPosition(i, OpenTK.Vector3.Zero);
                    OpenTK.Quaternion rot = node.GetQuaternionRotation(i, new OpenTK.Quaternion(0, 0, 0, 0));
                    OpenTK.Vector3    sca = node.GetScaling(i, OpenTK.Vector3.Zero);

                    seOut.AddTranslationKey(node.Name, i, pos.X, pos.Y, pos.Z);
                    seOut.AddRotationKey(node.Name, i, rot.X, rot.Y, rot.Z, rot.W);
                    seOut.AddScaleKey(node.Name, i, sca.X, sca.Y, sca.Z);
                }
            }

            seOut.Write(FileName); //write it!
        }
Esempio n. 7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="animation"></param>
        /// <param name="skeleton"></param>
        public void ExportSBAnimation(string FileName, SBAnimation animation, SBSkeleton skeleton)
        {
            SEAnim seOut = new SEAnim();                   //init new SEAnim

            foreach (var node in animation.TransformNodes) //iterate through each node
            {
                for (int i = 0; i < animation.FrameCount; i++)
                {
                    SBBone temp = new SBBone();

                    temp.Transform = node.GetTransformAt(i, skeleton);

                    seOut.AddTranslationKey(node.Name, i, temp.X, temp.Y, temp.Z);
                    seOut.AddRotationKey(node.Name, i, temp.RotationQuaternion.X, temp.RotationQuaternion.Y, temp.RotationQuaternion.Z, temp.RotationQuaternion.W);
                    seOut.AddScaleKey(node.Name, i, temp.SX, temp.SY, temp.SZ);
                }
            }

            seOut.Write(FileName); //write it!
        }
Esempio n. 8
0
        static void CheckAnimName(string animName, Boolean patchAnim = false)
        {
            string hashName     = string.Format("{0:x}", HashUtil.Hash(animName));
            string hashFilePath = greyhoundExportFolder + "\\xanims\\xanim_" + hashName + ".seanim";

            if (File.Exists(hashFilePath))
            {
                Console.WriteLine("Found asset: {0:x}", animName.PadRight(40) + hashName);
                File.AppendAllText(greyhoundExportFolder + "\\AnimsFound.txt", hashName + "," + animName + Environment.NewLine);
                string destFileName = greyhoundExportFolder + "\\xanims\\" + animName + ".seanim";
                File.Copy(hashFilePath, destFileName, true);
                if (patchAnim)
                {
                    SEAnim seAnim = SEAnim.Read(destFileName);
                    seAnim.AnimType = AnimationType.Absolute;
                    seAnim.AnimationBoneModifiers["tag_weapon"]    = AnimationType.Relative;
                    seAnim.AnimationBoneModifiers["tag_weapon_le"] = AnimationType.Relative;
                    seAnim.Write(destFileName, false);
                }
            }
        }
Esempio n. 9
0
        public static void SaveAnimation(string FileName, Animation anim, STSkeleton skeleton)
        {
            SEAnim seAnim = new SEAnim();

            //Reset active animation to 0
            anim.SetFrame(0);
            for (int frame = 0; frame < anim.FrameCount; frame++)
            {
                anim.NextFrame(skeleton);

                //Reset it when it reaches the total frame count
                if (anim.Frame >= anim.FrameCount)
                {
                    anim.Frame = 0;
                }

                foreach (Animation.KeyNode boneAnim in anim.Bones)
                {
                    STBone bone = skeleton.GetBone(boneAnim.Text);

                    if (bone == null)
                    {
                        continue;
                    }

                    Vector3    position = bone.GetPosition();
                    Quaternion rotation = bone.GetRotation();
                    Vector3    scale    = bone.GetScale();

                    seAnim.AddTranslationKey(boneAnim.Text, frame, position.X, position.Y, position.Z);
                    seAnim.AddRotationKey(boneAnim.Text, frame, rotation.X, rotation.Y, rotation.Z, rotation.W);
                    seAnim.AddScaleKey(boneAnim.Text, frame, scale.X, scale.Y, scale.Z);
                }

                //Add frames to the playing animation
                anim.Frame += 1f;
            }

            seAnim.Write(FileName);
        }
Esempio n. 10
0
        private static void ConvertAnimation(Stream animStream, string path, bool convertAnims, FindLogic.Combo.AnimationAsset animationInfo, bool scaleAnims)
        {
            var parsedAnimation = default(teAnimation);
            var priority        = 100;

            try
            {
                parsedAnimation = new teAnimation(animStream, true);
                priority        = parsedAnimation.Header.Priority;
            }
            catch (Exception)
            {
                Logger.Error("Combo", $"Unable to parse animation {animationInfo.GetName()}");
            }
            string animationDirectory =
                Path.Combine(path, "Animations", priority.ToString());

            if (convertAnims && parsedAnimation != null)
            {
                SEAnim seAnim     = new SEAnim(parsedAnimation, scaleAnims);
                string animOutput = Path.Combine(animationDirectory,
                                                 animationInfo.GetNameIndex() + "." + seAnim.Extension);
                CreateDirectoryFromFile(animOutput);
                using (Stream fileStream = new FileStream(animOutput, FileMode.Create)) {
                    seAnim.Write(fileStream);
                }
            }
            else
            {
                animStream.Position = 0;
                string rawAnimOutput = Path.Combine(animationDirectory,
                                                    $"{animationInfo.GetNameIndex()}.{teResourceGUID.Type(animationInfo.m_GUID):X3}");
                CreateDirectoryFromFile(rawAnimOutput);
                using (Stream fileStream = new FileStream(rawAnimOutput, FileMode.Create)) {
                    animStream.CopyTo(fileStream);
                }
            }
        }
Esempio n. 11
0
        public static void Save(STSkeletonAnimation anim, string FileName)
        {
            STSkeleton skeleton = anim.GetActiveSkeleton();

            SEAnim seAnim = new SEAnim();

            seAnim.Looping  = anim.Loop;
            seAnim.AnimType = AnimationType.Absolute;

            anim.SetFrame(0);
            for (int frame = 0; frame < anim.FrameCount; frame++)
            {
                anim.SetFrame(frame);
                anim.NextFrame();

                foreach (STAnimGroup boneAnim in anim.AnimGroups)
                {
                    if (boneAnim.GetTracks().Any(x => x.HasKeys))
                    {
                        STBone bone = skeleton.GetBone(boneAnim.Name);
                        if (bone == null)
                        {
                            continue;
                        }

                        Vector3    position = bone.GetPosition();
                        Quaternion rotation = bone.GetRotation();
                        Vector3    scale    = bone.GetScale();

                        seAnim.AddTranslationKey(boneAnim.Name, frame, position.X, position.Y, position.Z);
                        seAnim.AddRotationKey(boneAnim.Name, frame, rotation.X, rotation.Y, rotation.Z, rotation.W);
                        seAnim.AddScaleKey(boneAnim.Name, frame, scale.X, scale.Y, scale.Z);
                    }
                }
            }

            seAnim.Write(FileName);
        }
Esempio n. 12
0
        /// <summary>
        /// Goes through each anim bone and compares it to the joints specified by user
        /// </summary>
        private void DoAnimScan()
        {
            for (int i = 0; i < file_paths.Count; i++)
            {
                outputTextbox.Invoke(new Action(() => outputTextbox.AppendText("Reading " + System.IO.Path.GetFileNameWithoutExtension(file_paths.ElementAt(i)) + " .... \n")));

                bool isCorrectAnim = ReadSEanimForJoint(SEAnim.Read(file_paths.ElementAt(i)));
                if (isCorrectAnim)
                {
                    if (!System.IO.Directory.Exists(ExportDirectory))
                    {
                        System.IO.Directory.CreateDirectory(ExportDirectory);
                    }
                    System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(ExportDirectory);
                    System.IO.File.Move(@file_paths.ElementAt(i), ExportDirectory + System.IO.Path.GetFileName(file_paths.ElementAt(i)));
                    file_paths.RemoveAt(i);                                          //Remove the anim , then lower I to make sure to get the last element
                    animList.Invoke(new Action(() => animList.Items.RemoveAt(i--))); //Add file name to the UI list
                }
                progressBar.Invoke(new Action(() => progressBar.Increment(1)));      //Increments the progress bar to inform the user how long till it's done
            }
            System.Windows.Forms.MessageBox.Show("Scan has been completed, anims can be found in \"SEanimations\" ");
            ScanInProgress = false;
        }
Esempio n. 13
0
        public void ExportSBAnimation(string FileName, SBAnimation animation, SBSkeleton skeleton)
        {
            SEAnim seOut = new SEAnim();                   //init new SEAnim

            foreach (var node in animation.TransformNodes) //iterate through each node
            {
                for (int i = 0; i < animation.FrameCount; i++)
                {
                    SBBone temp = new SBBone();
                    temp.Transform = node.Transform.GetValue(i);

                    OpenTK.Vector3    pos = temp.Translation;
                    OpenTK.Quaternion rot = temp.RotationQuaternion;
                    OpenTK.Vector3    sca = temp.Scale;

                    seOut.AddTranslationKey(node.Name, i, pos.X, pos.Y, pos.Z);
                    seOut.AddRotationKey(node.Name, i, rot.X, rot.Y, rot.Z, rot.W);
                    seOut.AddScaleKey(node.Name, i, sca.X, sca.Y, sca.Z);
                }
            }

            seOut.Write(FileName); //write it!
        }
Esempio n. 14
0
        public static void Decode(string fileName)
        {
            // Get the right export folder and names
            string OutputName = Path.GetDirectoryName(fileName) + "\\" + Path.GetFileNameWithoutExtension(fileName);
            string ModelName  = Path.GetFileNameWithoutExtension(fileName).Replace("-", "_").Replace("#", "");

            // Make a new stream reader
            using (BinaryReader reader = new BinaryReader(new FileStream(fileName, FileMode.Open)))
            {
                // Make sure we are parsing a animation file
                string Magic = reader.ReadFixedString(4);
                if (Magic != "ANIM")
                {
                    Console.WriteLine(String.Format("File Magic \"{0}\" does not match IS's \"ANIM\"", Magic));
                    return;
                }

                // Get anim type
                int AnimType = reader.ReadInt32();
                if (AnimType == 10 || AnimType == 8)
                {
                    // Skip unknown bytes
                    reader.ReadBytes(4);

                    // Get base info of the animation
                    int BoneCount  = reader.ReadInt32();
                    int FrameCount = reader.ReadInt32();

                    // Make a new SEAnim to export
                    SEAnim AnimFile = new SEAnim();

                    // Put the base info in the animation
                    AnimFile.BoneCount  = BoneCount;
                    AnimFile.AnimType   = AnimationType.Additive;
                    AnimFile.FrameCount = FrameCount;

                    // Skip unknown bytes
                    reader.ReadBytes(4);

                    // Go through all the frames
                    for (int i = 0; i < FrameCount; i++)
                    {
                        // Skip 4 bytes for now
                        // Animtype 8  -> frame count
                        // Animtype 10 -> frame byte length
                        reader.ReadBytes(4);

                        // Go through all bone data
                        for (int j = 0; j < BoneCount; j++)
                        {
                            // Get offset to the next joint data
                            long StreamPos = reader.BaseStream.Position + 20;

                            // Read the joint rotation data
                            float BoneDirX = reader.ReadInt16() / 32768.0f;
                            float BoneDirZ = reader.ReadInt16() / 32768.0f;
                            float BoneDirY = reader.ReadInt16() / 32768.0f;
                            float BoneDirW = reader.ReadInt16() / 32768.0f;

                            // Put it in a quaternion object
                            Quaternion BoneDirection = new Quaternion(BoneDirX, BoneDirY, BoneDirZ, BoneDirW);

                            // Add the rotation of the joint to the anim
                            AnimFile.AddRotationKey("tag_is_model_" + j, i, BoneDirection.X, BoneDirection.Y, BoneDirection.Z, BoneDirection.W);

                            // Read joint position data
                            float bonePosX = System.BitConverter.ToSingle(reader.ReadBytes(4), 0);
                            float bonePosZ = System.BitConverter.ToSingle(reader.ReadBytes(4), 0);
                            float bonePosY = System.BitConverter.ToSingle(reader.ReadBytes(4), 0) * -1;

                            // Add the position of the joint to the anim
                            AnimFile.AddTranslationKey("tag_is_model_" + j, i, bonePosX, bonePosY, bonePosZ);

                            // Go to the next joint data
                            reader.Seek(StreamPos, SeekOrigin.Begin);
                        }
                    }

                    // Write the SEAnim file
                    AnimFile.Write(OutputName + ".seanim");

                    // Get the length of the Es file name
                    int EsFileNameLength = reader.ReadInt32();
                    // Only read it if it got an actual name
                    if (EsFileNameLength != 0)
                    {
                        // Read the name
                        string EsFileName = Path.GetFileName(reader.ReadFixedString(EsFileNameLength));

                        // Make a stream reader
                        using (BinaryReader ESreader = new BinaryReader(new FileStream(EsFileName, FileMode.Open)))
                        {
                            // Make sure were reading an ES file
                            if (ESreader.ReadFixedString(4) != "ESES")
                            {
                                Console.WriteLine("File Magic does not match IS's \"ESES\"");
                                return;
                            }

                            // Get the ES type
                            int ESType = ESreader.ReadInt32();

                            int skipInfo = ESreader.ReadInt32();
                        }
                    }
                }
            }
        }
Esempio n. 15
0
        public static Animation Read(string FileName, STSkeleton skeleton)
        {
            Animation anim   = new Animation();
            var       seanim = SEAnim.Read(FileName);

            anim.FrameCount = seanim.FrameCount;
            anim.CanLoop    = seanim.Looping;

            foreach (var bone in seanim.Bones)
            {
                STBone genericBone = skeleton.GetBone(bone);
                if (genericBone != null)
                {
                    var boneAnim = new Animation.KeyNode(bone);
                    boneAnim.RotType = Animation.RotationType.EULER;
                    boneAnim.UseSegmentScaleCompensate = false;
                    anim.Bones.Add(boneAnim);

                    float PositionX = 0;
                    float PositionY = 0;
                    float PositionZ = 0;

                    float RotationX = 0;
                    float RotationY = 0;
                    float RotationZ = 0;

                    float ScaleX = 0;
                    float ScaleY = 0;
                    float ScaleZ = 0;

                    if (seanim.AnimType == AnimationType.Relative)
                    {
                        PositionX = genericBone.position[0];
                        PositionY = genericBone.position[1];
                        PositionZ = genericBone.position[2];

                        RotationX = genericBone.rotation[0];
                        RotationY = genericBone.rotation[1];
                        RotationZ = genericBone.rotation[2];

                        ScaleX = genericBone.scale[0];
                        ScaleY = genericBone.scale[1];
                        ScaleZ = genericBone.scale[2];
                    }

                    System.Console.WriteLine(bone);

                    if (seanim.AnimationPositionKeys.ContainsKey(bone))
                    {
                        var translationKeys = seanim.AnimationPositionKeys[bone];
                        foreach (SEAnimFrame animFrame in translationKeys)
                        {
                            System.Console.WriteLine(animFrame.Frame + " T " + ((SELib.Utilities.Vector3)animFrame.Data).X);
                            System.Console.WriteLine(animFrame.Frame + " T " + ((SELib.Utilities.Vector3)animFrame.Data).Y);
                            System.Console.WriteLine(animFrame.Frame + " T " + ((SELib.Utilities.Vector3)animFrame.Data).Z);

                            boneAnim.XPOS.Keys.Add(new Animation.KeyFrame()
                            {
                                Value = (float)((SELib.Utilities.Vector3)animFrame.Data).X + PositionX,
                                Frame = animFrame.Frame,
                            });
                            boneAnim.YPOS.Keys.Add(new Animation.KeyFrame()
                            {
                                Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Y + PositionY,
                                Frame = animFrame.Frame,
                            });
                            boneAnim.ZPOS.Keys.Add(new Animation.KeyFrame()
                            {
                                Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Z + PositionZ,
                                Frame = animFrame.Frame,
                            });
                        }
                    }
                    if (seanim.AnimationRotationKeys.ContainsKey(bone))
                    {
                        var rotationnKeys = seanim.AnimationRotationKeys[bone];
                        foreach (SEAnimFrame animFrame in rotationnKeys)
                        {
                            var quat  = ((SELib.Utilities.Quaternion)animFrame.Data);
                            var euler = STMath.ToEulerAngles(quat.X, quat.Y, quat.Z, quat.W);

                            System.Console.WriteLine(animFrame.Frame + " R " + euler.X);
                            System.Console.WriteLine(animFrame.Frame + " R " + euler.Y);
                            System.Console.WriteLine(animFrame.Frame + " R " + euler.Z);

                            boneAnim.XROT.Keys.Add(new Animation.KeyFrame()
                            {
                                Value = euler.X + RotationX,
                                Frame = animFrame.Frame,
                            });
                            boneAnim.YROT.Keys.Add(new Animation.KeyFrame()
                            {
                                Value = euler.Y + RotationY,
                                Frame = animFrame.Frame,
                            });
                            boneAnim.ZROT.Keys.Add(new Animation.KeyFrame()
                            {
                                Value = euler.Z + RotationZ,
                                Frame = animFrame.Frame,
                            });
                        }
                    }
                    if (seanim.AnimationScaleKeys.ContainsKey(bone))
                    {
                        var scaleKeys = seanim.AnimationScaleKeys[bone];
                        foreach (SEAnimFrame animFrame in scaleKeys)
                        {
                            System.Console.WriteLine(animFrame.Frame + " S " + ((SELib.Utilities.Vector3)animFrame.Data).X);
                            System.Console.WriteLine(animFrame.Frame + " S " + ((SELib.Utilities.Vector3)animFrame.Data).Y);
                            System.Console.WriteLine(animFrame.Frame + " S " + ((SELib.Utilities.Vector3)animFrame.Data).Z);

                            boneAnim.XSCA.Keys.Add(new Animation.KeyFrame()
                            {
                                Value = (float)((SELib.Utilities.Vector3)animFrame.Data).X + ScaleX,
                                Frame = animFrame.Frame,
                            });
                            boneAnim.YSCA.Keys.Add(new Animation.KeyFrame()
                            {
                                Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Y + ScaleY,
                                Frame = animFrame.Frame,
                            });
                            boneAnim.ZSCA.Keys.Add(new Animation.KeyFrame()
                            {
                                Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Z + ScaleZ,
                                Frame = animFrame.Frame,
                            });
                        }
                    }
                    else
                    {
                        boneAnim.XSCA.Keys.Add(new Animation.KeyFrame()
                        {
                            Value = 1,
                            Frame = 0,
                        });
                        boneAnim.YSCA.Keys.Add(new Animation.KeyFrame()
                        {
                            Value = 1,
                            Frame = 0,
                        });
                        boneAnim.ZSCA.Keys.Add(new Animation.KeyFrame()
                        {
                            Value = 1,
                            Frame = 0,
                        });
                    }
                }
            }



            return(anim);
        }
Esempio n. 16
0
        public static void SaveAnimation(string FileName, Animation anim, STSkeleton skeleton)
        {
            anim.SetFrame(anim.FrameCount - 1);       //from last frame
            for (int f = 0; f < anim.FrameCount; ++f) //go through each frame with nextFrame
            {
                anim.NextFrame(skeleton);
            }
            anim.NextFrame(skeleton);  //go on first frame

            foreach (STBone b in skeleton.getBoneTreeOrder())
            {
                if (anim.HasBone(b.Text))
                {
                    Animation.KeyNode n = anim.GetBone(b.Text);


                    if (n.XPOS.HasAnimation())
                    {
                        WriteKey(n.XPOS);
                    }
                    if (n.YPOS.HasAnimation())
                    {
                        WriteKey(n.YPOS);
                    }
                    if (n.ZPOS.HasAnimation())
                    {
                        WriteKey(n.ZPOS);
                    }
                    if (n.XROT.HasAnimation())
                    {
                        WriteKey(n.XROT);
                    }
                    if (n.YROT.HasAnimation())
                    {
                        WriteKey(n.YROT);
                    }
                    if (n.ZROT.HasAnimation())
                    {
                        WriteKey(n.ZROT);
                    }
                    if (n.XSCA.HasAnimation())
                    {
                        WriteKey(n.XSCA);
                    }
                    if (n.YSCA.HasAnimation())
                    {
                        WriteKey(n.YSCA);
                    }
                    if (n.ZSCA.HasAnimation())
                    {
                        WriteKey(n.ZSCA);
                    }
                }
            }

            SEAnim seAnim = new SEAnim();

            seAnim.Looping  = anim.CanLoop;
            seAnim.AnimType = AnimationType.Absolute;
            //Reset active animation to 0
            anim.SetFrame(0);
            for (int frame = 0; frame < anim.FrameCount; frame++)
            {
                anim.NextFrame(skeleton, false, true);

                foreach (Animation.KeyNode boneAnim in anim.Bones)
                {
                    if (boneAnim.HasKeyedFrames(frame))
                    {
                        STBone bone = skeleton.GetBone(boneAnim.Text);
                        if (bone == null)
                        {
                            continue;
                        }

                        Vector3    position = bone.GetPosition();
                        Quaternion rotation = bone.GetRotation();
                        Vector3    scale    = bone.GetScale();

                        //Exporting at specific keys doesn't work atm
                        //Todo
                        bool IsTranlationKeyed = (boneAnim.XPOS.GetKeyFrame(frame).IsKeyed ||
                                                  boneAnim.YPOS.GetKeyFrame(frame).IsKeyed ||
                                                  boneAnim.ZPOS.GetKeyFrame(frame).IsKeyed);

                        bool IsRotationKeyed = (boneAnim.XROT.GetKeyFrame(frame).IsKeyed ||
                                                boneAnim.YROT.GetKeyFrame(frame).IsKeyed ||
                                                boneAnim.ZROT.GetKeyFrame(frame).IsKeyed);

                        bool IsScaleKeyed = (boneAnim.XSCA.GetKeyFrame(frame).IsKeyed ||
                                             boneAnim.YSCA.GetKeyFrame(frame).IsKeyed ||
                                             boneAnim.ZSCA.GetKeyFrame(frame).IsKeyed);

                        seAnim.AddTranslationKey(boneAnim.Text, frame, position.X, position.Y, position.Z);
                        seAnim.AddRotationKey(boneAnim.Text, frame, rotation.X, rotation.Y, rotation.Z, rotation.W);
                        seAnim.AddScaleKey(boneAnim.Text, frame, scale.X, scale.Y, scale.Z);
                    }
                }
            }

            seAnim.Write(FileName);
        }
Esempio n. 17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="skeleton"></param>
        /// <returns></returns>
        public SBAnimation ImportSBAnimation(string FileName, SBSkeleton skeleton)
        {
            SEAnim anim = SEAnim.Read(FileName);

            var sbAnim = new SBAnimation();

            sbAnim.FrameCount = anim.FrameCount;
            sbAnim.Name       = anim.DeltaTagName;

            Dictionary <string, SBTransformAnimation> nameToAnim = new Dictionary <string, SBTransformAnimation>();

            foreach (var v in anim.AnimationPositionKeys)
            {
                if (!nameToAnim.ContainsKey(v.Key))
                {
                    SBTransformAnimation an = new SBTransformAnimation();
                    an.Name = v.Key;
                    nameToAnim.Add(v.Key, an);
                    sbAnim.TransformNodes.Add(an);
                }

                var a = nameToAnim[v.Key];

                foreach (var k in v.Value)
                {
                    if (k.Data is SELib.Utilities.Vector2 vc)
                    {
                        a.AddKey(k.Frame, (float)vc.X, SBTrackType.TranslateX, InterpolationType.Linear);
                        a.AddKey(k.Frame, (float)vc.Y, SBTrackType.TranslateY, InterpolationType.Linear);
                    }
                    if (k.Data is SELib.Utilities.Vector3 vc3)
                    {
                        a.AddKey(k.Frame, (float)vc3.X, SBTrackType.TranslateX, InterpolationType.Linear);
                        a.AddKey(k.Frame, (float)vc3.Y, SBTrackType.TranslateY, InterpolationType.Linear);
                        a.AddKey(k.Frame, (float)vc3.Z, SBTrackType.TranslateZ, InterpolationType.Linear);
                    }
                }
            }

            foreach (var v in anim.AnimationRotationKeys)
            {
                if (!nameToAnim.ContainsKey(v.Key))
                {
                    SBTransformAnimation an = new SBTransformAnimation();
                    an.Name = v.Key;
                    nameToAnim.Add(v.Key, an);
                    sbAnim.TransformNodes.Add(an);
                }

                var a = nameToAnim[v.Key];

                foreach (var k in v.Value)
                {
                    if (k.Data is SELib.Utilities.Quaternion q)
                    {
                        var euler = Tools.CrossMath.ToEulerAngles(new OpenTK.Quaternion((float)q.X, (float)q.Y, (float)q.Z, (float)q.W).Inverted());

                        a.AddKey(k.Frame, (float)q.X, SBTrackType.RotateX, InterpolationType.Linear);
                        a.AddKey(k.Frame, (float)q.Y, SBTrackType.RotateY, InterpolationType.Linear);
                        a.AddKey(k.Frame, (float)q.Z, SBTrackType.RotateZ, InterpolationType.Linear);
                        a.AddKey(k.Frame, (float)q.W, SBTrackType.RotateW, InterpolationType.Linear);
                    }
                    if (k.Data is SELib.Utilities.Vector3 vc)
                    {
                        a.AddKey(k.Frame, (float)vc.X, SBTrackType.RotateX, InterpolationType.Linear);
                        a.AddKey(k.Frame, (float)vc.Y, SBTrackType.RotateY, InterpolationType.Linear);
                        a.AddKey(k.Frame, (float)vc.Z, SBTrackType.RotateZ, InterpolationType.Linear);
                    }
                }
            }


            foreach (var v in anim.AnimationScaleKeys)
            {
                if (!nameToAnim.ContainsKey(v.Key))
                {
                    SBTransformAnimation an = new SBTransformAnimation();
                    an.Name = v.Key;
                    nameToAnim.Add(v.Key, an);
                    sbAnim.TransformNodes.Add(an);
                }

                var a = nameToAnim[v.Key];

                foreach (var k in v.Value)
                {
                    if (k.Data is SELib.Utilities.Vector3 vc3)
                    {
                        a.AddKey(k.Frame, (float)vc3.X, SBTrackType.ScaleX, InterpolationType.Linear);
                        a.AddKey(k.Frame, (float)vc3.Y, SBTrackType.ScaleY, InterpolationType.Linear);
                        a.AddKey(k.Frame, (float)vc3.Z, SBTrackType.ScaleZ, InterpolationType.Linear);
                    }
                }
            }

            return(sbAnim);
        }
Esempio n. 18
0
        /// <summary>
        /// Print the log to the file
        /// </summary>
        /// <param name="File">The file to debug</param>
        /// <param name="FileOutput">The output log file</param>
        private static void DebugLOGSEAnim(string File, string FileOutput)
        {
            // Load the anim
            var anim = SEAnim.Read(File);
            // Load bones
            var bones = anim.Bones;

            // Log
            Console.WriteLine("   Writing log to file...");
            // Prepare output
            using (StreamWriter writeFile = new StreamWriter(FileOutput))
            {
                // Log
                writeFile.WriteLine("-- SEAnim Debugger Utility --");
                writeFile.WriteLine("");
                // Output initial info
                writeFile.WriteLine("   Header:");
                // Header data
                {
                    writeFile.WriteLine("   - Frame count: " + anim.FrameCount);
                    writeFile.WriteLine("   - Frame rate: " + anim.FrameRate);
                    writeFile.WriteLine("   - Animation type: " + anim.AnimType.ToString());
                    writeFile.WriteLine("   - Bone count: " + anim.BoneCount);
                    writeFile.WriteLine("   - Notetrack count: " + anim.NotificationCount);
                    writeFile.WriteLine("   - Modifiers count: " + anim.AnimationBoneModifiers.Count);
                    // Check for delta
                    if (anim.AnimType == AnimationType.Delta)
                    {
                        // Delta bone must be the first one
                        writeFile.WriteLine("   - Delta tag \"" + anim.DeltaTagName + "\"");
                    }
                }
                // Separate and prepare keys by bone
                writeFile.WriteLine("\n   Frames:");
                // Output keys
                foreach (string Bone in anim.Bones)
                {
                    // Bone header
                    writeFile.WriteLine("   - Bone \"" + Bone + "\" data:");
                    // Translation header
                    writeFile.Write("    - Translations [");
                    // Check for translation keys
                    if (anim.AnimationPositionKeys.ContainsKey(Bone))
                    {
                        // Output translation keys
                        var translationKeys = anim.AnimationPositionKeys[Bone];
                        // Count
                        writeFile.WriteLine(translationKeys.Count + "]");
                        // Output values
                        foreach (SEAnimFrame frame in translationKeys)
                        {
                            // Output the vector
                            writeFile.WriteLine("    [" + frame.Frame + "] {0} {1} {2}", ((Vector3)frame.Data).X, ((Vector3)frame.Data).Y, ((Vector3)frame.Data).Z);
                        }
                    }
                    else
                    {
                        // Had no keys
                        writeFile.WriteLine("0]");
                    }
                    // Rotation header
                    writeFile.Write("    - Rotations [");
                    // Check for rotation keys
                    if (anim.AnimationRotationKeys.ContainsKey(Bone))
                    {
                        // Output rotation keys
                        var rotKeys = anim.AnimationRotationKeys[Bone];
                        // Count
                        writeFile.WriteLine(rotKeys.Count + "]");
                        // Output values
                        foreach (SEAnimFrame frame in rotKeys)
                        {
                            // Output the quat
                            writeFile.WriteLine("    [" + frame.Frame + "] {0} {1} {2} {3}", ((Quaternion)frame.Data).X, ((Quaternion)frame.Data).Y, ((Quaternion)frame.Data).Z, ((Quaternion)frame.Data).W);
                        }
                    }
                    else
                    {
                        // Had no keys
                        writeFile.WriteLine("0]");
                    }
                    // Scales header
                    writeFile.Write("    - Scales [");
                    // Check for scale keys
                    if (anim.AnimationScaleKeys.ContainsKey(Bone))
                    {
                        // Output scale keys
                        var scaleKeys = anim.AnimationScaleKeys[Bone];
                        // Count
                        writeFile.WriteLine(scaleKeys.Count + "]");
                        // Output values
                        foreach (SEAnimFrame frame in scaleKeys)
                        {
                            // Output the vector
                            writeFile.WriteLine("    [" + frame.Frame + "] {0} {1} {2}", ((Vector3)frame.Data).X, ((Vector3)frame.Data).Y, ((Vector3)frame.Data).Z);
                        }
                    }
                    else
                    {
                        // Had no keys
                        writeFile.WriteLine("0]");
                    }
                }
                // Separate and prepare notes
                writeFile.WriteLine("\n   Notifications:");
                // Output notetracks
                foreach (KeyValuePair <string, List <SEAnimFrame> > Notetrack in anim.AnimationNotetracks)
                {
                    // Note header
                    writeFile.WriteLine("   - Note \"" + Notetrack.Key + "\" data:");
                    // Loop and output keys
                    foreach (SEAnimFrame frame in Notetrack.Value)
                    {
                        // Log it
                        writeFile.WriteLine("   [" + frame.Frame + "] plays");
                    }
                }
            }
        }
Esempio n. 19
0
        static void Main(string[] args)
        {
            // SELib Unit Test
            Console.Title = "SELib Unit Tests";
            Console.WriteLine("SELib Unit Tests\n");

            Console.WriteLine("- SEAnims\n");

            #region SEAnim

            {
                // Log
                Console.Write("-- Test 1   ");
                // Make it
                var anim = new SEAnim();
                // Add some keys
                anim.AddTranslationKey("shoulder", 0, 0, 0, 0);
                anim.AddTranslationKey("shoulder", 5, 1, 1, 1);
                anim.AddTranslationKey("shoulder", 10, 10, 10, 10);
                anim.AddTranslationKey("shoulder", 30, 20, 20, 20);
                anim.AddTranslationKey("shoulder", 40, 30, 30, 30);

                // Save it
                anim.Write("test1.seanim");
                // Done
                Console.WriteLine("DONE!");
            }

            {
                // Log
                Console.Write("-- Test 2   ");
                // Make it
                var anim = new SEAnim();
                // Add some keys
                anim.AddTranslationKey("shoulder", 0, 0, 0, 0);
                anim.AddTranslationKey("shoulder", 5, 1, 1, 1);
                anim.AddTranslationKey("shoulder", 10, 10, 10, 10);
                anim.AddTranslationKey("shoulder", 30, 20, 20, 20);
                anim.AddTranslationKey("shoulder", 40, 30, 30, 30);
                // Add some scale
                anim.AddScaleKey("shoulder", 0, 1, 1, 1);
                anim.AddScaleKey("shoulder", 50, 3, 3, 3);

                // Save it
                anim.Write("test2.seanim");
                // Done
                Console.WriteLine("DONE!");
            }

            {
                // Log
                Console.Write("-- Test 3   ");
                // Make it
                var anim = new SEAnim();
                // Add some keys
                anim.AddTranslationKey("shoulder", 0, 0, 0, 0);
                anim.AddTranslationKey("shoulder", 5, 1, 1, 1);
                anim.AddTranslationKey("shoulder", 10, 10, 10, 10);
                anim.AddTranslationKey("shoulder", 30, 20, 20, 20);
                anim.AddTranslationKey("shoulder", 40, 30, 30, 30);
                // Add some scale
                anim.AddScaleKey("shoulder", 0, 1, 1, 1);
                anim.AddScaleKey("shoulder", 50, 3, 3, 3);
                // Add some note
                anim.AddNoteTrack("hello_world", 3);
                anim.AddNoteTrack("bye", 50);

                // Save it
                anim.Write("test3.seanim");
                // Done
                Console.WriteLine("DONE!");
            }

            {
                // Log
                Console.Write("-- Test 4   ");
                // Make it
                var anim = new SEAnim();
                // Add some keys
                anim.AddTranslationKey("shoulder", 0, 0, 0, 0);
                anim.AddTranslationKey("shoulder", 5, 1, 1, 1);
                anim.AddTranslationKey("shoulder", 10, 10, 10, 10);
                anim.AddTranslationKey("shoulder", 30, 20, 20, 20);
                anim.AddTranslationKey("shoulder", 40, 30, 30, 30);
                // Add some scale
                anim.AddScaleKey("shoulder", 0, 1, 1, 1);
                anim.AddScaleKey("shoulder", 50, 3, 3, 3);
                // Add some note
                anim.AddNoteTrack("hello_world", 3);
                anim.AddNoteTrack("bye", 50);

                // Save it (Really, we don't need doubles!!)
                anim.Write("test4.seanim", true);
                // Done
                Console.WriteLine("DONE!");
            }

            {
                // Log
                Console.Write("-- Test 5   ");
                // Make it
                var anim = new SEAnim();
                // Add some keys
                anim.AddTranslationKey("shoulder", 0, 0, 0, 0);
                anim.AddTranslationKey("shoulder", 5, 1, 1, 1);
                anim.AddTranslationKey("shoulder", 10, 10, 10, 10);
                anim.AddTranslationKey("shoulder", 30, 20, 20, 20);
                anim.AddTranslationKey("shoulder", 40, 30, 30, 30);
                // Add some scale
                anim.AddScaleKey("shoulder", 0, 1, 1, 1);
                anim.AddScaleKey("shoulder", 50, 3, 3, 3);
                // Add some rot
                anim.AddRotationKey("shoulder", 0, 0, 0, 0, 1);
                anim.AddRotationKey("shoulder", 50, 0.3, 0.2, 0.5, 1); // Random quat for test
                // Add some note
                anim.AddNoteTrack("hello_world", 3);
                anim.AddNoteTrack("bye", 50);

                // Save it
                anim.Write("test5.seanim");
                // Done
                Console.WriteLine("DONE!");
            }

            {
                // Log
                Console.Write("-- Test 6   ");
                // Read from test 5
                var anim = SEAnim.Read("test5.seanim");

                // Check data
                System.Diagnostics.Debug.Assert(anim.AnimationNotetracks.Count == 2);
                System.Diagnostics.Debug.Assert(anim.AnimationPositionKeys.Count == 1);
                System.Diagnostics.Debug.Assert(anim.AnimationRotationKeys.Count == 1);
                System.Diagnostics.Debug.Assert(anim.AnimationScaleKeys.Count == 1);
                System.Diagnostics.Debug.Assert(anim.BoneCount == 1);
                System.Diagnostics.Debug.Assert(anim.FrameCount == 51);
                System.Diagnostics.Debug.Assert(anim.FrameRate == 30.0);

                // Version
                System.Diagnostics.Debug.Assert(anim.APIVersion == "v1.0.1");

                // Check functions
                System.Diagnostics.Debug.Assert(anim.RenameBone("shoulder", "shoulder") == false);
                System.Diagnostics.Debug.Assert(anim.RenameBone("shoulder", "new_shoulder") == true);

                // Done
                Console.WriteLine("DONE!");
            }

            #endregion

            Console.WriteLine("\n- SEModels\n");

            #region SEModel

            {
                // Log
                Console.Write("-- Test 1   ");
                // Make it
                var model = new SEModel();
                // Add some bones
                model.AddBone("bone_0001", -1, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One);
                model.AddBone("bone_0002", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One);
                model.AddBone("bone_0003", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One);
                model.AddBone("bone_0004", 2, Vector3.Zero, Quaternion.Identity, new Vector3(22, 22, 22), Quaternion.Identity, Vector3.One);

                // Save it
                model.Write("test1.semodel");
                // Done
                Console.WriteLine("DONE!");
            }

            {
                // Log
                Console.Write("-- Test 2   ");
                // Make it
                var model = new SEModel();
                // Allow globals too
                model.ModelBoneSupport = ModelBoneSupportTypes.SupportsBoth;

                // Add some bones
                model.AddBone("bone_0001", -1, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One);
                model.AddBone("bone_0002", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One);
                model.AddBone("bone_0003", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One);
                model.AddBone("bone_0004", 2, Vector3.Zero, Quaternion.Identity, new Vector3(22, 22, 22), Quaternion.Identity, Vector3.One);

                // Save it
                model.Write("test2.semodel");
                // Done
                Console.WriteLine("DONE!");
            }

            #endregion

            // Pause
            Console.Write("\nPress any key to continue...");
            Console.ReadKey();
        }
Esempio n. 20
0
        public static LTBFile Read(FileInfo info)
        {
            var bFlip = info.Name.StartsWith("PV");

            var ltbFile = new LTBFile();

            var br = new ExtendedBinaryReader(info.OpenRead());

            #region Header

            var header = br.ReadUInt16();
            if (header > 20)
            {
                br.Close();
                var lzmaStream = new LzmaDecodeStream(info.OpenRead());
                var ms         = new MemoryStream();

                lzmaStream.CopyTo(ms);

                if (ms.Length == 0)
                {
                    Console.WriteLine($"{info.Name} is not a vaild LTB file.");

                    return(null);
                }

                br = new ExtendedBinaryReader(ms);
                br.Skip(0, true);
            }

            // Skip header
            br.Skip(0x14, true);

            uint version = br.ReadUInt32();

            uint nKeyFrame        = br.ReadUInt32();
            uint nAnim            = br.ReadUInt32();
            uint numBones         = br.ReadUInt32();
            uint nPieces          = br.ReadUInt32();
            uint nChildModels     = br.ReadUInt32();
            uint nTris            = br.ReadUInt32();
            uint nVerts           = br.ReadUInt32();
            uint nVertexWeights   = br.ReadUInt32();
            uint nLODs            = br.ReadUInt32();
            uint nSockets         = br.ReadUInt32();
            uint nWeightSets      = br.ReadUInt32();
            uint nStrings         = br.ReadUInt32();
            uint StringLengths    = br.ReadUInt32();
            uint VertAnimDataSize = br.ReadUInt32();
            uint nAnimData        = br.ReadUInt32();

            string cmdString    = br.ReadStringWithUInt16Length();
            float  globalRadius = br.ReadSingle();

            uint iNumEnabledOBBs = br.ReadUInt32();

            if (iNumEnabledOBBs != 0)
            {
                throw new Exception("LTB with OBB infomations are not supported");
            }

            uint numMesh = br.ReadUInt32();

            #endregion

            var romanisation = new McCuneReischauerRomanisation {
                PreserveNonKoreanText = true
            };

            #region Mesh nodes
            for (int i = 0; i < numMesh; i++)
            {
                string meshName = br.ReadStringWithUInt16Length(ltbEncode);

                meshName = romanisation.RomaniseText(meshName);

                foreach (var kvp in replaceDictionary)
                {
                    meshName = meshName.Replace(kvp.Key, kvp.Value);
                }

                meshName = meshName.ToLower();

                uint numLod = br.ReadUInt32();

                Console.WriteLine($"{meshName} - {numLod} Lods");

                meshName = meshName.ToLower();

                br.Skip((int)numLod * 4 + 8);

                int materialIndex = -1;

                if (!ltbFile.Materials.Any(material => material.Name == meshName))
                {
                    ltbFile.Materials.Add(new SEModelMaterial
                    {
                        Name         = "mtl_" + meshName,
                        MaterialData = new SEModelSimpleMaterial
                        {
                            DiffuseMap = meshName + ".png"
                        }
                    });

                    materialIndex = ltbFile.Materials.Count - 1;
                }
                else
                {
                    materialIndex = ltbFile.Materials.FindIndex(mtl => mtl.Name == meshName);
                }

                for (int iLod = 0; iLod < numLod; iLod++)
                {
                    var mesh = new SEModelMesh();
                    mesh.AddMaterialIndex(materialIndex);

                    var       nNumTex            = br.ReadUInt32();
                    const int MAX_PIECE_TEXTURES = 4;

                    for (int iTex = 0; iTex < MAX_PIECE_TEXTURES; iTex++)
                    {
                        // Texture index
                        br.ReadUInt32();
                    }

                    var renderStyle     = br.ReadUInt32();
                    var nRenderPriority = br.ReadByte();

                    var lodType = (PieceType)br.ReadUInt32();

                    var lodSize = br.ReadUInt32();

                    if (lodSize != 0)
                    {
                        uint numVerts = br.ReadUInt32();
                        uint numTris  = br.ReadUInt32();

                        uint iMaxBonesPerTri  = br.ReadUInt32();
                        uint iMaxBonesPerVert = br.ReadUInt32();

                        Console.WriteLine($"    Lod {iLod}: \n        Vertex count: {numVerts}\n        Triangle count: {numTris}");

                        bool bReIndexBones = false, bUseMatrixPalettes = false;

                        if (lodType == PieceType.SkelMesh)
                        {
                            bReIndexBones = br.ReadBoolean();
                        }

                        DataType[] streamData = { (DataType)br.ReadUInt32(), (DataType)br.ReadUInt32(), (DataType)br.ReadUInt32(), (DataType)br.ReadUInt32() };

                        uint rigidBone = uint.MaxValue;

                        if (lodType == PieceType.RigidMesh)
                        {
                            rigidBone = br.ReadUInt32();
                        }
                        else if (lodType == PieceType.SkelMesh)
                        {
                            bUseMatrixPalettes = br.ReadBoolean();
                        }
                        else
                        {
                            throw new Exception("Unsupported lod type");
                        }

                        if (bUseMatrixPalettes)
                        {
                            uint iMinBone = br.ReadUInt32();
                            uint iMaxBone = br.ReadUInt32();
                        }

                        var boneMap = new List <uint>();

                        if (bReIndexBones)
                        {
                            uint reindexBoneMapSize = br.ReadUInt32();

                            for (int iMap = 0; iMap < reindexBoneMapSize; iMap++)
                            {
                                boneMap.Add(br.ReadUInt32());
                            }
                        }

                        for (int iStream = 0; iStream < 4; ++iStream)
                        {
                            if (!streamData[iStream].HasFlag(DataType.Position))
                            {
                                continue;
                            }

                            for (int iVert = 0; iVert < numVerts; iVert++)
                            {
                                var v = new SEModelVertex();

                                if (streamData[iStream].HasFlag(DataType.Position))
                                {
                                    v.Position = new Vector3
                                    {
                                        X = br.ReadSingle(),
                                        Y = br.ReadSingle(),
                                        Z = br.ReadSingle(),
                                    };

                                    if (bFlip)
                                    {
                                        v.Position.X *= -1;
                                    }

                                    if (rigidBone == uint.MaxValue)
                                    {
                                        var weightSum = 0.0f;

                                        var maxWeight = bUseMatrixPalettes ? iMaxBonesPerVert : iMaxBonesPerTri;

                                        for (int iWeight = 0; iWeight < maxWeight - 1; iWeight++)
                                        {
                                            var weight = br.ReadSingle();

                                            if (weight > 1)
                                            {
                                                throw new Exception("wtf");
                                            }

                                            weightSum += weight;

                                            v.Weights.Add(new SEModelWeight
                                            {
                                                BoneIndex  = uint.MaxValue,
                                                BoneWeight = weight
                                            });
                                        }

                                        if (1.0f - weightSum > float.Epsilon)
                                        {
                                            v.Weights.Add(new SEModelWeight
                                            {
                                                BoneIndex  = uint.MaxValue,
                                                BoneWeight = 1.0f - weightSum
                                            });
                                        }

                                        if (bUseMatrixPalettes)
                                        {
                                            for (int iWeight = 0; iWeight < 4; iWeight++)
                                            {
                                                var boneIndex = br.ReadByte();

                                                if (bReIndexBones)
                                                {
                                                    boneIndex = (byte)boneMap[boneIndex];
                                                }

                                                if (v.Weights.Count > iWeight)
                                                {
                                                    v.Weights[iWeight].BoneIndex = boneIndex;
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (rigidBone >= numBones || rigidBone < 0)
                                        {
                                            throw new Exception("wtf");
                                        }

                                        v.Weights.Add(new SEModelWeight
                                        {
                                            BoneIndex  = rigidBone,
                                            BoneWeight = 1.0f
                                        });
                                    }
                                }

                                if (streamData[iStream].HasFlag(DataType.Normal))
                                {
                                    v.VertexNormal = new Vector3
                                    {
                                        X = br.ReadSingle(),
                                        Y = br.ReadSingle(),
                                        Z = br.ReadSingle(),
                                    };

                                    if (bFlip)
                                    {
                                        v.VertexNormal.X *= -1;
                                    }
                                }

                                if (streamData[iStream].HasFlag(DataType.Color))
                                {
                                    br.Skip(4);
                                }

                                if (streamData[iStream].HasFlag(DataType.UVSets1))
                                {
                                    v.UVSets.Add(new Vector2
                                    {
                                        X = br.ReadSingle(),
                                        Y = br.ReadSingle()
                                    });

                                    if (v.UVSets[0].X > 1.0f)
                                    {
                                        v.UVSets[0].X -= 1.0f;
                                    }
                                }

                                if (streamData[iStream].HasFlag(DataType.UVSets2))
                                {
                                    br.Skip(8);
                                }
                                if (streamData[iStream].HasFlag(DataType.UVSets3))
                                {
                                    br.Skip(8);
                                }
                                if (streamData[iStream].HasFlag(DataType.UVSets4))
                                {
                                    br.Skip(8);
                                }
                                if (streamData[iStream].HasFlag(DataType.BasisVectors))
                                {
                                    br.Skip(24);
                                }

                                if (v.Position == null || v.WeightCount == 0)
                                {
                                    throw new Exception("wtf");
                                }

                                mesh.AddVertex(v);
                            }
                        }

                        for (uint iTriangle = 0; iTriangle < numTris; iTriangle++)
                        {
                            mesh.AddFace(br.ReadUInt16(), br.ReadUInt16(), br.ReadUInt16());
                        }

                        if (lodType == PieceType.SkelMesh && !bUseMatrixPalettes)
                        {
                            var boneComboCount = br.ReadUInt32();

                            for (int iCombo = 0; iCombo < boneComboCount; iCombo++)
                            {
                                int m_BoneIndex_Start = br.ReadUInt16();
                                int m_BoneIndex_End   = m_BoneIndex_Start + br.ReadUInt16();

                                Console.WriteLine($"        Weight Combo: {m_BoneIndex_Start} to {m_BoneIndex_End}");

                                var bones = br.ReadBytes(4);

                                uint m_iIndexIndex = br.ReadUInt32();

                                for (int iVertex = m_BoneIndex_Start; iVertex < m_BoneIndex_End; iVertex++)
                                {
                                    for (int iBone = 0; iBone < 4 && bones[iBone] != 0xFF; iBone++)
                                    {
                                        if (mesh.Verticies[iVertex].Weights.Count <= iBone)
                                        {
                                            break;
                                        }

                                        mesh.Verticies[iVertex].Weights[iBone].BoneIndex = bones[iBone];
                                    }
                                }
                            }
                        }

                        ltbFile.Meshes.Add(mesh);
                        br.Skip(br.ReadByte());
                    }
                }
            }
            #endregion

            #region Bones
            uint[] boneTree = new uint[numBones];

            for (int i = 0; i < numBones; i++)
            {
                var boneName = br.ReadStringWithUInt16Length();
                var boneId   = br.ReadByte();
                var num2     = br.ReadUInt16();

                Matrix4x4 transformMatrix = new Matrix4x4();

                for (int j = 0; j < 4; j++)
                {
                    for (int k = 0; k < 4; k++)
                    {
                        transformMatrix[j, k] = br.ReadSingle();
                    }
                }

                boneTree[i] = br.ReadUInt32();

                var bone = new SEModelBone
                {
                    BoneName       = boneName.Replace('.', '_').Replace('-', '_').Replace(' ', '_'),
                    GlobalRotation = new Quaternion(transformMatrix),
                    GlobalPosition = new Vector3(transformMatrix)
                };

                if (bFlip)
                {
                    bone.GlobalPosition.X *= -1;

                    bone.GlobalRotation.Y *= -1;
                    bone.GlobalRotation.Z *= -1;
                }

                // rotate root bone;
                if (boneId == 0)
                {
                    bone.GlobalRotation *= globalRotation;
                }

                ltbFile.Bones[boneId] = bone;
            }

            uint[] nSubbone = new uint[numBones];
            nSubbone[0] = boneTree[0];

            ltbFile.Bones[0].BoneParent = -1;

            // Build bone tree
            for (byte i = 1; i < numBones; i++)
            {
                nSubbone[i] = boneTree[i];
                for (int j = i - 1; j >= 0; j--)
                {
                    if (nSubbone[j] > 0)
                    {
                        nSubbone[j]--;
                        ltbFile.Bones[i].BoneParent = j;
                        break;
                    }
                }
            }

            #endregion

            #region Random stuff
            Console.WriteLine("\nInternal filenames:");
            var childModelCount = br.ReadUInt32();

            for (int i = 0; i < childModelCount; i++)
            {
                Console.WriteLine(br.ReadStringWithUInt16Length());

                br.Skip((int)br.ReadUInt32() * 4);
            }

            br.Skip(4);
            #endregion

            #region Animations
            if (nAnim > 0)
            {
                var animationCount = br.ReadUInt32();

                Console.WriteLine($"\nAnimation count: {animationCount}\n");

                for (int i = 0; i < animationCount; i++)
                {
                    var seanim = new SEAnim();

                    var dim = new Vector3
                    {
                        X = br.ReadSingle(),
                        Y = br.ReadSingle(),
                        Z = br.ReadSingle(),
                    };

                    var animName = br.ReadStringWithUInt16Length();
                    Console.Write(animName);

                    var compressionType = (AnimCompressionType)br.ReadUInt32();
                    var interpolationMS = br.ReadUInt32();

                    var keyFrameCount = br.ReadUInt32();
                    Console.WriteLine($" has {keyFrameCount} keyframes");

                    for (int iKeyFrame = 0; iKeyFrame < keyFrameCount; iKeyFrame++)
                    {
                        var time       = br.ReadUInt32();
                        var animString = br.ReadStringWithUInt16Length();

                        if (!string.IsNullOrEmpty(animString))
                        {
                            seanim.AddNoteTrack(animString, iKeyFrame);
                        }
                    }

                    for (byte iBone = 0; iBone < numBones; iBone++)
                    {
                        if (compressionType != AnimCompressionType.None)
                        {
                            uint pFrames = br.ReadUInt32();

                            for (int iKeyFrame = 0; iKeyFrame < pFrames; iKeyFrame++)
                            {
                                var v = new Vector3(br.ReadInt16() / 16.0, br.ReadInt16() / 16.0, br.ReadInt16() / 16.0);

                                if (bFlip)
                                {
                                    v.X *= -1;
                                }

                                seanim.AddTranslationKey(ltbFile.Bones[iBone].BoneName, iKeyFrame, v.X, v.Y, v.Z);
                            }

                            uint rFrames = br.ReadUInt32();

                            for (int iKeyFrame = 0; iKeyFrame < rFrames; iKeyFrame++)
                            {
                                var q = new Quaternion(br.ReadInt16() / 16.0, -br.ReadInt16() / 16.0, -br.ReadInt16() / 16.0, br.ReadInt16() / 16.0);

                                if (bFlip)
                                {
                                    q.Y *= -1;
                                    q.Z *= -1;
                                }

                                // rotate root bone;
                                if (iBone == 0)
                                {
                                    q *= globalRotation;
                                }

                                seanim.AddRotationKey(ltbFile.Bones[iBone].BoneName, iKeyFrame, q.X, q.Y, q.Z, q.W);
                            }
                        }
                        else if (compressionType == AnimCompressionType.None)
                        {
                            bool isVertexAnim = br.ReadBoolean();

                            if (isVertexAnim)
                            {
                                throw new Exception("Vertex animation not supported!");
                            }
                            else
                            {
                                for (int iKeyFrame = 0; iKeyFrame < keyFrameCount; iKeyFrame++)
                                {
                                    var v = new Vector3(-br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                                    seanim.AddTranslationKey(ltbFile.Bones[iBone].BoneName, iKeyFrame, v.X, v.Y, v.Z);
                                }

                                for (int iKeyFrame = 0; iKeyFrame < keyFrameCount; iKeyFrame++)
                                {
                                    var q = new Quaternion(br.ReadSingle(), -br.ReadSingle(), -br.ReadSingle(), br.ReadSingle());

                                    // rotate root bone;
                                    if (iBone == 0)
                                    {
                                        q *= globalRotation;
                                    }

                                    seanim.AddRotationKey(ltbFile.Bones[iBone].BoneName, iKeyFrame, q.X, q.Y, q.Z, q.W);
                                }
                            }
                        }
                    }

                    ltbFile.Animations.Add(animName + ".seanim", seanim);
                }
            }

            #endregion

            return(ltbFile);
        }
Esempio n. 21
0
        public void FromSeanim(string FileName)
        {
            SEAnim anim = SEAnim.Read(FileName);

            if (GetResFileU() != null)
            {
                SkeletalAnimU             = new ResU.SkeletalAnim();
                SkeletalAnimU.FrameCount  = anim.FrameCount;
                SkeletalAnimU.FlagsScale  = ResU.SkeletalAnimFlagsScale.Maya;
                SkeletalAnimU.FlagsRotate = ResU.SkeletalAnimFlagsRotate.EulerXYZ;
                SkeletalAnimU.Loop        = anim.Looping;
                SkeletalAnimU.Name        = System.IO.Path.GetFileNameWithoutExtension(FileName);
                SkeletalAnimU.Path        = "";
            }
            else
            {
                SkeletalAnim             = new SkeletalAnim();
                SkeletalAnim.FrameCount  = anim.FrameCount;
                SkeletalAnim.FlagsScale  = SkeletalAnimFlagsScale.Maya;
                SkeletalAnim.FlagsRotate = SkeletalAnimFlagsRotate.EulerXYZ;
                SkeletalAnim.Loop        = anim.Looping;
                SkeletalAnim.Name        = System.IO.Path.GetFileNameWithoutExtension(FileName);
                SkeletalAnim.Path        = "";
            }

            for (int i = 0; i < anim.Bones.Count; i++)
            {
                if (GetResFileU() != null)
                {
                    var BoneAnimU = new ResU.BoneAnim();
                    BoneAnimU.Name = anim.Bones[i];
                    SkeletalAnimU.BoneAnims.Add(BoneAnimU);
                    SkeletalAnimU.BindIndices[i] = ushort.MaxValue;
                    bool IsRoot = false;

                    if (!IsRoot)
                    {
                        BoneAnimU.ApplyIdentity               = false;
                        BoneAnimU.ApplyRotateTranslateZero    = false;
                        BoneAnimU.ApplyRotateZero             = false;
                        BoneAnimU.ApplyScaleOne               = true;
                        BoneAnimU.ApplyScaleVolumeOne         = true;
                        BoneAnimU.ApplyScaleUniform           = true;
                        BoneAnimU.ApplySegmentScaleCompensate = true;
                        BoneAnimU.ApplyTranslateZero          = false;
                    }
                    else
                    {
                        BoneAnimU.ApplyIdentity               = true;
                        BoneAnimU.ApplyRotateTranslateZero    = true;
                        BoneAnimU.ApplyRotateZero             = true;
                        BoneAnimU.ApplyScaleOne               = true;
                        BoneAnimU.ApplyScaleVolumeOne         = true;
                        BoneAnimU.ApplyScaleUniform           = true;
                        BoneAnimU.ApplySegmentScaleCompensate = false;
                        BoneAnimU.ApplyTranslateZero          = true;
                    }
                }
                else
                {
                    var BoneAnim = new BoneAnim();
                    BoneAnim.Name = anim.Bones[i];
                    SkeletalAnim.BoneAnims.Add(BoneAnim);
                    SkeletalAnim.BindIndices[i] = ushort.MaxValue;

                    //Set base data and curves
                    var baseData = new BoneAnimData();
                    if (anim.AnimationPositionKeys.ContainsKey(anim.Bones[i]) &&
                        anim.AnimationPositionKeys[anim.Bones[i]].Count > 0)
                    {
                        BoneAnim.FlagsBase |= BoneAnimFlagsBase.Translate;
                        var keys = anim.AnimationPositionKeys[anim.Bones[i]];
                        var data = (SELib.Utilities.Vector3)keys[0].Data;

                        baseData.Translate = new Syroot.Maths.Vector3F((float)data.X, (float)data.Y, (float)data.Z);

                        if (keys.Count > 1)
                        {
                            AnimCurve curve = new AnimCurve();
                            BoneAnim.Curves.Add(curve);
                            CreateCurveData(curve, keys);
                        }
                    }
                    if (anim.AnimationRotationKeys.ContainsKey(anim.Bones[i]) &&
                        anim.AnimationRotationKeys[anim.Bones[i]].Count > 0)
                    {
                        BoneAnim.FlagsBase |= BoneAnimFlagsBase.Rotate;
                        var keys = anim.AnimationPositionKeys[anim.Bones[i]];
                        var data = (SELib.Utilities.Quaternion)keys[0].Data;

                        baseData.Rotate = new Syroot.Maths.Vector4F((float)data.X, (float)data.Y, (float)data.Z, (float)data.W);

                        if (keys.Count > 1)
                        {
                            AnimCurve curve = new AnimCurve();
                            BoneAnim.Curves.Add(curve);
                            CreateCurveData(curve, keys);
                        }
                    }
                    if (anim.AnimationScaleKeys.ContainsKey(anim.Bones[i]) &&
                        anim.AnimationScaleKeys[anim.Bones[i]].Count > 0)
                    {
                        BoneAnim.FlagsBase |= BoneAnimFlagsBase.Scale;
                        var keys = anim.AnimationPositionKeys[anim.Bones[i]];
                        var data = (SELib.Utilities.Vector3)keys[0].Data;

                        baseData.Scale = new Syroot.Maths.Vector3F((float)data.X, (float)data.Y, (float)data.Z);

                        if (keys.Count > 1)
                        {
                            AnimCurve curve = new AnimCurve();
                            BoneAnim.Curves.Add(curve);
                            CreateCurveData(curve, keys);
                        }
                    }


                    //Set transforms
                    bool IsRoot = false;
                    if (!IsRoot)
                    {
                        BoneAnim.ApplyIdentity               = false;
                        BoneAnim.ApplyRotateTranslateZero    = false;
                        BoneAnim.ApplyRotateZero             = false;
                        BoneAnim.ApplyScaleOne               = true;
                        BoneAnim.ApplyScaleVolumeOne         = true;
                        BoneAnim.ApplyScaleUniform           = true;
                        BoneAnim.ApplySegmentScaleCompensate = true;
                        BoneAnim.ApplyTranslateZero          = false;
                    }
                    else
                    {
                        BoneAnim.ApplyIdentity               = true;
                        BoneAnim.ApplyRotateTranslateZero    = true;
                        BoneAnim.ApplyRotateZero             = true;
                        BoneAnim.ApplyScaleOne               = true;
                        BoneAnim.ApplyScaleVolumeOne         = true;
                        BoneAnim.ApplyScaleUniform           = true;
                        BoneAnim.ApplySegmentScaleCompensate = false;
                        BoneAnim.ApplyTranslateZero          = true;
                    }
                }
            }

            for (int frame = 0; frame < anim.FrameCount; frame++)
            {
            }
        }