Beispiel #1
0
        private void SaveAllTextures()
        {
            if (TexDict?.Textures?.data_items == null)
            {
                return;
            }
            if (FolderBrowserDialog.ShowDialogNew() != DialogResult.OK)
            {
                return;
            }
            var folder = FolderBrowserDialog.SelectedPath;

            foreach (var tex in TexDict.Textures.data_items)
            {
                byte[] dds   = DDSIO.GetDDSFile(tex);
                string bpath = folder + "\\" + tex.Name;
                string fpath = bpath + ".dds";
                int    c     = 1;
                while (File.Exists(fpath))
                {
                    fpath = bpath + "_Copy" + c.ToString() + ".dds";
                    c++;
                }
                File.WriteAllBytes(fpath, dds);
            }
        }
Beispiel #2
0
        private Texture OpenDDSFile()
        {
            if (OpenDDSFileDialog.ShowDialog() != DialogResult.OK)
            {
                return(null);
            }

            var fn = OpenDDSFileDialog.FileName;

            if (!File.Exists(fn))
            {
                return(null);                  //couldn't find file?
            }
            try
            {
                var dds = File.ReadAllBytes(fn);
                var tex = DDSIO.GetTexture(dds);
                tex.Name     = Path.GetFileNameWithoutExtension(fn);
                tex.NameHash = JenkHash.GenHash(tex.Name?.ToLowerInvariant());
                JenkIndex.Ensure(tex.Name?.ToLowerInvariant());
                return(tex);
            }
            catch
            {
                MessageBox.Show("Unable to load " + fn + ".\nAre you sure it's a valid .dds file?");
            }

            return(null);
        }
Beispiel #3
0
        private void DisplayTexture(Texture tex, int mip)
        {
            try
            {
                int    cmip   = Math.Min(Math.Max(mip, 0), tex.Levels - 1);
                byte[] pixels = DDSIO.GetPixels(tex, cmip);
                int    w      = tex.Width >> cmip;
                int    h      = tex.Height >> cmip;
                Bitmap bmp    = new Bitmap(w, h, PixelFormat.Format32bppArgb);

                if (pixels != null)
                {
                    var        BoundsRect = new System.Drawing.Rectangle(0, 0, w, h);
                    BitmapData bmpData    = bmp.LockBits(BoundsRect, ImageLockMode.WriteOnly, bmp.PixelFormat);
                    IntPtr     ptr        = bmpData.Scan0;
                    int        bytes      = bmpData.Stride * bmp.Height;
                    Marshal.Copy(pixels, 0, ptr, bytes);
                    bmp.UnlockBits(bmpData);
                }

                SelDrawableTexturePictureBox.Image = bmp;
                SelTextureDimensionsLabel.Text     = w.ToString() + " x " + h.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error reading texture mip:\n" + ex.ToString());
                SelDrawableTexturePictureBox.Image = null;
            }
        }
Beispiel #4
0
        public override void ReadXml(XmlNode node, string ddsfolder)
        {
            base.ReadXml(node, ddsfolder);
            Width  = (ushort)Xml.GetChildUIntAttribute(node, "Width", "value");
            Height = (ushort)Xml.GetChildUIntAttribute(node, "Height", "value");
            Levels = (byte)Xml.GetChildUIntAttribute(node, "MipLevels", "value");
            Format = Xml.GetChildEnumInnerText <TextureFormat>(node, "Format");
            var filename = Xml.GetChildInnerText(node, "FileName");

            try
            {
                var filepath = Path.Combine(ddsfolder, filename);
                if (File.Exists(filepath))
                {
                    var dds = File.ReadAllBytes(filepath);
                    var tex = DDSIO.GetTexture(dds);
                    if (tex != null)
                    {
                        Data   = tex.Data;
                        Width  = tex.Width;
                        Height = tex.Height;
                        Depth  = tex.Depth;
                        Levels = tex.Levels;
                        Format = tex.Format;
                        Stride = tex.Stride;
                    }
                }
            }
            catch { }
        }
Beispiel #5
0
        public override void WriteXml(StringBuilder sb, int indent, string ddsfolder)
        {
            base.WriteXml(sb, indent, ddsfolder);
            YtdXml.ValueTag(sb, indent, "Width", Width.ToString());
            YtdXml.ValueTag(sb, indent, "Height", Height.ToString());
            YtdXml.ValueTag(sb, indent, "MipLevels", Levels.ToString());
            YtdXml.StringTag(sb, indent, "Format", Format.ToString());
            YtdXml.StringTag(sb, indent, "Usage", Usage.ToString());
            YtdXml.StringTag(sb, indent, "UsageFlags", UsageFlags.ToString());
            YtdXml.ValueTag(sb, indent, "ExtraFlags", ExtraFlags.ToString());
            YtdXml.StringTag(sb, indent, "FileName", YtdXml.XmlEscape((Name ?? "null") + ".dds"));

            try
            {
                if (!string.IsNullOrEmpty(ddsfolder))
                {
                    if (!Directory.Exists(ddsfolder))
                    {
                        Directory.CreateDirectory(ddsfolder);
                    }
                    var filepath = Path.Combine(ddsfolder, (Name ?? "null") + ".dds");
                    var dds      = DDSIO.GetDDSFile(this);
                    File.WriteAllBytes(filepath, dds);
                }
            }
            catch { }
        }
Beispiel #6
0
 public void Export(string fileName)
 {
     try
     {
         // only DDS supported
         DDSIO.SaveTextureData(texture, fileName);
     }
     catch
     { }
 }
Beispiel #7
0
 public void Import(string fileName)
 {
     try
     {
         // only DDS supported
         DDSIO.LoadTextureData(texture, fileName);
     }
     catch
     { }
 }
Beispiel #8
0
        private void ShowTextureMip(Texture tex, int mip, bool mipchange)
        {
            if (tex == null)
            {
                SelTexturePictureBox.Image     = null;
                SelTextureNameTextBox.Text     = string.Empty;
                SelTextureDimensionsLabel.Text = "-";
                SelTextureMipLabel.Text        = "0";
                SelTextureMipTrackBar.Value    = 0;
                SelTextureMipTrackBar.Maximum  = 0;
                return;
            }


            if (mipchange)
            {
                if (mip >= tex.Levels)
                {
                    mip = tex.Levels - 1;
                }
            }
            else
            {
                SelTextureMipTrackBar.Maximum = tex.Levels - 1;
            }

            SelTextureNameTextBox.Text = tex.Name;

            try
            {
                int    cmip   = Math.Min(Math.Max(mip, 0), tex.Levels - 1);
                byte[] pixels = DDSIO.GetPixels(tex, cmip);
                int    w      = tex.Width >> cmip;
                int    h      = tex.Height >> cmip;
                Bitmap bmp    = new Bitmap(w, h, PixelFormat.Format32bppArgb);

                if (pixels != null)
                {
                    var        BoundsRect = new System.Drawing.Rectangle(0, 0, w, h);
                    BitmapData bmpData    = bmp.LockBits(BoundsRect, ImageLockMode.WriteOnly, bmp.PixelFormat);
                    IntPtr     ptr        = bmpData.Scan0;
                    int        bytes      = bmpData.Stride * bmp.Height;
                    Marshal.Copy(pixels, 0, ptr, bytes);
                    bmp.UnlockBits(bmpData);
                }

                SelTexturePictureBox.Image     = bmp;
                SelTextureDimensionsLabel.Text = w.ToString() + " x " + h.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error reading texture mip:\n" + ex.ToString());
                SelTexturePictureBox.Image = null;
            }
        }
Beispiel #9
0
        private void SaveAllTexturesButton_Click(object sender, EventArgs e)
        {
            if (FolderBrowserDialog.ShowDialogNew() != DialogResult.OK)
            {
                return;
            }
            string folderpath = FolderBrowserDialog.SelectedPath;

            if (!folderpath.EndsWith("\\"))
            {
                folderpath += "\\";
            }

            var texs = new List <Texture>();

            foreach (TreeNode modelnode in SelDrawableTexturesTreeView.Nodes)
            {
                foreach (TreeNode geomnode in modelnode.Nodes)
                {
                    foreach (TreeNode texnode in geomnode.Nodes)
                    {
                        var    texbase = texnode.Tag as TextureBase;
                        var    tex     = texbase as Texture;
                        string errstr  = "";
                        if ((tex == null) && (texbase != null))
                        {
                            tex = TryGetTexture(texbase, out _, ref errstr);
                        }
                        if (tex != null)
                        {
                            if (!texs.Contains(tex))
                            {
                                texs.Add(tex);
                            }
                        }
                    }
                }
            }

            foreach (var tex in texs)
            {
                string fpath = folderpath + tex.Name + ".dds";
                byte[] dds   = DDSIO.GetDDSFile(tex);
                File.WriteAllBytes(fpath, dds);
            }
        }
Beispiel #10
0
        private void SaveTextureAs()
        {
            if (CurrentTexture == null)
            {
                return;
            }
            string fname = CurrentTexture.Name + ".dds";

            SaveDDSFileDialog.FileName = fname;
            if (SaveDDSFileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            string fpath = SaveDDSFileDialog.FileName;

            byte[] dds = DDSIO.GetDDSFile(CurrentTexture);
            File.WriteAllBytes(fpath, dds);
        }
Beispiel #11
0
        private void SaveTexture(Texture tex, RpfEntry entry, string folder)
        {
            //DirectXTex

            byte[] dds = DDSIO.GetDDSFile(tex);

            string bpath = folder + "\\" + entry.Name + "_" + tex.Name;
            string fpath = bpath + ".dds";
            int    c     = 1;

            while (File.Exists(fpath))
            {
                fpath = bpath + "_Copy" + c.ToString() + ".dds";
                c++;
            }

            File.WriteAllBytes(fpath, dds);
        }
Beispiel #12
0
        private void SaveTextureButton_Click(object sender, EventArgs e)
        {
            if (currentTex == null)
            {
                return;
            }
            string fname = currentTex.Name + ".dds";

            SaveFileDialog.FileName = fname;
            if (SaveFileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            string fpath = SaveFileDialog.FileName;

            byte[] dds = DDSIO.GetDDSFile(currentTex);
            File.WriteAllBytes(fpath, dds);
        }
Beispiel #13
0
        private void ShowTextureMip(Texture tex, int mip, bool mipchange)
        {
            CurrentTexture = tex;
            UpdateSaveTextureAs();

            if (tex == null)
            {
                SelTexturePictureBox.Image         = null;
                SelTextureNameTextBox.Text         = string.Empty;
                SelTextureDimensionsLabel.Text     = "-";
                SelTextureMipLabel.Text            = "0";
                SelTextureMipTrackBar.Value        = 0;
                SelTextureMipTrackBar.Maximum      = 0;
                DetailsPropertyGrid.SelectedObject = null;
                RemoveTextureButton.Enabled        = false;
                ReplaceTextureButton.Enabled       = false;
                UpdateStatus(GetTexCountStr());
                return;
            }

            RemoveTextureButton.Enabled  = true;
            ReplaceTextureButton.Enabled = true;


            if (mipchange)
            {
                if (mip >= tex.Levels)
                {
                    mip = tex.Levels - 1;
                }
            }
            else
            {
                SelTextureMipTrackBar.Maximum = tex.Levels - 1;
            }

            SelTextureNameTextBox.Text         = tex.Name;
            DetailsPropertyGrid.SelectedObject = tex;


            try
            {
                int    cmip   = Math.Min(Math.Max(mip, 0), tex.Levels - 1);
                byte[] pixels = DDSIO.GetPixels(tex, cmip);
                int    w      = tex.Width >> cmip;
                int    h      = tex.Height >> cmip;
                Bitmap bmp    = new Bitmap(w, h, PixelFormat.Format32bppArgb);

                if (pixels != null)
                {
                    var        BoundsRect = new System.Drawing.Rectangle(0, 0, w, h);
                    BitmapData bmpData    = bmp.LockBits(BoundsRect, ImageLockMode.WriteOnly, bmp.PixelFormat);
                    IntPtr     ptr        = bmpData.Scan0;
                    int        bytes      = bmpData.Stride * bmp.Height;
                    Marshal.Copy(pixels, 0, ptr, bytes);
                    bmp.UnlockBits(bmpData);
                }

                var dimstr = w.ToString() + " x " + h.ToString();

                SelTexturePictureBox.Image     = bmp;
                SelTextureDimensionsLabel.Text = dimstr;

                var str1 = GetTexCountStr();
                var str2 = tex.Name + ", mip " + cmip.ToString() + ", " + dimstr;
                if (!string.IsNullOrEmpty(str1))
                {
                    UpdateStatus(str1 + ". " + str2);
                }
                else
                {
                    UpdateStatus(str2);
                }
            }
            catch (Exception ex)
            {
                UpdateStatus("Error reading texture mip: " + ex.ToString());
                SelTexturePictureBox.Image = null;
            }

            UpdateZoom();
        }
Beispiel #14
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);
            }
        }
Beispiel #15
0
        public static JObject Deamon_GetDrawableJSON(GtaDrawable drawable, string drawablePath)
        {
            Console.WriteLine("Requested drawable : " + drawable.Name.Value);

            var txds = Deamon_LoadExternalTextures(drawablePath);

            var data = new JObject()
            {
                ["shaderGroup"] = new JObject()
                {
                    ["shaders"]  = new JArray(),
                    ["textures"] = new JArray()
                },
                ["models"] = new JObject()
                {
                    ["high"]    = new JArray(),
                    ["medium"]  = new JArray(),
                    ["low"]     = new JArray(),
                    ["verylow"] = new JArray(),
                    ["x"]       = new JArray(),
                }
            };

            var jShaders  = (JArray)data["shaderGroup"]["shaders"];
            var jTextures = (JArray)data["shaderGroup"]["textures"];

            for (int i = 0; i < drawable.ShaderGroup.Shaders.Count; i++)
            {
                var shader = drawable.ShaderGroup.Shaders[i];

                var jShader = new JObject()
                {
                    ["textures"] = new JObject()
                };

                for (int j = 0; j < shader.ParametersList.Parameters.Count; j++)
                {
                    var param = shader.ParametersList.Parameters[j];

                    if (param.Data is TextureDX11)
                    {
                        var tx     = param.Data as TextureDX11;
                        var txName = tx.Name.Value.ToLowerInvariant();

                        switch (param.Unknown_1h)
                        {
                        case 0: jShader["textures"]["diffuse"] = txName; break;

                        case 2: jShader["textures"]["specular"] = txName; break;

                        case 3: jShader["textures"]["bump"] = txName; break;
                        }
                    }
                    else if (param.Data is Texture)
                    {
                        var txName = (param.Data as Texture).Name.Value.ToLowerInvariant();

                        for (int k = 0; k < txds.Length; k++)
                        {
                            var txd = txds[k];

                            for (int l = 0; l < txd.TextureDictionary.Textures.Entries.Count; l++)
                            {
                                var tx      = txd.TextureDictionary.Textures.Entries[l];
                                var txName2 = tx.Name.Value.ToLowerInvariant();

                                if (txName == txName2)
                                {
                                    switch (param.Unknown_1h)
                                    {
                                    case 0: jShader["textures"]["diffuse"] = txName; break;

                                    case 2: jShader["textures"]["specular"] = txName; break;

                                    case 3: jShader["textures"]["bump"] = txName; break;
                                    }

                                    break;
                                }
                            }
                        }
                    }
                }

                jShaders.Add(jShader);
            }

            for (int i = 0; i < txds.Length; i++)
            {
                var txd = txds[i];

                for (int j = 0; j < txd.TextureDictionary.Textures.Entries.Count; j++)
                {
                    var tx        = txd.TextureDictionary.Textures.Entries[j];
                    var txWrapper = new TextureWrapper_GTA5_pc(tx);
                    var txName    = tx.Name.Value.ToLowerInvariant();
                    var path      = Path.GetTempPath() + "\\gtautil_texture_" + txName + ".dds";

                    for (int m = 0; m < jShaders.Count; m++)
                    {
                        var jShader = (JObject)jShaders[m];

                        if ((string)jShader["textures"]["diffuse"] == txName || (string)jShader["textures"]["specular"] == txName || (string)jShader["textures"]["bump"] == txName)
                        {
                            Console.WriteLine("Reusing external texture " + txName);

                            DDSIO.SaveTextureData(txWrapper, path);

                            Utils.Hash(txName);

                            var jTx        = new JObject();
                            var txNameHash = Jenkins.Hash(txName);

                            jTx["hash"]   = txNameHash;
                            jTx["name"]   = txName;
                            jTx["path"]   = path;
                            jTx["width"]  = tx.Width;
                            jTx["height"] = tx.Height;

                            jTextures.Add(jTx);
                        }
                    }
                }
            }

            for (int i = 0; i < drawable.ShaderGroup.TextureDictionary.Textures.Entries.Count; i++)
            {
                var tx        = drawable.ShaderGroup.TextureDictionary.Textures.Entries[i];
                var txWrapper = new TextureWrapper_GTA5_pc(tx);
                var txName    = tx.Name.Value.ToLowerInvariant();
                var path      = Path.GetTempPath() + "\\gtautil_texture_" + txName + ".dds";

                DDSIO.SaveTextureData(txWrapper, path);

                Utils.Hash(txName);

                var jTx        = new JObject();
                var txNameHash = drawable.ShaderGroup.TextureDictionary.TextureNameHashes.Entries[i].Value;

                jTx["hash"]   = txNameHash;
                jTx["name"]   = txName;
                jTx["path"]   = path;
                jTx["width"]  = tx.Width;
                jTx["height"] = tx.Height;

                jTextures.Add(jTx);
            }

            for (int i = 0; i < drawable.DrawableModelsHigh.Entries.Count; i++)
            {
                var jModel = Deamon_GetModelData(drawable.DrawableModelsHigh?.Entries[i]);
                ((JArray)data["models"]["high"]).Add(jModel);
            }

            for (int i = 0; i < drawable.DrawableModelsMedium?.Entries.Count; i++)
            {
                var jModel = Deamon_GetModelData(drawable.DrawableModelsMedium.Entries[i]);
                ((JArray)data["models"]["medium"]).Add(jModel);
            }

            for (int i = 0; i < drawable.DrawableModelsLow?.Entries.Count; i++)
            {
                var jModel = Deamon_GetModelData(drawable.DrawableModelsLow.Entries[i]);
                ((JArray)data["models"]["low"]).Add(jModel);
            }

            for (int i = 0; i < drawable.DrawableModelsVeryLow?.Entries.Count; i++)
            {
                var jModel = Deamon_GetModelData(drawable.DrawableModelsVeryLow.Entries[i]);
                ((JArray)data["models"]["verylow"]).Add(jModel);
            }

            for (int i = 0; i < drawable.DrawableModelsX?.Entries.Count; i++)
            {
                var jModel = Deamon_GetModelData(drawable.DrawableModelsX.Entries[i]);
                ((JArray)data["models"]["x"]).Add(jModel);
            }

            return(data);
        }
Beispiel #16
0
        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();
            }
        }