Mesh v4 #1

Merged
MaximumADHD merged 2 commits from mesh-v4 into master 2020-07-18 18:44:24 -05:00
5 changed files with 695 additions and 443 deletions

View File

@ -51,8 +51,7 @@
<ItemGroup>
<Compile Include="Extensions\Formatting.cs" />
<Compile Include="Extensions\RegistryHelper.cs" />
<Compile Include="Geometry\Mesh.cs" />
<Compile Include="Geometry\Vertex.cs" />
<Compile Include="Mesh.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">

View File

@ -1,407 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using RobloxFiles.DataTypes;
namespace BevelGenerator
{
public class Mesh
{
public int Version;
public int NumVerts = 0;
public List<Vertex> Verts;
public int NumFaces = 0;
public List<int[]> Faces;
public ushort NumLODs = 0;
public List<int> LODs;
private static Vector3 ReadVector3(BinaryReader reader)
{
float x = reader.ReadSingle(),
y = reader.ReadSingle(),
z = reader.ReadSingle();
return new Vector3(x, y, z);
}
private static Mesh CheckLOD(Mesh mesh)
{
if (mesh.NumLODs == 0)
{
mesh.NumLODs = 2;
mesh.LODs = new List<int> { 0, mesh.NumFaces };
}
return mesh;
}
private static void LoadGeometry_Ascii(StringReader reader, Mesh mesh)
{
string header = reader.ReadLine();
if (!header.StartsWith("version 1"))
throw new Exception("Expected version 1 header, got: " + header);
string version = header.Substring(8);
float vertScale = (version == "1.00" ? 0.5f : 1);
if (int.TryParse(reader.ReadLine(), out mesh.NumFaces))
mesh.NumVerts = mesh.NumFaces * 3;
else
throw new Exception("Expected 2nd line to be the polygon count.");
mesh.Faces = new List<int[]>();
mesh.Verts = new List<Vertex>();
string polyBuffer = reader.ReadLine();
MatchCollection matches = Regex.Matches(polyBuffer, @"\[(.*?)\]");
int face = 0;
int index = 0;
int target = 0;
var vertex = new Vertex();
foreach (Match m in matches)
{
string vectorStr = m.Groups[1].ToString();
float[] coords = vectorStr.Split(',')
.Select(coord => Format.ParseFloat(coord))
.ToArray();
if (target == 0)
vertex.Position = new Vector3(coords) * vertScale;
else if (target == 1)
vertex.Normal = new Vector3(coords);
else if (target == 2)
vertex.UV = new Vector3(coords[0], 1 - coords[1], 0);
target = (target + 1) % 3;
if (target == 0)
{
mesh.Verts.Add(vertex);
vertex = new Vertex();
if (index % 3 == 0)
{
int v = face * 3;
int[] faceDef = new int[3] { v, v + 1, v + 2 };
mesh.Faces.Add(faceDef);
}
}
}
CheckLOD(mesh);
}
private static void LoadGeometry_Binary(BinaryReader reader, Mesh mesh)
{
byte[] binVersion = reader.ReadBytes(13);
var headerSize = reader.ReadUInt16();
var vertSize = reader.ReadByte();
var faceSize = reader.ReadByte();
if (mesh.Version >= 3)
{
var lodRangeSize = reader.ReadUInt16();
mesh.NumLODs = reader.ReadUInt16();
}
mesh.NumVerts = reader.ReadInt32();
mesh.NumFaces = reader.ReadInt32();
mesh.LODs = new List<int>();
mesh.Faces = new List<int[]>();
mesh.Verts = new List<Vertex>();
for (int i = 0; i < mesh.NumVerts; i++)
{
var vert = new Vertex()
{
Position = ReadVector3(reader),
Normal = ReadVector3(reader),
UV = ReadVector3(reader)
};
if (vertSize > 36)
{
int rgba = reader.ReadInt32();
int argb = (rgba << 24 | rgba >> 8);
vert.Color = Color.FromArgb(argb);
vert.HasColor = true;
}
mesh.Verts.Add(vert);
}
for (int i = 0; i < mesh.NumFaces; i++)
{
int[] face = new int[3];
for (int f = 0; f < 3; f++)
face[f] = reader.ReadInt32();
mesh.Faces.Add(face);
}
if (mesh.NumLODs > 0)
{
for (int i = 0; i < mesh.NumLODs; i++)
{
int lod = reader.ReadInt32();
mesh.LODs.Add(lod);
}
}
CheckLOD(mesh);
}
public void AddLOD(Mesh lodMesh)
{
Verts.AddRange(lodMesh.Verts);
Faces.AddRange(lodMesh.Faces
.Select(face => face
.Select(i => i + NumVerts)
.ToArray()
)
);
NumVerts = Verts.Count;
NumFaces = Faces.Count;
LODs.Add(NumFaces);
NumLODs += 1;
}
public void Save(Stream stream)
{
const ushort HeaderSize = 16;
const byte VertSize = 40;
const byte FaceSize = 12;
const ushort LOD_Size = 4;
byte[] VersionHeader = Encoding.ASCII.GetBytes("version 3.00\n");
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(VersionHeader);
writer.Write(HeaderSize);
writer.Write(VertSize);
writer.Write(FaceSize);
writer.Write(LOD_Size);
writer.Write(NumLODs);
writer.Write(NumVerts);
writer.Write(NumFaces);
for (int i = 0; i < NumVerts; i++)
{
Vertex vertex = Verts[i];
Vector3 pos = vertex.Position;
writer.Write(pos.X);
writer.Write(pos.Y);
writer.Write(pos.Z);
Vector3 norm = vertex.Normal;
writer.Write(norm.X);
writer.Write(norm.Y);
writer.Write(norm.Z);
Vector3 uv = vertex.UV;
writer.Write(uv.X);
writer.Write(uv.Y);
writer.Write(uv.Z);
if (vertex.HasColor)
{
var color = vertex.Color;
int argb = color.ToArgb();
int rgba = (argb << 8 | argb >> 24);
writer.Write(rgba);
}
else
{
writer.Write(-1);
}
}
for (int i = 0; i < NumFaces; i++)
{
int[] faces = Faces[i];
for (int f = 0; f < 3; f++)
{
int face = faces[f];
writer.Write(face);
}
}
for (int i = 0; i < NumLODs; i++)
{
int lod = LODs[i];
writer.Write(lod);
}
}
}
public static Mesh FromObjFile(string filePath)
{
string contents = File.ReadAllText(filePath);
Mesh mesh = new Mesh()
{
Version = 3,
Faces = new List<int[]>(),
Verts = new List<Vertex>()
};
var posTable = new List<Vector3>();
var normTable = new List<Vector3>();
var vertexLookup = new Dictionary<string, int>();
using (StringReader reader = new StringReader(contents))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (line.Length == 0)
continue;
string[] buffer = line.Split(' ');
string cmd = buffer[0];
if (cmd == "v" || cmd == "vn")
{
float[] input = buffer
.Skip(1)
.Select(float.Parse)
.ToArray();
var value = new Vector3(input);
var target = (cmd == "v" ? posTable : normTable);
target.Add(value);
}
else if (cmd == "f")
{
int[] face = new int[3];
for (int i = 0; i < 3; i++)
{
string faceDef = buffer[i + 1];
string[] indices = faceDef.Split('/');
int posId = int.Parse(indices[0]) - 1;
int normId = int.Parse(indices[2]) - 1;
string key = $"{posId}/{normId}";
if (!vertexLookup.ContainsKey(key))
{
int faceId = mesh.NumVerts++;
vertexLookup.Add(key, faceId);
Vertex vert = new Vertex()
{
Position = posTable[posId],
Normal = normTable[normId],
UV = new Vector3()
};
mesh.Verts.Add(vert);
}
face[i] = vertexLookup[key];
}
mesh.Faces.Add(face);
mesh.NumFaces++;
}
}
}
return CheckLOD(mesh);
}
public static Mesh FromBuffer(byte[] data)
{
string file = Encoding.ASCII.GetString(data);
if (!file.StartsWith("version "))
throw new Exception("Invalid .mesh header!");
string versionStr = file.Substring(8, 4);
double version = Format.ParseDouble(versionStr);
Mesh mesh = new Mesh();
mesh.Version = (int)version;
IDisposable disposeThis;
if (mesh.Version == 1)
{
StringReader buffer = new StringReader(file);
LoadGeometry_Ascii(buffer, mesh);
disposeThis = buffer;
}
else if (mesh.Version == 2 || mesh.Version == 3)
{
MemoryStream stream = new MemoryStream(data);
using (BinaryReader reader = new BinaryReader(stream))
LoadGeometry_Binary(reader, mesh);
disposeThis = stream;
}
else
{
throw new Exception($"Unknown .mesh file version: {version}");
}
disposeThis.Dispose();
disposeThis = null;
return mesh;
}
public static Mesh FromStream(Stream stream)
{
byte[] data;
using (MemoryStream buffer = new MemoryStream())
{
stream.CopyTo(buffer);
data = buffer.ToArray();
}
return FromBuffer(data);
}
public static Mesh FromFile(string path)
{
using (FileStream meshStream = File.OpenRead(path))
{
return FromStream(meshStream);
}
}
}
}

View File

@ -1,15 +0,0 @@
using System.Drawing;
using RobloxFiles.DataTypes;
namespace BevelGenerator
{
public class Vertex
{
public Vector3 Position;
public Vector3 Normal;
public Vector3 UV;
public bool HasColor = false;
public Color Color;
}
}

628
Bevels/Mesh.cs Normal file
View File

@ -0,0 +1,628 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using RobloxFiles;
using RobloxFiles.DataTypes;
namespace BevelGenerator
{
public class Bone : Instance
{
public int NameIndex;
public short Id;
public short ParentId;
public float Unknown;
public CFrame CFrame;
public override string ToString()
{
return $"[Bone: {Name}]";
}
}
public class Vertex
{
public Vector3 Position;
public Vector3 Normal;
public Vector3 UV;
public Color? Color;
public BoneWeights? Weights;
}
public class SkinData
{
public int FacesBegin;
public int FacesLength;
public int VertsBegin;
public int VertsLength;
public int NumBones;
public short[] BoneIndexTree;
}
public struct BoneWeights
{
public byte[] Bones;
public byte[] Weights;
public override string ToString()
{
var bones = string.Join(", ", Bones);
var weights = string.Join(", ", Weights);
return $"{{Bones: [{bones}] | Weights: [{weights}]}}";
}
}
public class Mesh
{
public int Version;
public ushort NumMeshes = 0;
public int NumVerts = 0;
public List<Vertex> Verts;
public int NumFaces = 0;
public List<int[]> Faces;
public ushort NumLODs;
public List<int> LODs;
public int NumBones = 0;
public List<Bone> Bones;
public int NumSkinData = 0;
public List<SkinData> SkinData;
public int NameTableSize = 0;
public byte[] NameTable;
public bool HasLODs => (Version >= 3);
public bool HasSkinning => (Version >= 4);
public bool HasVertexColors { get; private set; }
private static Vector3 ReadVector3(BinaryReader reader)
{
float x = reader.ReadSingle(),
y = reader.ReadSingle(),
z = reader.ReadSingle();
return new Vector3(x, y, z);
}
private static void LoadGeometry_Ascii(StringReader reader, Mesh mesh)
{
string header = reader.ReadLine();
mesh.NumMeshes = 1;
if (!header.StartsWith("version 1"))
throw new Exception("Expected version 1 header, got: " + header);
string version = header.Substring(8);
float vertScale = (version == "1.00" ? 0.5f : 1);
if (int.TryParse(reader.ReadLine(), out mesh.NumFaces))
mesh.NumVerts = mesh.NumFaces * 3;
else
throw new Exception("Expected 2nd line to be the polygon count.");
mesh.Faces = new List<int[]>();
mesh.Verts = new List<Vertex>();
string polyBuffer = reader.ReadLine();
MatchCollection matches = Regex.Matches(polyBuffer, @"\[(.*?)\]");
int face = 0;
int index = 0;
int target = 0;
var vertex = new Vertex();
foreach (Match m in matches)
{
string vectorStr = m.Groups[1].ToString();
float[] coords = vectorStr.Split(',')
.Select(coord => Format.ParseFloat(coord))
.ToArray();
if (target == 0)
vertex.Position = new Vector3(coords) * vertScale;
else if (target == 1)
vertex.Normal = new Vector3(coords);
else if (target == 2)
vertex.UV = new Vector3(coords[0], 1 - coords[1], 0);
target = (target + 1) % 3;
if (target == 0)
{
mesh.Verts.Add(vertex);
vertex = new Vertex();
if (index % 3 == 0)
{
int v = face * 3;
int[] faceDef = new int[3] { v, v + 1, v + 2 };
mesh.Faces.Add(faceDef);
}
}
}
}
private static void LoadGeometry_Binary(BinaryReader reader, Mesh mesh)
{
byte[] binVersion = reader.ReadBytes(13); // version x.xx\n
var headerSize = reader.ReadUInt16();
if (mesh.HasSkinning)
{
mesh.NumMeshes = reader.ReadUInt16();
mesh.NumVerts = reader.ReadInt32();
mesh.NumFaces = reader.ReadInt32();
mesh.NumLODs = reader.ReadUInt16();
mesh.NumBones = reader.ReadUInt16();
mesh.NameTableSize = reader.ReadInt32();
mesh.NumSkinData = reader.ReadInt32();
}
else
{
var sizeof_Vertex = reader.ReadByte();
mesh.HasVertexColors = (sizeof_Vertex > 36);
_ = reader.ReadByte();
if (mesh.HasLODs)
{
_ = reader.ReadUInt16();
mesh.NumLODs = reader.ReadUInt16();
}
if (mesh.NumLODs > 0)
mesh.NumMeshes = (ushort)(mesh.NumLODs - 1);
else
mesh.NumMeshes = 1;
mesh.NumVerts = reader.ReadInt32();
mesh.NumFaces = reader.ReadInt32();
mesh.NameTable = new byte[0];
}
mesh.LODs = new List<int>();
mesh.Bones = new List<Bone>();
mesh.Faces = new List<int[]>();
mesh.Verts = new List<Vertex>();
mesh.SkinData = new List<SkinData>();
// Read Vertices
for (int i = 0; i < mesh.NumVerts; i++)
{
var vert = new Vertex()
{
Position = ReadVector3(reader),
Normal = ReadVector3(reader),
UV = ReadVector3(reader)
};
Color? color = null;
if (mesh.HasVertexColors)
{
int rgba = reader.ReadInt32();
color = Color.FromArgb(rgba << 24 | rgba >> 8);
}
vert.Color = color;
mesh.Verts.Add(vert);
}
if (mesh.HasSkinning)
{
// Read Bone Weights?
for (int i = 0; i < mesh.NumVerts; i++)
{
var vert = mesh.Verts[i];
var weights = new BoneWeights()
{
Bones = reader.ReadBytes(4),
Weights = reader.ReadBytes(4)
};
vert.Weights = weights;
}
}
// Read Faces
for (int i = 0; i < mesh.NumFaces; i++)
{
int[] face = new int[3];
for (int f = 0; f < 3; f++)
face[f] = reader.ReadInt32();
mesh.Faces.Add(face);
}
if (mesh.HasLODs && mesh.NumLODs > 0)
{
// Read LOD ranges
for (int i = 0; i < mesh.NumLODs; i++)
{
int lod = reader.ReadInt32();
mesh.LODs.Add(lod);
}
}
if (mesh.HasSkinning)
{
// Read Bones
for (int i = 0; i < mesh.NumBones; i++)
{
float[] cf = new float[12];
Bone bone = new Bone()
{
NameIndex = reader.ReadInt32(),
Id = reader.ReadInt16(),
ParentId = reader.ReadInt16(),
Unknown = reader.ReadSingle()
};
for (int m = 0; m < 12; m++)
{
int index = (m + 3) % 12;
cf[index] = reader.ReadSingle();
}
bone.CFrame = new CFrame(cf);
mesh.Bones.Add(bone);
}
// Read Bone Names & Parents
var nameTable = reader.ReadBytes(mesh.NameTableSize);
mesh.NameTable = nameTable;
foreach (Bone bone in mesh.Bones)
{
int index = bone.NameIndex;
int parentId = bone.ParentId;
var buffer = new List<byte>();
while (true)
{
byte next = nameTable[index];
if (next > 0)
index++;
else
break;
buffer.Add(next);
}
var result = buffer.ToArray();
bone.Name = Encoding.UTF8.GetString(result);
if (parentId >= 0)
{
var parent = mesh.Bones[parentId];
bone.Parent = parent;
}
}
// Read Skin Data?
for (int p = 0; p < mesh.NumSkinData; p++)
{
var skinData = new SkinData()
{
FacesBegin = reader.ReadInt32(),
FacesLength = reader.ReadInt32(),
VertsBegin = reader.ReadInt32(),
VertsLength = reader.ReadInt32(),
NumBones = reader.ReadInt32(),
BoneIndexTree = new short[26]
};
for (int i = 0; i < 26; i++)
skinData.BoneIndexTree[i] = reader.ReadInt16();
mesh.SkinData.Add(skinData);
}
}
Debugger.Break();
}
public void AddLOD(Mesh lodMesh)
{
Verts.AddRange(lodMesh.Verts);
Faces.AddRange
(
lodMesh.Faces.Select
(
face => face
.Select(i => i + NumVerts)
.ToArray()
)
);
NumVerts = Verts.Count;
NumFaces = Faces.Count;
LODs.Add(NumFaces);
NumLODs += 1;
}
public void Save(Stream stream)
{
const ushort HeaderSize = 16;
const byte VertSize = 40;
const byte FaceSize = 12;
const ushort LOD_Size = 4;
byte[] VersionHeader = Encoding.UTF8.GetBytes("version 3.00\n");
if (NumLODs == 0)
{
NumLODs = 2;
LODs = new List<int> { 0, NumFaces };
}
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(VersionHeader);
writer.Write(HeaderSize);
writer.Write(VertSize);
writer.Write(FaceSize);
writer.Write(LOD_Size);
writer.Write(NumLODs);
writer.Write(NumVerts);
writer.Write(NumFaces);
for (int i = 0; i < NumVerts; i++)
{
Vertex vertex = Verts[i];
Vector3 pos = vertex.Position;
writer.Write(pos.X);
writer.Write(pos.Y);
writer.Write(pos.Z);
Vector3 norm = vertex.Normal;
writer.Write(norm.X);
writer.Write(norm.Y);
writer.Write(norm.Z);
Vector3 uv = vertex.UV;
writer.Write(uv.X);
writer.Write(uv.Y);
writer.Write(uv.Z);
if (vertex.Color.HasValue)
{
var color = vertex.Color.Value;
int argb = color.ToArgb();
int rgba = (argb << 8 | argb >> 24);
writer.Write(rgba);
}
else
{
writer.Write(-1);
}
}
for (int i = 0; i < NumFaces; i++)
{
int[] faces = Faces[i];
for (int f = 0; f < 3; f++)
{
int face = faces[f];
writer.Write(face);
}
}
for (int i = 0; i < NumLODs; i++)
{
int lod = LODs[i];
writer.Write(lod);
}
}
}
public static Mesh FromObjFile(string filePath)
{
string contents = File.ReadAllText(filePath);
Mesh mesh = new Mesh()
{
Version = 3,
Faces = new List<int[]>(),
Verts = new List<Vertex>()
};
var uvTable = new List<Vector3>();
var posTable = new List<Vector3>();
var normTable = new List<Vector3>();
var vertexLookup = new Dictionary<string, int>();
using (StringReader reader = new StringReader(contents))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (line.Length == 0)
continue;
string[] buffer = line.Split(' ');
string action = buffer[0];
switch (action)
{
case "v":
case "vn":
case "vt":
{
float[] input = buffer
.Skip(1)
.Select(float.Parse)
.ToArray();
var value = new Vector3(input);
List<Vector3> target = null;
switch (action)
{
case "v":
{
target = posTable;
break;
}
case "vn":
{
target = normTable;
break;
}
case "vt":
{
target = uvTable;
break;
}
}
target.Add(value);
break;
}
case "f":
{
int[] face = new int[3];
for (int i = 0; i < 3; i++)
{
string faceDef = buffer[i + 1];
string[] indices = faceDef.Split('/');
int uvId = int.Parse(indices[1]) - 1;
int posId = int.Parse(indices[0]) - 1;
int normId = int.Parse(indices[2]) - 1;
string key = $"{posId}/{uvId}/{normId}";
if (!vertexLookup.ContainsKey(key))
{
int faceId = mesh.NumVerts++;
vertexLookup.Add(key, faceId);
Vertex vert = new Vertex()
{
Position = posTable[posId],
Normal = normTable[normId],
UV = uvTable[uvId]
};
mesh.Verts.Add(vert);
}
face[i] = vertexLookup[key];
}
mesh.Faces.Add(face);
mesh.NumFaces++;
break;
}
}
}
}
return mesh;
}
public static Mesh FromBuffer(byte[] data)
{
string file = Encoding.ASCII.GetString(data);
if (!file.StartsWith("version "))
throw new Exception("Invalid .mesh header!");
string versionStr = file.Substring(8, 4);
double version = Format.ParseDouble(versionStr);
Mesh mesh = new Mesh();
mesh.Version = (int)version;
IDisposable disposeThis;
if (mesh.Version == 1)
{
StringReader buffer = new StringReader(file);
LoadGeometry_Ascii(buffer, mesh);
disposeThis = buffer;
}
else
{
MemoryStream stream = new MemoryStream(data);
using (BinaryReader reader = new BinaryReader(stream))
LoadGeometry_Binary(reader, mesh);
disposeThis = stream;
}
disposeThis.Dispose();
disposeThis = null;
return mesh;
}
public static Mesh FromStream(Stream stream)
{
byte[] data;
using (MemoryStream buffer = new MemoryStream())
{
stream.CopyTo(buffer);
data = buffer.ToArray();
}
return FromBuffer(data);
}
public static Mesh FromFile(string path)
{
Mesh result;
using (FileStream meshStream = File.OpenRead(path))
result = FromStream(meshStream);
return result;
}
}
}

View File

@ -11,6 +11,7 @@ using RobloxFiles.Enums;
using RobloxFiles.DataTypes;
using Microsoft.Win32;
using System.Text.RegularExpressions;
namespace BevelGenerator
{
@ -20,7 +21,7 @@ namespace BevelGenerator
private static string bevelCacheDir;
private static string studioCookies = "";
private static string xCsrfToken = "Fetch";
private static string xCsrfToken = "FETCH";
private static Random rng = new Random();
@ -102,7 +103,7 @@ namespace BevelGenerator
// Update the X-CSRF-TOKEN.
xCsrfToken = response.Headers.Get("X-CSRF-TOKEN");
// Retry the request again.
// Retry the upload.
return UploadMesh(mesh, name, desc);
}
else
@ -240,34 +241,79 @@ namespace BevelGenerator
Console.Clear();
}
static void ProcessObjFile(FileInfo info)
static Mesh PortObjFile(FileInfo info)
{
Console.WriteLine("Reading obj file...");
string objPath = info.FullName;
Mesh mesh = Mesh.FromObjFile(objPath);
string meshPath = objPath.Replace(info.Extension, ".mesh");
FileStream file = File.OpenWrite(meshPath);
Console.WriteLine("Writing mesh file...");
using (file)
string extension = info.Extension;
string filePath = objPath.Replace(extension, ".mesh");
using (FileStream file = File.OpenWrite(filePath))
{
file.SetLength(0);
mesh.Save(file);
}
Debugger.Break();
return mesh;
}
static void ProcessFileArg(string filePath)
{
FileInfo info = new FileInfo(filePath);
if (info.Extension == ".obj")
switch (info.Extension)
{
ProcessObjFile(info);
return;
case ".obj":
Mesh export = PortObjFile(info);
Console.Write("Would you like to upload this mesh? (y/n): ");
string answer = Console.ReadLine();
if (answer.ToLower()[0] == 'y')
{
Console.Write("Enter a name for this mesh: ");
string name = Console.ReadLine();
Console.Write("Enter a description for this mesh: ");
string desc = Console.ReadLine();
Console.WriteLine("Uploading mesh...");
long result = 0;
try
{
result = UploadMesh(export, name, desc);
}
catch (Exception e)
{
Console.WriteLine($"An error occurred while uploading: {e.Message}");
}
if (result > 0)
{
Clipboard.SetText($"rbxassetid://{result}");
Console.WriteLine($"Result -> rbxassetid://{result} (copied to clipboard)");
}
Debugger.Break();
}
break;
case ".bin":
case ".mesh":
Mesh import = Mesh.FromFile(filePath);
Debugger.Break();
break;
default:
ProcessModelFile(filePath);
break;
}
}
[STAThread]
@ -289,17 +335,18 @@ namespace BevelGenerator
foreach (string name in robloxCookies.GetValueNames())
{
string cookie = robloxCookies.GetString(name);
Match match = Regex.Match(cookie, "COOK::<([^>]*)>");
int startIndex = cookie.IndexOf("COOK::<") + 7;
int endIndex = cookie.IndexOf('>', startIndex);
cookie = cookie.Substring(startIndex, endIndex - startIndex);
if (match.Groups.Count > 1)
{
cookie = match.Groups[1].Value;
if (studioCookies.Length > 0)
studioCookies += "; ";
studioCookies += $"{name}={cookie}";
}
}
if (args.Length > 0)
{