コード例 #1
0
        private void SelectTexture(TextureBase texbase, bool mipchange)
        {
            Texture tex    = texbase as Texture;
            YtdFile ytd    = null;
            string  errstr = string.Empty;

            if ((tex == null) && (texbase != null))
            {
                tex = TryGetTexture(texbase, out ytd, ref errstr);
            }
            if (tex != null)
            {
                currentTex = tex;
                int mip = 0;
                if (mipchange)
                {
                    mip = SelTextureMipTrackBar.Value;
                    if (mip >= tex.Levels)
                    {
                        mip = tex.Levels - 1;
                    }
                }
                else
                {
                    SelTextureMipTrackBar.Maximum = tex.Levels - 1;
                }
                DisplayTexture(tex, mip);


                //try get owner drawable to get the name for the dictionary textbox...
                object owner = null;
                if (Selection.Drawable != null)
                {
                    owner = Selection.Drawable.Owner;
                }
                YdrFile ydr = owner as YdrFile;
                YddFile ydd = owner as YddFile;
                YftFile yft = owner as YftFile;

                SelTextureNameTextBox.Text       = tex.Name;
                SelTextureDictionaryTextBox.Text = (ytd != null) ? ytd.Name : (ydr != null) ? ydr.Name : (ydd != null) ? ydd.Name : (yft != null) ? yft.Name : string.Empty;
                SaveTextureButton.Enabled        = true;
            }
            else
            {
                SelDrawableTexturePictureBox.Image = null;
                SelTextureNameTextBox.Text         = errstr;
                SelTextureDictionaryTextBox.Text   = string.Empty;
                SelTextureMipTrackBar.Value        = 0;
                SelTextureMipTrackBar.Maximum      = 0;
                SelTextureDimensionsLabel.Text     = "-";
                SaveTextureButton.Enabled          = false;
                currentTex = null;
            }
        }
コード例 #2
0
ファイル: ProjectFile.cs プロジェクト: q4a/CodeWalker
 public bool ContainsYtd(YtdFile ytd)
 {
     foreach (var f in YtdFiles)
     {
         if (f == ytd)
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #3
0
ファイル: YtdForm.cs プロジェクト: q4a/CodeWalker
        public void LoadYtd(YtdFile ytd)
        {
            Ytd = ytd;

            FileName = ytd?.Name;
            if (string.IsNullOrEmpty(FileName))
            {
                FileName = ytd?.RpfFileEntry?.Name;
            }

            LoadTexDict(ytd.TextureDict, FileName);
        }
コード例 #4
0
ファイル: ProjectFile.cs プロジェクト: q4a/CodeWalker
        public YtdFile AddYtdFile(string filename)
        {
            YtdFile ytd = new YtdFile();

            ytd.RpfFileEntry      = new RpfResourceFileEntry();
            ytd.RpfFileEntry.Name = Path.GetFileName(filename);
            ytd.FilePath          = GetFullFilePath(filename);
            ytd.Name = ytd.RpfFileEntry.Name;
            if (!AddYtdFile(ytd))
            {
                return(null);
            }
            return(ytd);
        }
コード例 #5
0
ファイル: ProjectFile.cs プロジェクト: q4a/CodeWalker
        public void RemoveYtdFile(YtdFile ytd)
        {
            if (ytd == null)
            {
                return;
            }
            var relpath = GetRelativePath(ytd.FilePath);

            if (string.IsNullOrEmpty(relpath))
            {
                relpath = ytd.Name;
            }
            YtdFiles.Remove(ytd);
            YtdFilenames.Remove(relpath);
            HasChanged = true;
        }
コード例 #6
0
ファイル: ProjectFile.cs プロジェクト: q4a/CodeWalker
        public bool AddYtdFile(YtdFile ytd)
        {
            string relpath = GetRelativePath(ytd.FilePath);

            if (string.IsNullOrEmpty(relpath))
            {
                relpath = ytd.Name;
            }
            if (YtdFilenames.Contains(relpath))
            {
                return(false);
            }
            YtdFilenames.Add(relpath);
            YtdFiles.Add(ytd);
            return(true);
        }
コード例 #7
0
        private Texture TryGetTexture(TextureBase texbase, out YtdFile ytd, ref string errstr)
        {
            //need to load from txd.
            var  arch    = Selection.Archetype;
            uint texhash = texbase.NameHash;
            uint txdHash = (arch != null) ? arch.TextureDict.Hash : 0;
            var  tex     = TryGetTextureFromYtd(texhash, txdHash, out ytd);

            if (tex == null)
            { //search parent ytds...
                uint ptxdhash = WorldForm.GameFileCache.TryGetParentYtdHash(txdHash);
                while ((ptxdhash != 0) && (tex == null))
                {
                    tex = TryGetTextureFromYtd(texhash, ptxdhash, out ytd);
                    if (tex == null)
                    {
                        ptxdhash = WorldForm.GameFileCache.TryGetParentYtdHash(ptxdhash);
                    }
                    else
                    {
                    }
                }
                if (tex == null)
                {
                    ytd = WorldForm.GameFileCache.TryGetTextureDictForTexture(texhash);
                    if (ytd != null)
                    {
                        int tries = 0;
                        while (!ytd.Loaded && (tries < 500)) //wait upto ~5 sec
                        {
                            System.Threading.Thread.Sleep(10);
                            tries++;
                        }
                        if (ytd.Loaded)
                        {
                            tex = ytd.TextureDict.Lookup(texhash);
                        }
                    }
                    if (tex == null)
                    {
                        ytd    = null;
                        errstr = "<Couldn't find texture!>";
                    }
                }
            }
            return(tex);
        }
コード例 #8
0
ファイル: WorldInfoForm.cs プロジェクト: PichotM/CodeWalker
 private Texture TryGetTextureFromYtd(uint texHash, uint txdHash, out YtdFile ytd)
 {
     if (txdHash != 0)
     {
         ytd = WorldForm.GameFileCache.GetYtd(txdHash);
         if (ytd != null)
         {
             int tries = 0;
             while (!ytd.Loaded && (tries < 500)) //wait upto ~5 sec
             {
                 System.Threading.Thread.Sleep(10);
                 tries++;
             }
             if (ytd.Loaded)
             {
                 return(ytd.TextureDict.Lookup(texHash));
             }
         }
     }
     ytd = null;
     return(null);
 }
コード例 #9
0
ファイル: WorldInfoForm.cs プロジェクト: PichotM/CodeWalker
        private void SelectTexture(TextureBase texbase, bool mipchange)
        {
            Texture tex    = texbase as Texture;
            YtdFile ytd    = null;
            string  errstr = string.Empty;

            if ((tex == null) && (texbase != null))
            {
                //need to load from txd.
                var  arch    = Selection.Archetype;
                uint texhash = texbase.NameHash;
                uint txdHash = (arch != null) ? arch.TextureDict.Hash : 0;
                tex = TryGetTextureFromYtd(texhash, txdHash, out ytd);
                if (tex == null)
                { //search parent ytds...
                    uint ptxdhash = WorldForm.GameFileCache.TryGetParentYtdHash(txdHash);
                    while ((ptxdhash != 0) && (tex == null))
                    {
                        tex = TryGetTextureFromYtd(texhash, ptxdhash, out ytd);
                        if (tex == null)
                        {
                            ptxdhash = WorldForm.GameFileCache.TryGetParentYtdHash(ptxdhash);
                        }
                        else
                        {
                        }
                    }
                    if (tex == null)
                    {
                        ytd = WorldForm.GameFileCache.TryGetTextureDictForTexture(texhash);
                        if (ytd != null)
                        {
                            int tries = 0;
                            while (!ytd.Loaded && (tries < 500)) //wait upto ~5 sec
                            {
                                System.Threading.Thread.Sleep(10);
                                tries++;
                            }
                            if (ytd.Loaded)
                            {
                                tex = ytd.TextureDict.Lookup(texhash);
                            }
                        }
                        if (tex == null)
                        {
                            ytd    = null;
                            errstr = "<Couldn't find texture!>";
                        }
                    }
                }
            }
            if (tex != null)
            {
                int mip = 0;
                if (mipchange)
                {
                    mip = SelTextureMipTrackBar.Value;
                    if (mip >= tex.Levels)
                    {
                        mip = tex.Levels - 1;
                    }
                }
                else
                {
                    SelTextureMipTrackBar.Maximum = tex.Levels - 1;
                }
                DisplayTexture(tex, mip);


                //try get owner drawable to get the name for the dictionary textbox...
                object owner = null;
                if (Selection.Drawable != null)
                {
                    owner = Selection.Drawable.Owner;
                }
                YdrFile ydr = owner as YdrFile;
                YddFile ydd = owner as YddFile;
                YftFile yft = owner as YftFile;

                SelTextureNameTextBox.Text       = tex.Name;
                SelTextureDictionaryTextBox.Text = (ytd != null) ? ytd.Name : (ydr != null) ? ydr.Name : (ydd != null) ? ydd.Name : (yft != null) ? yft.Name : string.Empty;
            }
            else
            {
                SelDrawableTexturePictureBox.Image = null;
                SelTextureNameTextBox.Text         = errstr;
                SelTextureDictionaryTextBox.Text   = string.Empty;
                SelTextureMipTrackBar.Value        = 0;
                SelTextureMipTrackBar.Maximum      = 0;
                SelTextureDimensionsLabel.Text     = "-";
            }
        }
コード例 #10
0
ファイル: BrowseForm.cs プロジェクト: pnwparksfan/CodeWalker
        private void SelectFile(RpfEntry entry, int offset, int length)
        {
            SelectedEntry  = entry;
            SelectedOffset = offset;
            SelectedLength = length;

            RpfFileEntry rfe = entry as RpfFileEntry;

            if (rfe == null)
            {
                RpfDirectoryEntry rde = entry as RpfDirectoryEntry;
                if (rde != null)
                {
                    FileInfoLabel.Text = rde.Path + " (Directory)";
                    DataTextBox.Text   = "[Please select a data file]";
                }
                else
                {
                    FileInfoLabel.Text = "[Nothing selected]";
                    DataTextBox.Text   = "[Please select a data file]";
                }
                ShowTextures(null);
                return;
            }


            Cursor = Cursors.WaitCursor;

            string typestr = "Resource";

            if (rfe is RpfBinaryFileEntry)
            {
                typestr = "Binary";
            }

            byte[] data = rfe.File.ExtractFile(rfe);

            int datalen = (data != null) ? data.Length : 0;

            FileInfoLabel.Text = rfe.Path + " (" + typestr + " file)  -  " + TextUtil.GetBytesReadable(datalen);


            if (ShowLargeFileContentsCheckBox.Checked || (datalen < 524287)) //512K
            {
                DisplayFileContentsText(rfe, data, length, offset);
            }
            else
            {
                DataTextBox.Text = "[Filesize >512KB. Select the Show large files option to view its contents]";
            }



            bool istexdict = false;


            if (rfe.NameLower.EndsWith(".ymap"))
            {
                YmapFile ymap = new YmapFile(rfe);
                ymap.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ymap;
            }
            else if (rfe.NameLower.EndsWith(".ytyp"))
            {
                YtypFile ytyp = new YtypFile();
                ytyp.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ytyp;
            }
            else if (rfe.NameLower.EndsWith(".ymf"))
            {
                YmfFile ymf = new YmfFile();
                ymf.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ymf;
            }
            else if (rfe.NameLower.EndsWith(".ymt"))
            {
                YmtFile ymt = new YmtFile();
                ymt.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ymt;
            }
            else if (rfe.NameLower.EndsWith(".ybn"))
            {
                YbnFile ybn = new YbnFile();
                ybn.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ybn;
            }
            else if (rfe.NameLower.EndsWith(".fxc"))
            {
                FxcFile fxc = new FxcFile();
                fxc.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = fxc;
            }
            else if (rfe.NameLower.EndsWith(".yft"))
            {
                YftFile yft = new YftFile();
                yft.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = yft;

                if ((yft.Fragment != null) && (yft.Fragment.Drawable != null) && (yft.Fragment.Drawable.ShaderGroup != null) && (yft.Fragment.Drawable.ShaderGroup.TextureDictionary != null))
                {
                    ShowTextures(yft.Fragment.Drawable.ShaderGroup.TextureDictionary);
                    istexdict = true;
                }
            }
            else if (rfe.NameLower.EndsWith(".ydr"))
            {
                YdrFile ydr = new YdrFile();
                ydr.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ydr;

                if ((ydr.Drawable != null) && (ydr.Drawable.ShaderGroup != null) && (ydr.Drawable.ShaderGroup.TextureDictionary != null))
                {
                    ShowTextures(ydr.Drawable.ShaderGroup.TextureDictionary);
                    istexdict = true;
                }
            }
            else if (rfe.NameLower.EndsWith(".ydd"))
            {
                YddFile ydd = new YddFile();
                ydd.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ydd;
                //todo: show embedded texdicts in ydd's? is this possible?
            }
            else if (rfe.NameLower.EndsWith(".ytd"))
            {
                YtdFile ytd = new YtdFile();
                ytd.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ytd;
                ShowTextures(ytd.TextureDict);
                istexdict = true;
            }
            else if (rfe.NameLower.EndsWith(".ycd"))
            {
                YcdFile ycd = new YcdFile();
                ycd.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ycd;
            }
            else if (rfe.NameLower.EndsWith(".ynd"))
            {
                YndFile ynd = new YndFile();
                ynd.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ynd;
            }
            else if (rfe.NameLower.EndsWith(".ynv"))
            {
                YnvFile ynv = new YnvFile();
                ynv.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ynv;
            }
            else if (rfe.NameLower.EndsWith("_cache_y.dat"))
            {
                CacheDatFile cdf = new CacheDatFile();
                cdf.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = cdf;
            }
            else if (rfe.NameLower.EndsWith(".rel"))
            {
                RelFile rel = new RelFile(rfe);
                rel.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = rel;
            }
            else if (rfe.NameLower.EndsWith(".gxt2"))
            {
                Gxt2File gxt2 = new Gxt2File();
                gxt2.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = gxt2;
            }
            else if (rfe.NameLower.EndsWith(".pso"))
            {
                JPsoFile pso = new JPsoFile();
                pso.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = pso;
            }
            else
            {
                DetailsPropertyGrid.SelectedObject = null;
            }


            if (!istexdict)
            {
                ShowTextures(null);
            }


            Cursor = Cursors.Default;
        }
コード例 #11
0
        static void ExtractFilesInRPF(RpfFile rpf, string directoryOffset)
        {
            try
            {
                using (BinaryReader br = new BinaryReader(File.OpenRead(rpf.GetPhysicalFilePath())))
                {
                    foreach (RpfEntry entry in rpf.AllEntries)
                    {
                        if (!entry.NameLower.EndsWith(".rpf")) //don't try to extract rpf's, they will be done separately..
                        {
                            if (entry is RpfBinaryFileEntry)
                            {
                                RpfBinaryFileEntry binentry = entry as RpfBinaryFileEntry;
                                byte[]             data     = rpf.ExtractFileBinary(binentry, br);
                                if (data == null)
                                {
                                    if (binentry.FileSize == 0)
                                    {
                                        Console.WriteLine("Invalid binary file size!");
                                    }
                                    else
                                    {
                                        Console.WriteLine("data is null!");
                                    }
                                }
                                else if (data.Length == 0)
                                {
                                    Console.WriteLine("{0} : Decompressed output was empty.", entry.Path);
                                }
                                else
                                {
                                    Console.WriteLine("binary meme -> " + entry.NameLower);
                                    File.WriteAllBytes(directoryOffset + entry.NameLower, data);
                                }
                            }
                            else if (entry is RpfResourceFileEntry)
                            {
                                RpfResourceFileEntry resentry = entry as RpfResourceFileEntry;
                                byte[] data = rpf.ExtractFileResource(resentry, br);
                                data = ResourceBuilder.Compress(data); //not completely ideal to recompress it...
                                data = ResourceBuilder.AddResourceHeader(resentry, data);
                                if (data == null)
                                {
                                    if (resentry.FileSize == 0)
                                    {
                                        Console.WriteLine("{0} : Resource FileSize is 0.", entry.Path);
                                    }
                                    else
                                    {
                                        Console.WriteLine("{0} : {1}", entry.Path);
                                    }
                                }
                                else if (data.Length == 0)
                                {
                                    Console.WriteLine("{0} : Decompressed output was empty.", entry.Path);
                                }
                                else
                                {
                                    Console.WriteLine("Potential meme -> " + entry.NameLower);
                                    foreach (KeyValuePair <string, string[]> extentionMap in extensions)
                                    {
                                        foreach (string extention in extentionMap.Value)
                                        {
                                            if (entry.NameLower.EndsWith(extention))
                                            {
                                                Console.WriteLine("Resource meme -> " + entry.NameLower);

                                                if (extention.Equals(".ytd"))
                                                {
                                                    RpfFileEntry rpfent = entry as RpfFileEntry;

                                                    byte[] ytddata = rpfent.File.ExtractFile(rpfent);

                                                    bool needsResized = ytddata.Length > 5242880; // 5MB

                                                    YtdFile ytd = new YtdFile();
                                                    ytd.Load(ytddata, rpfent);

                                                    Dictionary <uint, Texture> Dicts = new Dictionary <uint, Texture>();

                                                    bool somethingResized = false;
                                                    foreach (KeyValuePair <uint, Texture> texture in ytd.TextureDict.Dict)
                                                    {
                                                        if (texture.Value.Width > 1440 || needsResized && texture.Value.Width > 550) // Only resize if it is greater than 1440p or 550p if vehicle is oversized
                                                        {
                                                            byte[] dds = DDSIO.GetDDSFile(texture.Value);

                                                            string fileName = $"{texture.Value.Name}.dds";
                                                            fileName = String.Concat(fileName.Where(c => !Char.IsWhiteSpace(c)));

                                                            File.WriteAllBytes("./NConvert/" + fileName, dds);

                                                            Process p = new Process();
                                                            p.StartInfo.FileName               = @"./NConvert/nconvert.exe";
                                                            p.StartInfo.Arguments              = @"-out dds -resize 50% 50% -overwrite ./NConvert/" + fileName;
                                                            p.StartInfo.UseShellExecute        = false;
                                                            p.StartInfo.RedirectStandardOutput = true;
                                                            p.Start();

                                                            //Wait for the process to end.
                                                            p.WaitForExit();

                                                            // Move file back
                                                            File.Move("./NConvert/" + fileName, directoryOffset + fileName);

                                                            byte[]  resizedData = File.ReadAllBytes(directoryOffset + fileName);
                                                            Texture resizedTex  = DDSIO.GetTexture(resizedData);
                                                            resizedTex.Name = texture.Value.Name;
                                                            Console.WriteLine(resizedData.Length.ToString());
                                                            Dicts.Add(texture.Key, resizedTex);

                                                            // Yeet the file, we are done with it
                                                            File.Delete(directoryOffset + fileName);
                                                            somethingResized = true;
                                                        }
                                                        else
                                                        {
                                                            Dicts.Add(texture.Key, texture.Value);
                                                        }
                                                    }
                                                    // No point rebuilding the ytd when nothing was resized
                                                    if (!somethingResized)
                                                    {
                                                        break;
                                                    }

                                                    TextureDictionary dic = new TextureDictionary();
                                                    dic.Textures                     = new ResourcePointerList64 <Texture>();
                                                    dic.TextureNameHashes            = new ResourceSimpleList64_uint();
                                                    dic.Textures.data_items          = Dicts.Values.ToArray();
                                                    dic.TextureNameHashes.data_items = Dicts.Keys.ToArray();

                                                    dic.BuildDict();
                                                    ytd.TextureDict = dic;

                                                    byte[] resizedYtdData = ytd.Save();
                                                    File.WriteAllBytes(directoryOffset + entry.NameLower, resizedYtdData);

                                                    Console.WriteLine("Done some ytd resize memes -> " + entry.NameLower);
                                                    break;
                                                }

                                                File.WriteAllBytes(directoryOffset + entry.NameLower, data);
                                                break;
                                            }
                                        }
                                    }

                                    if (entry.NameLower.EndsWith(".ytd"))
                                    {
                                        latestModelName = entry.NameLower.Remove(entry.NameLower.Length - 4);
                                    }
                                }
                            }
                        }
                        else
                        {
                            // Write file first
                            RpfBinaryFileEntry binentry = entry as RpfBinaryFileEntry;
                            byte[]             data     = rpf.ExtractFileBinary(binentry, br);
                            File.WriteAllBytes(directoryOffset + entry.NameLower, data);

                            RpfFile subRPF = new RpfFile(directoryOffset + entry.NameLower, directoryOffset + entry.NameLower);

                            if (subRPF.ScanStructure(null, null))
                            {
                                //recursive memes
                                ExtractFilesInRPF(subRPF, directoryOffset);
                            }
                            //yeet
                            File.Delete(directoryOffset + entry.NameLower);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception memes!");
                Console.WriteLine(e.Message);
            }
        }
コード例 #12
0
        private void ExtractButton_Click(object sender, EventArgs e)
        {
            if (InProgress)
            {
                return;
            }

            if (!KeysLoaded)
            {
                MessageBox.Show("Please scan a GTA 5 exe dump for keys first, or include key files in this app's folder!");
                return;
            }
            if (!Directory.Exists(FolderTextBox.Text))
            {
                MessageBox.Show("Folder doesn't exist: " + FolderTextBox.Text);
                return;
            }
            if (!Directory.Exists(OutputFolderTextBox.Text))
            {
                MessageBox.Show("Folder doesn't exist: " + OutputFolderTextBox.Text);
                return;
            }
            //if (Directory.GetFiles(OutputFolderTextBox.Text, "*.ysc", SearchOption.AllDirectories).Length > 0)
            //{
            //    if (MessageBox.Show("Output folder already contains .ysc files. Are you sure you want to continue?", "Output folder already contains .ysc files", MessageBoxButtons.OKCancel) != DialogResult.OK)
            //    {
            //        return;
            //    }
            //}

            InProgress     = true;
            AbortOperation = false;

            string searchpath = FolderTextBox.Text;
            string outputpath = OutputFolderTextBox.Text;
            string replpath   = searchpath + "\\";
            bool   bytd       = YtdChecBox.Checked;
            bool   bydr       = YdrCheckBox.Checked;
            bool   bydd       = YddCheckBox.Checked;
            bool   byft       = YftCheckBox.Checked;

            Task.Run(() =>
            {
                UpdateExtractStatus("Keys loaded.");



                RpfManager rpfman = new RpfManager();
                rpfman.Init(searchpath, UpdateExtractStatus, UpdateExtractStatus);


                UpdateExtractStatus("Beginning texture extraction...");
                StringBuilder errsb = new StringBuilder();
                foreach (RpfFile rpf in rpfman.AllRpfs)
                {
                    foreach (RpfEntry entry in rpf.AllEntries)
                    {
                        if (AbortOperation)
                        {
                            UpdateExtractStatus("Operation aborted");
                            InProgress = false;
                            return;
                        }
                        try
                        {
                            if (bytd && entry.NameLower.EndsWith(".ytd"))
                            {
                                UpdateExtractStatus(entry.Path);
                                YtdFile ytd = rpfman.GetFile <YtdFile>(entry);
                                if (ytd == null)
                                {
                                    throw new Exception("Couldn't load file.");
                                }
                                if (ytd.TextureDict == null)
                                {
                                    throw new Exception("Couldn't load texture dictionary.");
                                }
                                if (ytd.TextureDict.Textures == null)
                                {
                                    throw new Exception("Couldn't load texture dictionary texture array.");
                                }
                                if (ytd.TextureDict.Textures.data_items == null)
                                {
                                    throw new Exception("Texture dictionary had no entries...");
                                }
                                foreach (var tex in ytd.TextureDict.Textures.data_items)
                                {
                                    SaveTexture(tex, entry, outputpath);
                                }
                            }
                            else if (bydr && entry.NameLower.EndsWith(".ydr"))
                            {
                                UpdateExtractStatus(entry.Path);
                                YdrFile ydr = rpfman.GetFile <YdrFile>(entry);
                                if (ydr == null)
                                {
                                    throw new Exception("Couldn't load file.");
                                }
                                if (ydr.Drawable == null)
                                {
                                    throw new Exception("Couldn't load drawable.");
                                }
                                if (ydr.Drawable.ShaderGroup != null)
                                {
                                    var ydrtd = ydr.Drawable.ShaderGroup.TextureDictionary;
                                    if ((ydrtd != null) && (ydrtd.Textures != null) && (ydrtd.Textures.data_items != null))
                                    {
                                        foreach (var tex in ydrtd.Textures.data_items)
                                        {
                                            SaveTexture(tex, entry, outputpath);
                                        }
                                    }
                                }
                            }
                            else if (bydd && entry.NameLower.EndsWith(".ydd"))
                            {
                                UpdateExtractStatus(entry.Path);
                                YddFile ydd = rpfman.GetFile <YddFile>(entry);
                                if (ydd == null)
                                {
                                    throw new Exception("Couldn't load file.");
                                }
                                //if (ydd.DrawableDict == null) throw new Exception("Couldn't load drawable dictionary.");
                                //if (ydd.DrawableDict.Drawables == null) throw new Exception("Drawable dictionary had no items...");
                                //if (ydd.DrawableDict.Drawables.data_items == null) throw new Exception("Drawable dictionary had no items...");
                                if ((ydd.Dict == null) || (ydd.Dict.Count == 0))
                                {
                                    throw new Exception("Drawable dictionary had no items...");
                                }
                                foreach (var drawable in ydd.Dict.Values)
                                {
                                    if (drawable.ShaderGroup != null)
                                    {
                                        var ydrtd = drawable.ShaderGroup.TextureDictionary;
                                        if ((ydrtd != null) && (ydrtd.Textures != null) && (ydrtd.Textures.data_items != null))
                                        {
                                            foreach (var tex in ydrtd.Textures.data_items)
                                            {
                                                SaveTexture(tex, entry, outputpath);
                                            }
                                        }
                                    }
                                }
                            }
                            else if (byft && entry.NameLower.EndsWith(".yft"))
                            {
                                UpdateExtractStatus(entry.Path);
                                YftFile yft = rpfman.GetFile <YftFile>(entry);
                                if (yft == null)
                                {
                                    throw new Exception("Couldn't load file.");
                                }
                                if (yft.Fragment == null)
                                {
                                    throw new Exception("Couldn't load fragment.");
                                }
                                if (yft.Fragment.Drawable != null)
                                {
                                    if (yft.Fragment.Drawable.ShaderGroup != null)
                                    {
                                        var ydrtd = yft.Fragment.Drawable.ShaderGroup.TextureDictionary;
                                        if ((ydrtd != null) && (ydrtd.Textures != null) && (ydrtd.Textures.data_items != null))
                                        {
                                            foreach (var tex in ydrtd.Textures.data_items)
                                            {
                                                SaveTexture(tex, entry, outputpath);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            string err = entry.Name + ": " + ex.Message;
                            UpdateExtractStatus(err);
                            errsb.AppendLine(err);
                        }
                    }
                }

                File.WriteAllText(outputpath + "\\_errors.txt", errsb.ToString());

                UpdateExtractStatus("Complete.");
                InProgress = false;
            });
        }
コード例 #13
0
ファイル: Exporter.cs プロジェクト: fullike/CodeWalker
        public Exporter(string name, ResourcePointerList64 <DrawableModel> models, GameFileCache Cache)
        {
            using (StreamWriter FBXwriter = new StreamWriter("FBX/" + name + ".fbx"))
            {
                var timestamp = DateTime.Now;
                int BaseId    = 10000;

                StringBuilder fbx = new StringBuilder();
                StringBuilder ob  = new StringBuilder(); //Objects builder
                StringBuilder cb  = new StringBuilder(); //Connections builder
                StringBuilder mb  = new StringBuilder(); //Materials builder to get texture count in advance
                StringBuilder cb2 = new StringBuilder(); //and keep connections ordered
                cb.Append("\n}\n");                      //Objects end
                cb.Append("\nConnections:  {");
                List <DrawableGeometry> Geoms    = new List <DrawableGeometry>();
                List <ShaderFX>         Shaders  = new List <ShaderFX>();
                List <Texture>          Textures = new List <Texture>();
                //Models
                for (int mi = 0; mi < models.data_items.Length; mi++)
                {
                    var model = models.data_items[mi];
                    //SubMesh & Materials
                    foreach (var geom in model.Geometries.data_items)
                    {
                        if ((geom.Shader != null) && (geom.Shader.ParametersList != null) && (geom.Shader.ParametersList.Hashes != null))
                        {
                            Geoms.Add(geom);
                            Shaders.Add(geom.Shader);
                            var gname = "Geom" + Geoms.Count;
                            //创建节点
                            ob.AppendFormat("\n\tModel: 1{0}, \"Model::{1}\", \"Mesh\" {{", BaseId + Geoms.Count, gname);
                            ob.Append("\n\t\tVersion: 232");
                            ob.Append("\n\t\tProperties70:  {");
                            ob.Append("\n\t\t\tP: \"InheritType\", \"enum\", \"\", \"\",1");
                            ob.Append("\n\t\t\tP: \"ScalingMax\", \"Vector3D\", \"Vector\", \"\",0,0,0");
                            ob.Append("\n\t\t\tP: \"DefaultAttributeIndex\", \"int\", \"Integer\", \"\",0");
                            ob.AppendFormat("\n\t\t\tP: \"Lcl Translation\", \"Lcl Translation\", \"\", \"A\",{0},{1},{2}", 0, 0, 0);
                            ob.AppendFormat("\n\t\t\tP: \"Lcl Rotation\", \"Lcl Rotation\", \"\", \"A\",{0},{1},{2}", 0, 0, 0);//handedness is switched in quat
                            ob.AppendFormat("\n\t\t\tP: \"Lcl Scaling\", \"Lcl Scaling\", \"\", \"A\",{0},{1},{2}", 1, 1, 1);
                            ob.Append("\n\t\t}");
                            ob.Append("\n\t\tShading: T");
                            ob.Append("\n\t\tCulling: \"CullingOff\"\n\t}");

                            //把节点挂在根节点上
                            cb.AppendFormat("\n\n\t;Model::{0}, Model::RootNode", gname);
                            cb.AppendFormat("\n\tC: \"OO\",1{0},0", BaseId + Geoms.Count);

                            //把几何体挂在节点上
                            cb2.AppendFormat("\n\n\t;Geometry::, Model::{0}", gname);
                            cb2.AppendFormat("\n\tC: \"OO\",3{0},1{1}", BaseId + Geoms.Count, BaseId + Geoms.Count);
                            //把材质挂在节点上
                            cb2.AppendFormat("\n\n\t;Material::, Model::{0}", gname);
                            cb2.AppendFormat("\n\tC: \"OO\",6{0},1{1}", BaseId + Shaders.Count, BaseId + Geoms.Count);

                            var pl = geom.Shader.ParametersList;
                            var h  = pl.Hashes;
                            var p  = pl.Parameters;
                            for (int ip = 0; ip < h.Length; ip++)
                            {
                                var hash = pl.Hashes[ip];
                                var parm = pl.Parameters[ip];
                                var tex  = parm.Data as TextureBase;
                                if (tex != null)
                                {
                                    var t = tex as Texture;
                                    if (t == null)
                                    {
                                        YtdFile file = Cache.TryGetTextureDictForTexture(tex.NameHash);
                                        if (file != null)
                                        {
                                            t = file.TextureDict.Lookup(tex.NameHash);
                                        }
                                    }
                                    var tstr = tex.Name.Trim();
                                    if (t != null)
                                    {
                                        Textures.Add(t);
                                        cb2.AppendFormat("\n\n\t;Texture::, Material::{0}", geom.Shader.Name);
                                        cb2.AppendFormat("\n\tC: \"OP\",7{0},6{1}, ", BaseId + Textures.Count, BaseId + Shaders.Count);
                                        switch (hash.ToString().Trim())
                                        {
                                        case "DiffuseSampler":
                                            cb2.Append("\"DiffuseColor\"");
                                            break;

                                        case "BumpSampler":
                                            cb2.Append("\"NormalMap\"");
                                            break;

                                        case "SpecSampler":
                                            cb2.Append("\"SpecularColor\"");
                                            break;

                                        case "DetailSampler":
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }



                fbx.Append("; FBX 7.1.0 project file");
                fbx.Append("\nFBXHeaderExtension:  {\n\tFBXHeaderVersion: 1003\n\tFBXVersion: 7100\n\tCreationTimeStamp:  {\n\t\tVersion: 1000");
                fbx.Append("\n\t\tYear: " + timestamp.Year);
                fbx.Append("\n\t\tMonth: " + timestamp.Month);
                fbx.Append("\n\t\tDay: " + timestamp.Day);
                fbx.Append("\n\t\tHour: " + timestamp.Hour);
                fbx.Append("\n\t\tMinute: " + timestamp.Minute);
                fbx.Append("\n\t\tSecond: " + timestamp.Second);
                fbx.Append("\n\t\tMillisecond: " + timestamp.Millisecond);
                fbx.Append("\n\t}\n\tCreator: \"Unity Studio by Chipicao\"\n}\n");

                fbx.Append("\nGlobalSettings:  {");
                fbx.Append("\n\tVersion: 1000");
                fbx.Append("\n\tProperties70:  {");
                fbx.Append("\n\t\tP: \"UpAxis\", \"int\", \"Integer\", \"\",1");
                fbx.Append("\n\t\tP: \"UpAxisSign\", \"int\", \"Integer\", \"\",1");
                fbx.Append("\n\t\tP: \"FrontAxis\", \"int\", \"Integer\", \"\",2");
                fbx.Append("\n\t\tP: \"FrontAxisSign\", \"int\", \"Integer\", \"\",1");
                fbx.Append("\n\t\tP: \"CoordAxis\", \"int\", \"Integer\", \"\",0");
                fbx.Append("\n\t\tP: \"CoordAxisSign\", \"int\", \"Integer\", \"\",1");
                fbx.Append("\n\t\tP: \"OriginalUpAxis\", \"int\", \"Integer\", \"\",1");
                fbx.Append("\n\t\tP: \"OriginalUpAxisSign\", \"int\", \"Integer\", \"\",1");
                fbx.AppendFormat("\n\t\tP: \"UnitScaleFactor\", \"double\", \"Number\", \"\",1");
                fbx.Append("\n\t\tP: \"OriginalUnitScaleFactor\", \"double\", \"Number\", \"\",1.0");
                fbx.Append("\n\t}\n}\n");

                fbx.Append("\nDocuments:  {");
                fbx.Append("\n\tCount: 1");
                fbx.Append("\n\tDocument: 1234567890, \"\", \"Scene\" {");
                fbx.Append("\n\t\tProperties70:  {");
                fbx.Append("\n\t\t\tP: \"SourceObject\", \"object\", \"\", \"\"");
                fbx.Append("\n\t\t\tP: \"ActiveAnimStackName\", \"KString\", \"\", \"\", \"\"");
                fbx.Append("\n\t\t}");
                fbx.Append("\n\t\tRootNode: 0");
                fbx.Append("\n\t}\n}\n");
                fbx.Append("\nReferences:  {\n}\n");

                fbx.Append("\nDefinitions:  {");
                fbx.Append("\n\tVersion: 100");
                //      fbx.AppendFormat("\n\tCount: {0}", 1 + 2 * GameObjects.Count + Materials.Count + 2 * Textures.Count + ((bool)Properties.Settings.Default["exportDeformers"] ? Skins.Count + DeformerCount + Skins.Count + 1 : 0));

                fbx.Append("\n\tObjectType: \"GlobalSettings\" {");
                fbx.Append("\n\t\tCount: 1");
                fbx.Append("\n\t}");

                fbx.Append("\n\tObjectType: \"Model\" {");
                fbx.AppendFormat("\n\t\tCount: {0}", 1);
                fbx.Append("\n\t}");

                fbx.Append("\n\tObjectType: \"Geometry\" {");
                fbx.AppendFormat("\n\t\tCount: {0}", Geoms.Count);
                fbx.Append("\n\t}");

                fbx.Append("\n\tObjectType: \"Material\" {");
                fbx.AppendFormat("\n\t\tCount: {0}", Shaders.Count);
                fbx.Append("\n\t}");

                fbx.Append("\n\tObjectType: \"Texture\" {");
                fbx.AppendFormat("\n\t\tCount: {0}", Textures.Count);
                fbx.Append("\n\t}");


                fbx.Append("\n}\n");
                fbx.Append("\nObjects:  {");

                FBXwriter.Write(fbx);
                fbx.Clear();



                for (int i = 0; i < Shaders.Count; i++)
                {
                    ShaderFX Shader = Shaders[i];
                    mb.AppendFormat("\n\tMaterial: 6{0}, \"Material::{1}\", \"\" {{", BaseId + i + 1, Shader.Name);
                    mb.Append("\n\t\tVersion: 102");
                    mb.Append("\n\t\tShadingModel: \"phong\"");
                    mb.Append("\n\t\tMultiLayer: 0");
                    mb.Append("\n\t\tProperties70:  {");
                    mb.Append("\n\t\t\tP: \"ShadingModel\", \"KString\", \"\", \"\", \"phong\"");

                    //mb.Append("\n\t\t\tP: \"SpecularFactor\", \"Number\", \"\", \"A\",0");
                    mb.Append("\n\t\t}");
                    mb.Append("\n\t}");
                }
                for (int i = 0; i < Geoms.Count; i++)
                {
                    MeshFBX(Geoms[i], BaseId + i + 1, ob);

                    //write data 8MB at a time
                    if (ob.Length > (8 * 0x100000))
                    {
                        FBXwriter.Write(ob); ob.Clear();
                    }
                }
                for (int i = 0; i < Textures.Count; i++)
                {
                    Texture t = Textures[i];
                    //TODO check texture type and set path accordingly; eg. CubeMap, Texture3D
                    string texFilename = Path.GetFullPath("FBX/" + t.Name + ".png");

                    byte[]           bytes   = DDSIO.GetPixels(t, 0);
                    FileStream       stream  = new FileStream(texFilename, FileMode.Create);
                    PngBitmapEncoder encoder = new PngBitmapEncoder();
                    encoder.Interlace = PngInterlaceOption.On;
                    encoder.Frames.Add(BitmapFrame.Create(BitmapSource.Create(t.Width, t.Height, 96, 96, PixelFormats.Bgra32, null, bytes, t.Width * 4)));
                    encoder.Save(stream);
                    stream.Close();


                    //  File.WriteAllBytes(texFilename, DDSIO.GetDDSFile(t));



                    ob.AppendFormat("\n\tTexture: 7{0}, \"Texture::{1}\", \"\" {{", BaseId + i + 1, t.Name);
                    ob.Append("\n\t\tType: \"TextureVideoClip\"");
                    ob.Append("\n\t\tVersion: 202");
                    ob.AppendFormat("\n\t\tTextureName: \"Texture::{0}\"", t.Name);
                    ob.Append("\n\t\tProperties70:  {");
                    ob.Append("\n\t\t\tP: \"UVSet\", \"KString\", \"\", \"\", \"UVChannel_0\"");
                    ob.Append("\n\t\t\tP: \"UseMaterial\", \"bool\", \"\", \"\",1");
                    ob.Append("\n\t\t}");
                    ob.AppendFormat("\n\t\tMedia: \"Video::{0}\"", t.Name);
                    ob.AppendFormat("\n\t\tFileName: \"{0}\"", texFilename);
                    ob.AppendFormat("\n\t\tRelativeFilename: \"{0}\"", texFilename);
                    ob.Append("\n\t}");
                }

                ob.Append(mb); mb.Clear();
                cb.Append(cb2); cb2.Clear();

                FBXwriter.Write(ob);
                ob.Clear();

                cb.Append("\n}");//Connections end
                FBXwriter.Write(cb);
                cb.Clear();
            }
        }