public GetUVpoints ( int offset, string stagePath, int lastKnownTim ) : Tuple
|
||
offset | int | |
stagePath | string | |
lastKnownTim | int | |
return | Tuple
|
public Tuple<List<double>,List<double>,int> GetUVpoints(int offset, string stagePath, int lastKnownTim)
{
List<double> uv1 = new List<double>();
List<double> uv2 = new List<double>();
int clut = 0;
_stage = File.ReadAllBytes(stagePath);
int tim = lastKnownTim;
int tiMoffsetCluTetc = tim + 18;
ushort cluTsize = BitConverter.ToUInt16(_stage, tiMoffsetCluTetc);
tiMoffsetCluTetc += 2 + (cluTsize * 512) + 8;
_textureDataInt = tiMoffsetCluTetc + 4;
ushort szerU = BitConverter.ToUInt16(_stage, tiMoffsetCluTetc);
ushort wysoU = BitConverter.ToUInt16(_stage, tiMoffsetCluTetc + 2);
_width = szerU * 2;
_height = wysoU;
_verts = BitConverter.ToUInt16(_stage, offset + 4);
_absolutePolygon = offset + 6 + (_verts * 6);
_triangles = BitConverter.ToUInt16(_stage, _absolutePolygon + 4 + (_absolutePolygon % 4));
_quads = BitConverter.ToUInt16(_stage, _absolutePolygon + 6 + (_absolutePolygon % 4));
if (_triangles != 0)
{
_triangleOffset = _absolutePolygon + 12 + (_absolutePolygon % 4);
_currRun = _triangleOffset + 6;
_trisStop = _currRun + (_triangles * 20);
while (true)
{
_u1 = _stage[_currRun];
_v1 = _stage[_currRun + 1];
_u2 = _stage[_currRun + 2];
_v2 = _stage[_currRun + 3];
byte[] clutBuff = new byte[2];
Buffer.BlockCopy(_stage, _currRun + 4, clutBuff, 0, 2);
clut = ResolveClut(clutBuff);
_u3 = _stage[_currRun + 6];
_v3 = _stage[_currRun + 7];
string strByte = _stage[_currRun + 8].ToString("X2");
strByte = "0" + strByte.Substring(1);
byte page = byte.Parse(strByte);
int pageInt = page * 128;
double uu1 = _u1 / (float)_width + ((float)pageInt / _width);
double vv1 = 1.0f - (_v1 / 256.0f);
double uu2 = _u2 / (float)_width + ((float)pageInt / _width);
double vv2 = 1.0f - (_v2 / 256.0f);
double uu3 = _u3 / (float)_width + ((float)pageInt / _width);
double vv3 = 1.0f - (_v3 / 256.0f);
uv1.Add(uu1);
uv2.Add(vv1);
uv1.Add(uu2);
uv2.Add(vv2);
uv1.Add(uu3);
uv2.Add(vv3);
_changeStop = _trisStop - 20;
_changeAdd = 20;
if (_currRun == _changeStop)
break;
_currRun += _changeAdd;
}
}
_currRun = 0;
if (_quads != 0)
{
if (_triangles != 0)
{
_quadOffset = _absolutePolygon + 12 + (_absolutePolygon % 4) + _triangles * 20;
}
else
{
_quadOffset = _absolutePolygon + 12 + (_absolutePolygon % 4);
}
_currRun = _quadOffset + 8;
_quadStop = (_currRun + (_quads * 24));
_trisStop = (_currRun + (_triangles * 20));
while (true)
{
_u1 = _stage[_currRun];
_v1 = _stage[_currRun + 1];
byte[] clutBuff = new byte[2];
Buffer.BlockCopy(_stage, _currRun + 2, clutBuff, 0, 2);
clut = ResolveClut(clutBuff);
_u2 = _stage[_currRun + 4];
_v2 = _stage[_currRun + 5];
_u3 = _stage[_currRun + 8];
_v3 = _stage[_currRun + 9];
_u4 = _stage[_currRun + 10];
_v4 = _stage[_currRun + 11];
string strByte = _stage[_currRun + 6].ToString("X2");
strByte = "0" + strByte.Substring(1);
byte page = byte.Parse(strByte);
int pageInt = page * 128;
double uu1 = _u1 / (float)_width + ((float)pageInt / _width);
double vv1 = 1.0f - (_v1 / 256.0f);
double uu2 = _u2 / (float)_width + ((float)pageInt / _width);
double vv2 = 1.0f - (_v2 / 256.0f);
double uu3 = _u3 / (float)_width + ((float)pageInt / _width);
double vv3 = 1.0f - (_v3 / 256.0f);
double uu4 = _u4 / (float)_width + ((float)pageInt / _width);
double vv4 = 1.0f - (_v4 / 256.0f);
uv1.Add(uu1);
uv2.Add(vv1);
uv1.Add(uu2);
uv2.Add(vv2);
uv1.Add(uu3);
uv2.Add(vv3);
uv1.Add(uu4);
uv2.Add(vv4);
_changeStop = _quadStop - 24;
_changeAdd = 24;
if (_currRun == _changeStop)
break;
_currRun += _changeAdd;
}
}
return new Tuple<List<double>, List<double>, int>(uv1, uv2, clut);
}
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; } }