private void BattleStage_listbox(bool bGenerateTextures)
        {
            if (listBox1.SelectedIndex == -1)
                listBox1.SelectedIndex = 0;
            Image nullImageRes = _bmp2;
            _bmp = new Bitmap(nullImageRes);
            Graphics g = Graphics.FromImage(_bmp);
            int selected = Convert.ToInt32(listBox1.SelectedItems[0]);
            BattleStage bs = new BattleStage("UV");
            Tuple<List<double>, List<double>,int> uv = bs.GetUVpoints(selected, _lastKnownPath, _lastKnownTim);
            List<Point> uvPoint = new List<Point>();
            Pen pen = new Pen(Color.White, 1.0f);
            int index = 0;
            Tuple<int, int> texResTuple = bs.GetTextureRes();
            int width = texResTuple.Item1;
            int height = texResTuple.Item2;
            checkBox1.Checked = !_polygons[listBox1.SelectedIndex].IsEnabled;
            if (bGenerateTextures)
            {
                Console.WriteLine($"BS: Mixing textures...");
                Console.WriteLine($"BS: Collecting UV data and preparing bounding boxes");
                for (int i = 0; i != listBox1.Items.Count; i++)
                {
                    uv = bs.GetUVpoints(int.Parse(listBox1.Items[i].ToString()), _lastKnownPath, _lastKnownTim);
                    int clute = uv.Item3;
                    string pathText = Path.GetDirectoryName(_lastKnownPath);

                    if(clute!=0)
                        pathText = pathText + @"\" + Path.GetFileNameWithoutExtension(_lastKnownPath) + @"_" + clute + ".png";
                    else
                        pathText = pathText + @"\" + Path.GetFileNameWithoutExtension(_lastKnownPath) + ".png";

                    double u1Min = uv.Item1.Min(); double u1Max = uv.Item1.Max();
                    double v1Min = uv.Item2.Min(); double v1Max = uv.Item2.Max();
                    double x1 = Math.Floor(((u1Min * 100) * width) / 100);
                    double y1 = Math.Floor(((v1Min * 100) * height) / 100) ;
                    double x2 = Math.Floor(((u1Max * 100) * width) / 100);
                    double y2 = Math.Floor(((v1Max * 100) * height) / 100) ;
                    x1 = x1 <= 0 ? 1 : x1; x2 = x2 <= 0 ? 1 : x2;
                    Point topLeft = new Point((int)(Math.Round(x1)-1), height - (int)(Math.Round(y2)));
                    Point topRight = new Point((int)(Math.Round(x2)-1), height - (int)(Math.Round(y2)));
                    Point bottomLeft = new Point((int)(Math.Round(x1)), height - (int)(Math.Round(y1)));
                    Point bottomRight = new Point((int)(Math.Round(x2)), height - (int)(Math.Round(y1)));

                    if (!File.Exists(pathText)) continue;
                    Console.WriteLine($"BS: Mixing {pathText}");
                    Bitmap loadBmp = new Bitmap(pathText);
                    PixelFormat pf = PixelFormat.Format24bppRgb;
                    int wid = (topRight.X - topLeft.X) + 4;
                    int hei = (bottomLeft.Y - topLeft.Y) + 4;
                    wid = topLeft.X + wid > width ? wid - 4 : wid;
                    hei = bottomRight.Y + hei > height ? hei - 4 : hei;
                    Size sz = new Size(wid,hei);
                    Rectangle rectangle = new Rectangle(topLeft, sz);
                    BitmapData targetBitmapData = _bmp.LockBits(rectangle, ImageLockMode.WriteOnly, pf);
                    BitmapData sourBitmapData = loadBmp.LockBits(rectangle, ImageLockMode.ReadOnly, pf);
                    IntPtr workingptr = targetBitmapData.Scan0;
                    IntPtr sourceptr = sourBitmapData.Scan0;
                    byte[] rawLoadBmp = new byte[sourBitmapData.Stride * sourBitmapData.Height];
                    byte[] rawBmp = new byte[targetBitmapData.Stride * targetBitmapData.Height];
                    Marshal.Copy(workingptr, rawBmp, 0, rawBmp.Length);
                    Marshal.Copy(sourceptr, rawLoadBmp, 0, rawLoadBmp.Length);
                    for (int pixel = 0; pixel != rawLoadBmp.Length; pixel++)
                        rawBmp[pixel] = rawLoadBmp[pixel];
                    Marshal.Copy(rawBmp, 0, workingptr, rawBmp.Length);
                    loadBmp.UnlockBits(sourBitmapData);
                    _bmp.UnlockBits(targetBitmapData);
                    Console.WriteLine($"BS: Mixing finished");
                }
                pictureBox1.Image = _bmp;
                _bmp2 = _bmp;
                string pathTexte = Path.GetDirectoryName(_lastKnownPath);
                Console.WriteLine($"BS: Saving final texture");
                pathTexte = pathTexte + @"\" + Path.GetFileNameWithoutExtension(_lastKnownPath) + "_col.png";
                if (File.Exists(pathTexte))
                    File.Delete(pathTexte);
                Console.WriteLine($"BS: Setting transparency on final texture");
                _bmp.MakeTransparent(Color.Black);
                _bmp.Save(pathTexte);
                pathTexte = Path.GetDirectoryName(_lastKnownPath);
                pathTexte = pathTexte + @"\" + Path.GetFileNameWithoutExtension(_lastKnownPath) + ".MTL";
                string[] newfile = File.ReadAllLines(pathTexte);
                newfile[newfile.Length-1] = "map_Kd " + Path.GetFileNameWithoutExtension(_lastKnownPath) + "_col.png";
                File.WriteAllLines(pathTexte, newfile);
                pictureBox1.BackgroundImage = _bmp;
                Console.WriteLine($"BS: Finished!");
                Console.WriteLine($"BS: Delivered to renderer.");
                Render3D();
            }
            if (bGenerateTextures) return;
            {
                Console.WriteLine($"BS: Drawing UV layout");
                while (true)
                {
                    double x1 = (((uv.Item1[index] * 100) * width) / 100);
                    double y1 = (((uv.Item2[index] * 100) * height) / 100);
                    double x2 = (((uv.Item1[index + 1] * 100) * width) / 100);
                    double y2 = (((uv.Item2[index + 1] * 100) * height) / 100);
                    Point xy1 = new Point((int)(Math.Round(x1)), 256 - (int)(Math.Round(y1)));
                    Point xy2 = new Point((int)(Math.Round(x2)), 256 - (int)(Math.Round(y2)));
                    uvPoint.Add(xy1);
                    uvPoint.Add(xy2);
                    g.DrawLine(pen, uvPoint[index], uvPoint[index + 1]);

                    if (index >= uv.Item1.Count - 3 && index >= uv.Item2.Count - 3)
                        break;
                    index += 2;
                }
                g.Dispose();
                pictureBox1.Image = _bmp;
            }
        }
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog
            {
                Title = "Open FF8 .X stage model (a0stgXXX.x)",
                Filter = "Final Fantasy VIII stage (.x)|*.X"
            };
            if (ofd.ShowDialog() != DialogResult.OK) return;
            Console.WriteLine("BS: Opening file...");
            _state = StateBattleStageUv;
            exportToolStripMenuItem.Enabled = true;
            importToolStripMenuItem.Enabled = true;
            SetLines(false);
            BattleStage bs = new BattleStage(ofd.FileName);
            listBox1.Items.Clear();
            UpdateStatus(ofd.FileName);
            bs.Process(true);
            pictureBox1.Image = bs.GetTexture();
            pictureBox1.BackgroundImage = bs.GetTexture();
            _bmp = bs.GetTexture();
            _bmp2 = bs.GetTexture(); 
            _lastKnownPath = ofd.FileName;
            _lastKnownTim = bs.GetLastTim();
            _pathModels = new List<string>();
            foreach (int i in bs.GetArrayOfObjects())
            {
                listBox1.Items.Add(i.ToString());
                var pathOfd = Path.GetDirectoryName(ofd.FileName);
                pathOfd += $@"\{Path.GetFileNameWithoutExtension(ofd.FileName)}_{i.ToString()}_t.obj";
                if (File.Exists(pathOfd))
                    _pathModels.Add(pathOfd);

                string pathOfd2 = Path.GetDirectoryName(ofd.FileName);
                pathOfd2 += $@"\{Path.GetFileNameWithoutExtension(ofd.FileName)}_{i.ToString()}_q.obj";
                if (File.Exists(pathOfd2))
                    _pathModels.Add(pathOfd2);

                if (File.Exists(pathOfd) && File.Exists(pathOfd2))
                    listBox1.Items.Add(i.ToString());
            }
            Render3D();
            BattleStage_listbox(true);
            pictureBox1.BackgroundImage = null;
        }
 public void BSVertEditor_Update(string ofd)
 {
     BattleStage bs = new BattleStage(ofd);
     listBox1.Items.Clear();
     bs.Process(false, true);
     BS_UpdateObjects(bs.GetArrayOfObjects(), ofd);
     Render3D();
 }
        private void dumpRAWDataToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_state != StateBattleStageUv)
                return;

            SaveFileDialog sfd = new SaveFileDialog();
            if (sfd.ShowDialog() != DialogResult.OK) return;
            BattleStage bs = new BattleStage(_lastKnownPath);
            int nextoffset;
            if (listBox1.SelectedIndex == listBox1.Items.Count - 1)
                nextoffset = -1;
            else
                nextoffset = int.Parse(listBox1.Items[listBox1.SelectedIndex + 1].ToString());
            bs.DumpRaw(int.Parse(listBox1.Items[listBox1.SelectedIndex].ToString()), sfd.FileName, nextoffset);
        }