예제 #1
0
        private void samplerTB_TextChanged(object sender, EventArgs e)
        {
            if (textureRefListView.SelectedItems.Count <= 0)
            {
                return;
            }

            var index = textureRefListView.SelectedIndices[0];

            //   samplerHintTB.Text = GetHint(samplerHintTB.Text);

            bool IsDuped = false;

            List <string> KeyCheck = new List <string>();

            foreach (MatTexture item in material.TextureMaps)
            {
                if (!KeyCheck.Contains(item.SamplerName))
                {
                    KeyCheck.Add(item.SamplerName);
                }
                else
                {
                    IsDuped = true;
                    STErrorDialog.Show($"A sampler with the same name already exists! {item.SamplerName}",
                                       this.Text, "");
                }
            }
            if (!IsDuped)
            {
                material.TextureMaps[index].SamplerName = samplerTB.Text;
            }

            KeyCheck.Clear();
        }
예제 #2
0
        public Dictionary <string, STGenericTexture> GetTextures()
        {
            Dictionary <string, STGenericTexture> textures = new Dictionary <string, STGenericTexture>();

            if (IFileInfo.ArchiveParent != null)
            {
                foreach (var file in IFileInfo.ArchiveParent.Files)
                {
                    try
                    {
                        if (Utils.GetExtension(file.FileName) == ".tpl")
                        {
                            TPL tpl = (TPL)file.OpenFile();
                            file.FileFormat = tpl;
                            foreach (var tex in tpl.TextureList)
                            {
                                //Only need the first texture
                                if (!textures.ContainsKey(tex.Text))
                                {
                                    textures.Add(file.FileName, tex);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        STErrorDialog.Show($"Failed to load texture {file.FileName}. ", "Layout Editor", ex.ToString());
                    }
                }
            }

            return(textures);
        }
예제 #3
0
        public FMAT GetMaterial()
        {
            if (Parent == null)
            {
                STErrorDialog.Show($"Error! Shape {Text} has no parent node!", "GetMaterial", "");
            }

            return(((FMDL)Parent.Parent).materials.Values.ElementAt(MaterialIndex));
        }
예제 #4
0
        public override void SetImageData(Bitmap bitmap, int ArrayLevel)
        {
            if (bitmap == null)
            {
                return; //Image is likely disposed and not needed to be applied
            }
            texture.Format = ConvertToGx2Format(Format);
            texture.Width  = (uint)bitmap.Width;
            texture.Height = (uint)bitmap.Height;
            uint swizzle = (texture.Swizzle >> 8) & 7;

            if (MipCount != 1)
            {
                MipCount = GenerateMipCount(bitmap.Width, bitmap.Height);
                if (MipCount == 0)
                {
                    MipCount = 1;
                }
            }

            texture.MipCount   = MipCount;
            texture.MipOffsets = new uint[MipCount];

            try
            {
                //Create image block from bitmap first
                var data = GenerateMipsAndCompress(bitmap, MipCount, Format);

                bitmap.Dispose();

                //Swizzle and create surface
                var surface = GX2.CreateGx2Texture(data, Text,
                                                   (uint)texture.TileMode,
                                                   (uint)texture.AAMode,
                                                   (uint)texture.Width,
                                                   (uint)texture.Height,
                                                   (uint)texture.Depth,
                                                   (uint)texture.Format,
                                                   (uint)swizzle,
                                                   (uint)texture.Dim,
                                                   (uint)texture.MipCount
                                                   );

                var tex = FromGx2Surface(surface, texture.Name);
                UpdateTex(tex);

                IsEdited = true;
                Read(texture);
                LoadOpenGLTexture();
                LibraryGUI.UpdateViewport();
            }
            catch (Exception ex)
            {
                STErrorDialog.Show("Failed to swizzle and compress image " + Text, "Error", ex.ToString());
            }
        }
예제 #5
0
            public override void SetImageData(Bitmap bitmap, int ArrayLevel)
            {
                if (bitmap == null)
                {
                    return; //Image is likely disposed and not needed to be applied
                }
                RedChannel   = SetChannel(surface.compSel[0]);
                GreenChannel = SetChannel(surface.compSel[1]);
                BlueChannel  = SetChannel(surface.compSel[2]);
                AlphaChannel = SetChannel(surface.compSel[3]);

                surface.format = (uint)FTEX.ConvertToGx2Format(Format);
                surface.width  = (uint)bitmap.Width;
                surface.height = (uint)bitmap.Height;

                if (MipCount != 1)
                {
                    MipCount = GenerateMipCount(bitmap.Width, bitmap.Height);
                    if (MipCount == 0)
                    {
                        MipCount = 1;
                    }
                }

                surface.numMips   = MipCount;
                surface.mipOffset = new uint[MipCount];

                try
                {
                    //Create image block from bitmap first
                    var data = GenerateMipsAndCompress(bitmap, MipCount, Format);

                    //Swizzle and create surface
                    var NewSurface = GX2.CreateGx2Texture(data, Text,
                                                          (uint)surface.tileMode,
                                                          (uint)surface.aa,
                                                          (uint)surface.width,
                                                          (uint)surface.height,
                                                          (uint)surface.depth,
                                                          (uint)surface.format,
                                                          (uint)surface.swizzle,
                                                          (uint)surface.dim,
                                                          (uint)surface.numMips
                                                          );

                    ApplySurface(NewSurface);
                    IsEdited = true;
                    LoadOpenGLTexture();
                    LibraryGUI.Instance.UpdateViewport();
                }
                catch (Exception ex)
                {
                    STErrorDialog.Show("Failed to swizzle and compress image " + Text, "Error", ex.ToString());
                }
            }
예제 #6
0
 private void CompileLayout(object sender, EventArgs e)
 {
     try
     {
         activeLayout.ConvertFromString(editor.GetText());
     }
     catch (Exception ex)
     {
         STErrorDialog.Show("Failed to convert BFLYT! ", "Text Converter", ex.ToString());
     }
 }
예제 #7
0
        private bool CheckParser()
        {
            bool CanParse = true;

            float valSingle;
            int   valInt;
            byte  valByte;

            string Error = "";

            int curLine = 0;

            foreach (var line in valueTB.Lines)
            {
                bool Success = true;

                if (Type == "WString")
                {
                }
                else if (Type == "String")
                {
                }
                else if (line == string.Empty) //Don't parse empty lines, instead we'll skip those
                {
                }
                else if (Type == "Single")
                {
                    Success = float.TryParse(line, out valSingle);
                }
                else if (Type == "Int32")
                {
                    Success = int.TryParse(line, out valInt);
                }
                else if (Type == "Byte")
                {
                    Success = byte.TryParse(line, out valByte);
                }


                if (!Success)
                {
                    CanParse = false;

                    Error += $"Invalid data type at line {curLine}.\n";
                }
                curLine++;
            }
            if (CanParse == false)
            {
                STErrorDialog.Show($"Data must be type of {Type}", "User Data", Error);
            }

            return(CanParse);
        }
예제 #8
0
        public override void SetImageData(System.Drawing.Bitmap bitmap, int ArrayLevel)
        {
            if (bitmap == null || image == null)
            {
                return; //Image is likely disposed and not needed to be applied
            }
            MipCount = 1;
            var Gx2Format = FTEX.ConvertToGx2Format(Format);

            uint swizzle = (image.Swizzle >> 8) & 7;

            try
            {
                //Create image block from bitmap first
                var data = GenerateMipsAndCompress(bitmap, MipCount, Format);

                //Swizzle and create surface
                var surface = GX2.CreateGx2Texture(data, Text,
                                                   (uint)image.TileMode,
                                                   (uint)0,
                                                   (uint)image.Width,
                                                   (uint)image.Height,
                                                   (uint)1,
                                                   (uint)Gx2Format,
                                                   (uint)swizzle,
                                                   (uint)1,
                                                   (uint)MipCount
                                                   );

                image.Swizzle     = surface.swizzle;
                image.BflimFormat = FormatsWiiU.FirstOrDefault(x => x.Value == Format).Key;
                image.Height      = (ushort)surface.height;
                image.Width       = (ushort)surface.width;

                Width  = image.Width;
                Height = image.Height;

                ImageData = surface.data;

                IsEdited = true;
                LoadOpenGLTexture();
                LibraryGUI.UpdateViewport();
            }
            catch (Exception ex)
            {
                STErrorDialog.Show("Failed to swizzle and compress image " + Text, "Error", ex.ToString());
            }
        }
 private void stButton2_Click(object sender, EventArgs e)
 {
     List<string> KeyCheck = new List<string>();
     foreach (AtributeInput item in AtributeInputs)
     {
         if (!KeyCheck.Contains(item.ShaderVariable))
             KeyCheck.Add(item.ShaderVariable);
         else
         {
             STErrorDialog.Show($"A Shader Variable with the same name already exists! {item.ShaderVariable}",
                 this.Text, "");
             DialogResult = DialogResult.None;
         }
     }
     KeyCheck.Clear();
 }
예제 #10
0
        public override void SetImageData(System.Drawing.Bitmap bitmap, int ArrayLevel)
        {
            if (bitmap == null || image == null)
            {
                return; //Image is likely disposed and not needed to be applied
            }
            MipCount = 1;
            var CtrFormat = CTR_3DS.ConvertToPICAFormat(Format);

            try
            {
                //Create image block from bitmap first
                var data = GenerateMipsAndCompress(bitmap, MipCount, Format);

                //Swizzle and create surface

                /*    var surface = GX2.CreateGx2Texture(data, Text,
                 *      (uint)image.TileMode,
                 *      (uint)0,
                 *      (uint)image.Width,
                 *      (uint)image.Height,
                 *      (uint)1,
                 *      (uint)Gx2Format,
                 *      (uint)0,
                 *      (uint)1,
                 *      (uint)MipCount
                 *      );
                 *
                 *  image.Swizzle = (byte)surface.swizzle;
                 *  image.BCLIMFormat = ConvertFormatGenericToBflim(Format);
                 *  image.Height = (ushort)surface.height;
                 *  image.Width = (ushort)surface.width;*/

                Width  = image.Width;
                Height = image.Height;

                // ImageData = surface.data;

                IsEdited = true;
                LoadOpenGLTexture();
                LibraryGUI.UpdateViewport();
            }
            catch (Exception ex)
            {
                STErrorDialog.Show("Failed to swizzle and compress image " + Text, "Error", ex.ToString());
            }
        }
예제 #11
0
        public override void SetImageData(Bitmap bitmap, int ArrayLevel)
        {
            if (bitmap == null)
            {
                return; //Image is likely disposed and not needed to be applied
            }
            uint Gx2Format = (uint)Bfres.Structs.FTEX.ConvertToGx2Format(Format);

            Width  = (uint)bitmap.Width;
            Height = (uint)bitmap.Height;

            MipCount = 1;
            uint[] MipOffsets = new uint[MipCount];

            try
            {
                //Create image block from bitmap first
                var data = GenerateMipsAndCompress(bitmap, MipCount, Format);

                //Swizzle and create surface
                var surface = GX2.CreateGx2Texture(data, Text,
                                                   (uint)2,
                                                   (uint)0,
                                                   (uint)Width,
                                                   (uint)Height,
                                                   (uint)1,
                                                   (uint)Gx2Format,
                                                   (uint)Swizzle,
                                                   (uint)1,
                                                   (uint)MipCount
                                                   );

                TextureTGLP.Format      = (ushort)ConvertToGx2(Format);
                TextureTGLP.SheetHeight = (ushort)surface.height;
                TextureTGLP.SheetWidth  = (ushort)surface.width;
                TextureTGLP.SheetDataList[SheetIndex] = surface.data;

                IsEdited = true;
                UpdateEditor();
            }
            catch (Exception ex)
            {
                STErrorDialog.Show("Failed to swizzle and compress image " + Text, "Error", ex.ToString());
            }
        }
예제 #12
0
        public AudioPlayer OpenForm()
        {
            AudioPlayer form = new AudioPlayer();

            form.Text = FileName;
            form.Dock = DockStyle.Fill;

            try
            {
                form.LoadFile(audioData, this);
            }
            catch (Exception ex)
            {
                STErrorDialog.Show("Failed to open audio player!", "Audio Player", ex.ToString());
            }


            return(form);
        }
예제 #13
0
        private void stButton2_Click(object sender, EventArgs e)
        {
            List <string> KeyCheck = new List <string>();

            foreach (SamplerInput item in SamplerInputs)
            {
                if (!KeyCheck.Contains(item.ResourceInput))
                {
                    KeyCheck.Add(item.ResourceInput);
                }
                else
                {
                    STErrorDialog.Show($"A Resource Input with the same name already exists! {item.ResourceInput}",
                                       this.Text, "");
                    DialogResult = DialogResult.None;
                }
            }
            KeyCheck.Clear();
        }
예제 #14
0
        private void stButton2_Click(object sender, EventArgs e)
        {
            List <string> KeyCheck = new List <string>();

            foreach (BoneEntry item in Bones)
            {
                if (!KeyCheck.Contains(item.Name))
                {
                    KeyCheck.Add(item.Name);
                }
                else
                {
                    STErrorDialog.Show($"A Bones with the same name already exists! {item.Name}",
                                       this.Text, "");
                    DialogResult = DialogResult.None;
                }
            }
            KeyCheck.Clear();
        }
예제 #15
0
        public AudioPlayerPanel OpenForm()
        {
            if (audioData == null)
                throw new Exception("Audio data is null!");

            AudioPlayerPanel form = new AudioPlayerPanel();
            form.Text = FileName;
            form.Dock = DockStyle.Fill;

            try
            {
                form.LoadFile(audioData, this);
            }
            catch (Exception ex)
            {
                STErrorDialog.Show("Failed to open audio player!", "Audio Player" , ex.ToString());
            }


            return form;
        }
예제 #16
0
        //For tex2
        public static void GenerateMipmaps(uint mipCount, TEX_FORMAT Format, Bitmap bitmap, Texture texture)
        {
            if (bitmap == null)
            {
                return; //Image is likely disposed and not needed to be applied
            }
            Console.WriteLine(texture.Name + " mipCount " + mipCount);
            texture.MipCount   = mipCount;
            texture.MipOffsets = new uint[mipCount];

            try
            {
                //Create image block from bitmap first
                var data = GenerateMipsAndCompress(bitmap, mipCount, Format);

                bitmap.Dispose();

                //Swizzle and create surface
                var surface = GX2.CreateGx2Texture(data, texture.Name,
                                                   (uint)texture.TileMode,
                                                   (uint)texture.AAMode,
                                                   (uint)texture.Width,
                                                   (uint)texture.Height,
                                                   (uint)texture.Depth,
                                                   (uint)texture.Format,
                                                   (uint)texture.Swizzle,
                                                   (uint)texture.Dim,
                                                   (uint)texture.MipCount
                                                   );

                var tex = FromGx2Surface(surface, texture.Name);
                texture.MipData    = tex.MipData;
                texture.MipOffsets = tex.MipOffsets;
                texture.MipCount   = tex.MipCount;
            }
            catch (Exception ex)
            {
                STErrorDialog.Show("Failed to swizzle and compress image " + texture.Name, "Error", ex.ToString());
            }
        }
예제 #17
0
        private void SaveFileForCompression(bool Compress, string[] fileNames, ICompressionFormat compressionFormat)
        {
            if (fileNames.Length == 0)
            {
                return;
            }

            string ext = Compress ? ".comp" : ".dec";

            if (compressionFormat.Extension.Length > 0 && Compress)
            {
                ext = compressionFormat.Extension[0].Replace("*", string.Empty);
            }

            List <string> failedFiles = new List <string>();

            if (fileNames.Length > 1)
            {
                FolderSelectDialog ofd = new FolderSelectDialog();
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    foreach (var file in fileNames)
                    {
                        string name = Path.GetFileName(file);
                        using (var data = new FileStream(file, FileMode.Open, FileAccess.Read))
                        {
                            try
                            {
                                Stream stream;
                                if (Compress)
                                {
                                    stream = compressionFormat.Compress(data);
                                }
                                else
                                {
                                    compressionFormat.Identify(data, file);
                                    stream = compressionFormat.Decompress(data);
                                }

                                if (stream != null)
                                {
                                    stream.ExportToFile($"{ofd.SelectedPath}/{name}{ext}");
                                    stream.Flush();
                                    stream.Close();
                                }
                            }
                            catch (Exception ex)
                            {
                                failedFiles.Add($"{file} \n\n {ex} \n\n");
                            }
                        }
                    }

                    if (failedFiles.Count > 0)
                    {
                        string action = Compress ? "compress" : "decompress";
                        STErrorDialog.Show($"Some files failed to {action}! See detail list of failed files.", "Switch Toolbox",
                                           string.Join("\n", failedFiles.ToArray()));
                    }
                    else
                    {
                        MessageBox.Show("Files batched successfully!");
                    }
                }
            }
            else
            {
                SaveFileDialog sfd  = new SaveFileDialog();
                string         name = Path.GetFileName(fileNames[0]);
                sfd.FileName = name + ext;
                sfd.Filter   = "All files(*.*)|*.*";

                Cursor.Current = Cursors.Default;
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        using (var data = new FileStream(fileNames[0], FileMode.Open, FileAccess.Read))
                        {
                            Stream stream;
                            if (Compress)
                            {
                                stream = compressionFormat.Compress(data);
                            }
                            else
                            {
                                compressionFormat.Identify(data, sfd.FileName);
                                stream = compressionFormat.Decompress(data);
                            }

                            if (stream != null)
                            {
                                stream.ExportToFile(sfd.FileName);
                                stream.Flush();
                                stream.Close();

                                MessageBox.Show($"File has been saved to {sfd.FileName}", "Save Notification");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        string action = Compress ? "compress" : "decompress";
                        STErrorDialog.Show($"Failed to {action}! See details for info.", "Switch Toolbox", ex.ToString());
                    }
                }
            }
        }
예제 #18
0
        public void ApplyImportSettings(BfresModelImportSettings settings, FMAT mat)
        {
            //    VertexSkinCount = settings.SkinCountLimit;

            if (settings.FlipUVsVertical)
            {
                foreach (Vertex v in vertices)
                {
                    v.uv0 = new Vector2(v.uv0.X, 1 - v.uv0.Y);
                }
            }
            if (settings.RecalculateNormals)
            {
                CalculateNormals();
            }
            if (settings.Rotate90DegreesY)
            {
                TransformPosition(Vector3.Zero, new Vector3(90, 0, 0), new Vector3(1));
            }
            if (settings.Rotate90DegreesNegativeY)
            {
                TransformPosition(Vector3.Zero, new Vector3(-90, 0, 0), new Vector3(1));
            }
            if (settings.EnableTangents)
            {
                try
                {
                    bool UseUVLayer2 = false;

                    //for BOTW if it uses UV layer 2 for normal maps use second UV map
                    if (Parent != null && GetMaterial().shaderassign.options.ContainsKey("uking_texture2_texcoord"))
                    {
                        float value = float.Parse(GetMaterial().shaderassign.options["uking_texture2_texcoord"]);
                        UseUVLayer2 = (value == 1);
                    }

                    CalculateTangentBitangent(UseUVLayer2);
                }
                catch (Exception ex)
                {
                    STErrorDialog.Show($"Failed to generate tangents for mesh {Text}", "Tangent Calculation", ex.ToString());
                }
            }
            if (settings.SetDefaultParamData)
            {
                foreach (var param in mat.matparam.Values)
                {
                    switch (param.Name)
                    {
                    case "const_color0":
                    case "const_color1":
                    case "const_color2":
                    case "const_color3":
                    case "base_color_mul_color":
                    case "uniform0_mul_color":
                    case "uniform1_mul_color":
                    case "uniform2_mul_color":
                    case "uniform3_mul_color":
                    case "uniform4_mul_color":
                    case "proc_texture_2d_mul_color":
                    case "proc_texture_3d_mul_color":
                    case "displacement1_color":
                    case "ripple_emission_color":
                    case "hack_color":
                    case "stain_color":
                    case "displacement_color":
                        param.ValueFloat = new float[] { 1, 1, 1, 1 };
                        break;

                    case "gsys_bake_st0":
                    case "gsys_bake_st1":
                        param.ValueFloat = new float[] { 1, 1, 0, 0 };
                        break;
                    }
                }
            }
        }
예제 #19
0
        public void Replace(string FileName, ResFile resFileNX, ResU.ResFile resFileU)
        {
            string ext = Utils.GetExtension(FileName);

            if (ext == ".bfska")
            {
                bool IsSwitch = BfresUtilies.IsSubSectionSwitch(FileName);

                if (resFileU != null)
                {
                    //If it's a switch animation try to conver it to wii u
                    if (IsSwitch)
                    {
                        var ska = new SkeletalAnim();
                        ska.Import(FileName);
                        SkeletalAnimU      = BfresPlatformConverter.FSKAConvertSwitchToWiiU(ska);
                        SkeletalAnimU.Name = Text;
                        LoadAnim(SkeletalAnimU);
                    }
                    else
                    {
                        SkeletalAnimU.Import(FileName, resFileU);
                        SkeletalAnimU.Name = Text;
                        LoadAnim(SkeletalAnimU);
                    }
                }
                else
                {
                    if (IsSwitch)
                    {
                        SkeletalAnim.Import(FileName);
                        SkeletalAnim.Name = Text;
                        LoadAnim(SkeletalAnim);
                    }
                    else
                    {
                        //Create a new wii u skeletal anim and try to convert it instead
                        var ska = new ResU.SkeletalAnim();
                        ska.Import(FileName, new ResU.ResFile());
                        SkeletalAnim      = BfresPlatformConverter.FSKAConvertWiiUToSwitch(ska);
                        SkeletalAnim.Name = Text;
                        LoadAnim(SkeletalAnim);
                    }
                }
            }
            else if (ext == ".anim")
            {
                FromAnim(FileName);
            }
            else if (ext == ".seanim")
            {
                STSkeleton skeleton = GetActiveSkeleton();

                if (skeleton != null)
                {
                    var ska = FromGeneric(SEANIM.Read(FileName, skeleton));
                    ska.Loop = this.CanLoop;
                    UpdateAnimation(ska);
                }
                else
                {
                    STErrorDialog.Show("No matching skeleton bones found to assign!", "Skeleton Importer", "");
                }
            }
            else if (ext == ".smd")
            {
                STSkeleton skeleton = GetActiveSkeleton();

                if (skeleton != null)
                {
                    var ska = FromGeneric(SMD.Read(FileName, skeleton));
                    ska.Loop = this.CanLoop;
                    UpdateAnimation(ska);
                }
                else
                {
                    STErrorDialog.Show("No matching skeleton bones found to assign!", "Skeleton Importer", "");
                }
            }
            else if (ext == ".chr0")
            {
                FromChr0(FileName, resFileU != null);
            }
            else if (ext == ".dae")
            {
                //   FromAssimp(FileName, resFileU != null);
            }
            else if (ext == ".fbx")
            {
                //   FromAssimp(FileName, resFileU != null);
            }
        }
예제 #20
0
        private void ImportModel(GFLXModelImporter importer,
                                 List <STGenericMaterial> importedMaterials, List <STGenericObject> importedMeshes,
                                 STSkeleton skeleton)
        {
            Model.Model.Groups.Clear();
            Model.Model.Meshes.Clear();

            List <string> textures = Model.Textures.ToList();

            foreach (var mat in importedMaterials)
            {
            }

            var meshes = GeneratePolygonGroups(importedMeshes, importedMaterials, textures, importer.Settings);

            //Once mesh groups are merged search for bone nodes
            //The bone section is basically a node tree
            //Which contains nodes for meshes
            //We need to remove the original and replace with new ones
            //Then index these in our mesh groups
            if (importer.ImportNewBones)
            {
                //Clear the original bones and nodes
                Model.Skeleton.bones.Clear();
                Model.Model.Bones.Clear();

                List <int> SkinningIndices = new List <int>();
                foreach (var genericBone in skeleton.bones)
                {
                    var scale = genericBone.Scale;
                    var trans = genericBone.Position;
                    var rot   = genericBone.EulerRotation;

                    Bone bone = new Bone();
                    bone.Name        = genericBone.Text;
                    bone.BoneType    = 0;
                    bone.Parent      = genericBone.parentIndex;
                    bone.Zero        = 0;
                    bone.Visible     = false;
                    bone.Scale       = new GFMDLStructs.Vector3(scale.X, scale.Y, scale.Z);
                    bone.Rotation    = new GFMDLStructs.Vector3(rot.X, rot.Y, rot.Z);
                    bone.Translation = new GFMDLStructs.Vector3(trans.X, trans.Y, trans.Z);
                    bone.RadiusStart = new GFMDLStructs.Vector3(0, 0, 0);
                    bone.RadiusEnd   = new GFMDLStructs.Vector3(0, 0, 0);

                    Model.Model.Bones.Add(bone);
                }
            }

            int originIndex = int.MaxValue;

            //Go through each bone and remove the original mesh node
            List <STBone> bonesToRemove = new List <STBone>();

            for (int i = 0; i < Model.Skeleton.bones.Count; i++)
            {
                //Reset bone as rigid
                var node = (GFLXBone)Model.Skeleton.bones[i];
                node.Bone.RigidCheck = new BoneRigidData()
                {
                    Unknown1 = 0
                };
                if (node.Bone.BoneType == 1)
                {
                    node.Bone.BoneType = 0;
                }

                int index = Model.Skeleton.bones.IndexOf(node);

                if (node.Text == "Origin")
                {
                    originIndex = index;
                }

                //Check if the bone is rigged to any meshes and use skinning
                for (int m = 0; m < meshes.Count; m++)
                {
                    if (meshes[m].vertices.Any(x => x.boneNames.Contains(node.Text)))
                    {
                        node.Bone.BoneType   = 1;
                        node.Bone.RigidCheck = null;
                    }
                }

                if (Model.GenericMeshes.Any(x => x.Text == node.Text))
                {
                    bonesToRemove.Add(node);
                    Model.Model.Bones.Remove(node.Bone);
                }

                /*  if (Model.Model.CollisionGroups?.Count != 0)
                 * {
                 *    var collisionGroups = Model.Model.CollisionGroups;
                 *    for (int c = 0; c < collisionGroups.Count; c++)
                 *    {
                 *        if (collisionGroups[c].BoneIndex == i)
                 *        {
                 *
                 *        }
                 *    }
                 * }*/
            }

            foreach (var bone in bonesToRemove)
            {
                Model.Skeleton.bones.Remove(bone);
            }

            bonesToRemove.Clear();

            Model.Model.CollisionGroups = new List <CollisionGroup>();

            List <int> skinningIndices = Model.GenerateSkinningIndices();

            //Set an empty bone with rigging if there is no rigging
            if (importer.Settings.MeshSettings.Any(x => x.HasBoneIndices) && skinningIndices.Count == 0)
            {
                var node = (GFLXBone)Model.Skeleton.bones[0];
                node.Bone.RigidCheck = null;
                node.Bone.BoneType   = 1;
                skinningIndices.Add(0);
            }

            List <string> unmappedBones = new List <string>();

            foreach (var mesh in meshes)
            {
                var setting = importer.Settings.MeshSettings[meshes.IndexOf(mesh)];

                for (int i = 0; i < mesh.vertices.Count; i++)
                {
                    if (setting.SetNormalsToColorChannel2)
                    {
                        mesh.vertices[i].col2 = new OpenTK.Vector4(
                            mesh.vertices[i].nrm.X * 0.5f + 0.5f,
                            mesh.vertices[i].nrm.Y * 0.5f + 0.5f,
                            mesh.vertices[i].nrm.Z * 0.5f + 0.5f,
                            1);
                    }

                    //Single bind if no bones are mapped but setting is enabled
                    if (setting.HasBoneIndices && mesh.vertices[i].boneNames.Count == 0)
                    {
                        mesh.vertices[i].boneIds.Add(skinningIndices.FirstOrDefault());
                        mesh.vertices[i].boneWeights.Add(1);
                    }

                    if (importer.RotationY != 0)
                    {
                        var transform = OpenTK.Matrix4.CreateRotationX(OpenTK.MathHelper.DegreesToRadians(importer.RotationY));
                        mesh.vertices[i].pos = OpenTK.Vector3.TransformPosition(mesh.vertices[i].pos, transform);
                        mesh.vertices[i].nrm = OpenTK.Vector3.TransformPosition(mesh.vertices[i].nrm, transform);
                    }

                    if (importer.Settings.FlipUVsVertical)
                    {
                        mesh.vertices[i].uv0 = new Vector2(0, 1) - mesh.vertices[i].uv0;
                        mesh.vertices[i].uv1 = new Vector2(0, 1) - mesh.vertices[i].uv1;
                        mesh.vertices[i].uv2 = new Vector2(0, 1) - mesh.vertices[i].uv2;
                    }

                    if (importer.Settings.OptmizeZeroWeights)
                    {
                        float[] weightsA = new float[4];

                        int MaxWeight = 255;
                        for (int j = 0; j < 4; j++)
                        {
                            if (mesh.vertices[i].boneWeights.Count < j + 1)
                            {
                                weightsA[j] = 0;
                                MaxWeight   = 0;
                            }
                            else
                            {
                                int weight = (int)(mesh.vertices[i].boneWeights[j] * 255);
                                if (mesh.vertices[i].boneWeights.Count == j + 1)
                                {
                                    weight = MaxWeight;
                                }

                                if (weight >= MaxWeight)
                                {
                                    weight    = MaxWeight;
                                    MaxWeight = 0;
                                }
                                else
                                {
                                    MaxWeight -= weight;
                                }

                                weightsA[j] = weight / 255f;
                            }
                        }

                        mesh.vertices[i].boneWeights = weightsA.ToList();
                    }

                    for (int j = 0; j < mesh.vertices[i].boneNames?.Count; j++)
                    {
                        string boneName  = mesh.vertices[i].boneNames[j];
                        int    boneIndex = Model.Model.Bones.IndexOf(Model.Model.Bones.Where(p => p.Name == boneName).FirstOrDefault());

                        if (boneIndex != -1 && skinningIndices.IndexOf(boneIndex) != -1)
                        {
                            mesh.vertices[i].boneIds.Add(boneIndex);
                        }
                        else
                        {
                            if (!unmappedBones.Contains(boneName))
                            {
                                unmappedBones.Add(boneName);
                            }
                        }
                    }
                }
            }

            //Adjust materials if necessary
            if (importer.Settings.ResetUVTransform)
            {
                foreach (var mat in Model.GenericMaterials)
                {
                    foreach (var param in mat.ValueParams)
                    {
                        if (param.Key.Contains("UVScale"))
                        {
                            param.Value.Value = 1;
                        }
                        if (param.Key.Contains("UVTranslate"))
                        {
                            param.Value.Value = 0;
                        }
                        if (param.Key.Contains("ColorBaseU"))
                        {
                            param.Value.Value = 0;
                        }
                        if (param.Key.Contains("ColorBaseV"))
                        {
                            param.Value.Value = 0;
                        }
                    }
                }
            }

            //Now add brand new mesh nodes
            foreach (var mesh in meshes)
            {
                int index = meshes.IndexOf(mesh);

                var setting = importer.Settings.MeshSettings[index];

                Bone bone = new Bone();
                bone.Name        = mesh.ObjectName;
                bone.BoneType    = 0;
                bone.Parent      = 0;
                bone.Zero        = 0;
                bone.Visible     = false;
                bone.Scale       = new GFMDLStructs.Vector3(1, 1, 1);
                bone.Rotation    = new GFMDLStructs.Vector3(0, 0, 0);
                bone.Translation = new GFMDLStructs.Vector3(0, 0, 0);
                bone.RadiusStart = new GFMDLStructs.Vector3(0, 0, 0);
                bone.RadiusEnd   = new GFMDLStructs.Vector3(0, 0, 0);
                //     bone.RigidCheck = new BoneRigidData();

                Model.Model.Bones.Add(bone);
                int NodeIndex = Model.Model.Bones.IndexOf(bone);

                //Now create the associated group
                var group = new Group();
                group.Bounding  = Model.GenerateBoundingBox(mesh);
                group.BoneIndex = (uint)NodeIndex;
                group.MeshIndex = (uint)index;
                group.Layer     = 0;
                Model.Model.Groups.Add(group);

                //Now create our mesh data
                var meshData = new Mesh();
                Model.Model.Meshes.Add(meshData);

                if (setting.HasTangents || setting.HasBitangents)
                {
                    try {
                        mesh.CalculateTangentBitangent(false);
                    }
                    catch { }
                }

                //Add attributes based on settings
                IList <MeshAttribute> attributes = new List <MeshAttribute>();
                attributes.Add(new MeshAttribute()
                {
                    VertexType   = (uint)VertexType.Position,
                    BufferFormat = (uint)setting.PositionFormat,
                    ElementCount = 3,
                });

                if (setting.HasNormals)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.Normal,
                        BufferFormat = (uint)setting.NormalFormat,
                        ElementCount = 4,
                    });
                }

                if (setting.HasTangents)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.Tangents,
                        BufferFormat = (uint)setting.TangentsFormat,
                        ElementCount = 4,
                    });
                }

                if (setting.HasTexCoord1)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.UV1,
                        BufferFormat = (uint)setting.TexCoord1Format,
                        ElementCount = 2,
                    });
                }
                if (setting.HasTexCoord2)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.UV2,
                        BufferFormat = (uint)setting.TexCoord2Format,
                        ElementCount = 2,
                    });
                }
                if (setting.HasTexCoord3)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.UV3,
                        BufferFormat = (uint)setting.TexCoord3Format,
                        ElementCount = 2,
                    });
                }
                if (setting.HasTexCoord4)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.UV4,
                        BufferFormat = (uint)setting.TexCoord4Format,
                        ElementCount = 2,
                    });
                }
                if (setting.HasColor1)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.Color1,
                        BufferFormat = (uint)setting.Color1Format,
                        ElementCount = 4,
                    });
                }
                if (setting.HasColor2)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.Color2,
                        BufferFormat = (uint)setting.Color2Format,
                        ElementCount = 4,
                    });
                }

                if (setting.HasBoneIndices)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.BoneID,
                        BufferFormat = (uint)setting.BoneIndexFormat,
                        ElementCount = 4,
                    });
                }

                if (setting.HasWeights)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.BoneWeight,
                        BufferFormat = (uint)setting.BoneWeightFormat,
                        ElementCount = 4,
                    });
                }

                if (setting.HasBitangents)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.Bitangent,
                        BufferFormat = (uint)setting.BitangentnFormat,
                        ElementCount = 4,
                    });
                }

                meshData.Attributes = attributes;
                meshData.SetData(GFLXMeshBufferHelper.CreateVertexDataBuffer(mesh, skinningIndices, attributes));

                //Lastly add the polygon groups
                foreach (var poly in mesh.PolygonGroups)
                {
                    List <ushort> faces = new List <ushort>();
                    for (int f = 0; f < poly.faces.Count; f++)
                    {
                        faces.Add((ushort)poly.faces[f]);
                    }

                    if (poly.MaterialIndex < 0)
                    {
                        poly.MaterialIndex = 0;
                    }

                    meshData.Polygons = new List <MeshPolygon>();
                    meshData.Polygons.Add(new MeshPolygon()
                    {
                        MaterialIndex = (uint)poly.MaterialIndex,
                        Faces         = faces,
                    });
                }
            }

            if (unmappedBones.Count > 0)
            {
                STErrorDialog.Show($"{unmappedBones.Count} bone(s) are not present in the boneset and are unmapped!",
                                   "GFBMDL Importer", string.Join("\n", unmappedBones.ToArray()));
            }

            Console.WriteLine($"");

            //Generate bounding box
            Model.GenerateBoundingBox();
            ReloadModel(Model.Model);

            Model.UpdateVertexData(true);
        }
예제 #21
0
        public Dictionary <string, STGenericTexture> GetTextures()
        {
            Dictionary <string, STGenericTexture> textures = new Dictionary <string, STGenericTexture>();

            if (File.Exists(FilePath))
            {
                string folder = Path.GetDirectoryName(FilePath);
                foreach (var file in Directory.GetFiles(folder))
                {
                    try
                    {
                        if (Utils.GetExtension(file) == ".bflim")
                        {
                            BFLIM bflim = (BFLIM)STFileLoader.OpenFileFormat(file);
                            if (!textures.ContainsKey(bflim.FileName))
                            {
                                textures.Add(bflim.FileName, bflim);
                            }
                        }
                        if (Utils.GetExtension(file) == ".bntx")
                        {
                            BNTX bntx = (BNTX)STFileLoader.OpenFileFormat(file);
                            foreach (var tex in bntx.Textures)
                            {
                                if (!textures.ContainsKey(tex.Key))
                                {
                                    textures.Add(tex.Key, tex.Value);
                                }
                            }

                            string fileName = Path.GetFileName(file);
                            if (!header.TextureManager.BinaryContainers.ContainsKey(fileName))
                            {
                                header.TextureManager.BinaryContainers.Add(fileName, bntx);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        STErrorDialog.Show($"Failed to load texture {file}. ", "Layout Editor", ex.ToString());
                    }
                }
            }

            foreach (var archive in PluginRuntime.SarcArchives)
            {
                foreach (var file in archive.Files)
                {
                    try
                    {
                        if (Utils.GetExtension(file.FileName) == ".bntx")
                        {
                            BNTX bntx = (BNTX)file.OpenFile();
                            file.FileFormat = bntx;
                            foreach (var tex in bntx.Textures)
                            {
                                if (!textures.ContainsKey(tex.Key))
                                {
                                    textures.Add(tex.Key, tex.Value);
                                }
                            }

                            if (!header.TextureManager.BinaryContainers.ContainsKey($"{archive.FileName}.bntx"))
                            {
                                header.TextureManager.BinaryContainers.Add($"{archive.FileName}.bntx", bntx);
                            }
                        }
                        if (Utils.GetExtension(file.FileName) == ".bflim")
                        {
                            BFLIM  bflim = (BFLIM)file.OpenFile();
                            string name  = bflim.FileName;
                            if (archive is SARC)
                            {
                                if (((SARC)archive).sarcData.HashOnly)
                                {
                                    var sarcEntry = file as SARC.SarcEntry;

                                    //Look through all textures and find a hash match
                                    name = sarcEntry.TryGetHash(header.Textures, "timg");
                                    name = Path.GetFileName(name);
                                }
                            }

                            file.FileFormat = bflim;
                            if (!textures.ContainsKey(bflim.FileName))
                            {
                                textures.Add(name, bflim);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        STErrorDialog.Show($"Failed to load texture {file.FileName}. ", "Layout Editor", ex.ToString());
                    }
                }

                if (!header.TextureManager.ArchiveFile.ContainsKey(archive.FileName))
                {
                    header.TextureManager.ArchiveFile.Add(archive.FileName, archive);
                }
            }

            return(textures);
        }