diff --git a/.vs/GearLib/DesignTimeBuild/.dtbcache.v2 b/.vs/GearLib/DesignTimeBuild/.dtbcache.v2 new file mode 100644 index 0000000..501531e Binary files /dev/null and b/.vs/GearLib/DesignTimeBuild/.dtbcache.v2 differ diff --git a/.vs/GearLib/FileContentIndex/399c3822-1081-482f-8a10-742059eaa5b9.vsidx b/.vs/GearLib/FileContentIndex/399c3822-1081-482f-8a10-742059eaa5b9.vsidx new file mode 100644 index 0000000..f5c4dce Binary files /dev/null and b/.vs/GearLib/FileContentIndex/399c3822-1081-482f-8a10-742059eaa5b9.vsidx differ diff --git a/.vs/GearLib/v17/.futdcache.v2 b/.vs/GearLib/v17/.futdcache.v2 new file mode 100644 index 0000000..0ec8e4a Binary files /dev/null and b/.vs/GearLib/v17/.futdcache.v2 differ diff --git a/.vs/GearLib/v17/.suo b/.vs/GearLib/v17/.suo new file mode 100644 index 0000000..cfd4f63 Binary files /dev/null and b/.vs/GearLib/v17/.suo differ diff --git a/.vs/GearLib/v17/.wsuo b/.vs/GearLib/v17/.wsuo new file mode 100644 index 0000000..7c08f77 Binary files /dev/null and b/.vs/GearLib/v17/.wsuo differ diff --git a/.vs/GearLib/v17/DocumentLayout.json b/.vs/GearLib/v17/DocumentLayout.json new file mode 100644 index 0000000..7878478 --- /dev/null +++ b/.vs/GearLib/v17/DocumentLayout.json @@ -0,0 +1,75 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\jacob\\source\\repos\\jacobbclr\\GearLib\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{1D09B02E-4BC7-43AA-AB94-0CD0003BBD41}|GearLib.csproj|c:\\users\\jacob\\source\\repos\\jacobbclr\\gearlib\\utils\\objparser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{1D09B02E-4BC7-43AA-AB94-0CD0003BBD41}|GearLib.csproj|solutionrelative:utils\\objparser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{1D09B02E-4BC7-43AA-AB94-0CD0003BBD41}|GearLib.csproj|c:\\users\\jacob\\source\\repos\\jacobbclr\\gearlib\\utils\\gearthonloader.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{1D09B02E-4BC7-43AA-AB94-0CD0003BBD41}|GearLib.csproj|solutionrelative:utils\\gearthonloader.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{1D09B02E-4BC7-43AA-AB94-0CD0003BBD41}|GearLib.csproj|c:\\users\\jacob\\source\\repos\\jacobbclr\\gearlib\\api\\part.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{1D09B02E-4BC7-43AA-AB94-0CD0003BBD41}|GearLib.csproj|solutionrelative:api\\part.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 1, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:128:0:{75188d03-9892-4ae2-abf1-207126247ce5}" + }, + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "ObjParser.cs", + "DocumentMoniker": "C:\\Users\\jacob\\source\\repos\\jacobbclr\\GearLib\\Utils\\ObjParser.cs", + "RelativeDocumentMoniker": "Utils\\ObjParser.cs", + "ToolTip": "C:\\Users\\jacob\\source\\repos\\jacobbclr\\GearLib\\Utils\\ObjParser.cs", + "RelativeToolTip": "Utils\\ObjParser.cs", + "ViewState": "AQIAAGkAAAAAAAAAAAAowIcAAAABAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-02T11:20:26.478Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "GearthonLoader.cs", + "DocumentMoniker": "C:\\Users\\jacob\\source\\repos\\jacobbclr\\GearLib\\Utils\\GearthonLoader.cs", + "RelativeDocumentMoniker": "Utils\\GearthonLoader.cs", + "ToolTip": "C:\\Users\\jacob\\source\\repos\\jacobbclr\\GearLib\\Utils\\GearthonLoader.cs", + "RelativeToolTip": "Utils\\GearthonLoader.cs", + "ViewState": "AQIAAHMAAAAAAAAAAAAAAIQAAABHAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-02T10:05:33.457Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "Part.cs", + "DocumentMoniker": "C:\\Users\\jacob\\source\\repos\\jacobbclr\\GearLib\\API\\Part.cs", + "RelativeDocumentMoniker": "API\\Part.cs", + "ToolTip": "C:\\Users\\jacob\\source\\repos\\jacobbclr\\GearLib\\API\\Part.cs", + "RelativeToolTip": "API\\Part.cs", + "ViewState": "AQIAADAAAAAAAAAAAAAqwEEAAAAlAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-02T10:03:18.5Z", + "EditorCaption": "" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/.vs/ProjectEvaluation/gearlib.metadata.v8.bin b/.vs/ProjectEvaluation/gearlib.metadata.v8.bin new file mode 100644 index 0000000..f2275a0 Binary files /dev/null and b/.vs/ProjectEvaluation/gearlib.metadata.v8.bin differ diff --git a/.vs/ProjectEvaluation/gearlib.projects.v8.bin b/.vs/ProjectEvaluation/gearlib.projects.v8.bin new file mode 100644 index 0000000..9d1f3af Binary files /dev/null and b/.vs/ProjectEvaluation/gearlib.projects.v8.bin differ diff --git a/.vs/ProjectEvaluation/gearlib.strings.v8.bin b/.vs/ProjectEvaluation/gearlib.strings.v8.bin new file mode 100644 index 0000000..d21ae8f Binary files /dev/null and b/.vs/ProjectEvaluation/gearlib.strings.v8.bin differ diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..3f24944 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,6 @@ +{ + "ExpandedNodes": [ + "\\Utils" + ], + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000..8529102 Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/API/Part.cs b/API/Part.cs index d279689..b4c6ce4 100644 --- a/API/Part.cs +++ b/API/Part.cs @@ -62,7 +62,9 @@ public Part( string asset = null, bool is_paintable = false, bool is_swappable_material = false, - bool mesh_collider = false + bool mesh_collider = false, + bool custom_collider = false, + Vector3 custom_collider_position = default(Vector3) ) { Plugin.Log.LogInfo($"{GetType().Name}: Adding custom part [{display_name}]"); @@ -182,6 +184,11 @@ public Part( foreach (MonoBehaviour behaviour in game_object.GetComponentsInChildren()) behaviour.enabled = false; } + else if (custom_collider) { + BoxCollisionVolume volume = collider.AddComponent(); + volume.size = new Vector3(0.1f, 0.1f, 0.1f); + volume.center = custom_collider_position; + } else { BoxCollisionVolume volume = collider.AddComponent(); diff --git a/Utils/GearthonLoader.cs b/Utils/GearthonLoader.cs index 031172b..8adea0e 100644 --- a/Utils/GearthonLoader.cs +++ b/Utils/GearthonLoader.cs @@ -129,7 +129,9 @@ public static void LoadParts() asset_path: $"{mod_folder}/models", is_paintable: (string)part_data["is_paintable"] == "True", is_swappable_material: (string)part_data["is_swappable_material"] == "True", - mesh_collider: (string)part_data["mesh_collider"] == "True" + mesh_collider: (string)part_data["mesh_collider"] == "True", + custom_collider: (string)part_data["custom_collider"] == "True", + custom_collider_position: (string)part_data["custom_collider"] == "True" ? JTokenToVector3(part_data["custom_collider_position"]) : default(Vector3) ); if (script != "") diff --git a/Utils/ObjParser.cs b/Utils/ObjParser.cs index 58d2425..3784e39 100644 --- a/Utils/ObjParser.cs +++ b/Utils/ObjParser.cs @@ -1,100 +1,136 @@ using UnityEngine; using System.Collections.Generic; -using System.IO; -using GearLib; -using System.Linq; -using System; using System.Globalization; -namespace GearLib.Utils; - -public class ObjParser +namespace GearLib.Utils { - public static Mesh ParseObj(string[] data) + public class ObjParser { - List vertices = new List(); - List normals = new List(); - List uvs = new List(); - List faces = new List(); + public static Mesh ParseObj(string[] data) + { + List vertices = new List(); + List normals = new List(); + List uvs = new List(); + List triangles = new List(); + List meshVertices = new List(); + List meshNormals = new List(); + List meshUVs = new List(); - foreach (string line in data) - { - string[] parts = line.Trim().Split(' '); + Dictionary vertexIndexMap = new Dictionary(); - switch (parts[0]) + foreach (string line in data) { - case "v": // Vertex position - Vector3 vertex = ParseVector3(parts); - vertices.Add(vertex); - break; - case "vn": // Vertex normal - Vector3 normal = ParseVector3(parts); - normals.Add(normal); - break; - case "vt": // Texture coordinate (UV) - Vector2 uv = ParseVector2(parts); - uvs.Add(uv); - break; - case "f": // Face - for (int i = 1; i < parts.Length; i++) - { - faces.Add(parts[i]); - } - break; + string[] parts = line.Trim().Split(' '); + + switch (parts[0]) + { + case "v": + vertices.Add(ParseVector3(parts)); + break; + case "vn": + normals.Add(ParseVector3(parts)); + break; + case "vt": + uvs.Add(ParseVector2(parts)); + break; + case "f": + ParseFace(parts, vertices, normals, uvs, meshVertices, meshNormals, meshUVs, triangles, vertexIndexMap); + break; + } } + + Mesh mesh = new Mesh + { + vertices = meshVertices.ToArray(), + triangles = triangles.ToArray() + }; + + if (meshNormals.Count > 0) + { + mesh.normals = meshNormals.ToArray(); + } + else + { + mesh.RecalculateNormals(); + } + + if (meshUVs.Count > 0) + { + mesh.uv = meshUVs.ToArray(); + } + + mesh.RecalculateBounds(); + return mesh; } - // Rebuilding obj for Unity - List unity_vertices = new List(); - List unity_normals = new List(); - List unity_uvs = new List(); - List unity_faces = new List(); - foreach (string face in faces) + private static void ParseFace(string[] parts, List vertices, List normals, List uvs, + List meshVertices, List meshNormals, List meshUVs, + List triangles, Dictionary vertexIndexMap) { - string[] face_data = face.Replace("f ", "").Split(' '); - foreach (string d in face_data) + for (int i = 1; i < parts.Length; i++) { - string[] ds = face.Split('/'); - Vector3 unity_vertex = vertices[Convert.ToInt32(ds[0])-1]; - unity_vertices.Add(unity_vertex); + string key = parts[i]; + if (!vertexIndexMap.TryGetValue(key, out int index)) + { + string[] indices = key.Split('/'); - Vector3 unity_normal = normals[Convert.ToInt32(ds[2])-1]; - unity_normals.Add(unity_normal); + int vertIndex = ParseIndex(indices[0], vertices.Count); + Vector3 vertex = vertices[vertIndex]; - if (ds[1] != "") - { - Vector2 unity_uv = uvs[Convert.ToInt32(ds[1])-1]; - unity_uvs.Add(unity_uv); + Vector3 normal = Vector3.zero; + if (indices.Length > 2 && !string.IsNullOrEmpty(indices[2])) + { + int normIndex = ParseIndex(indices[2], normals.Count); + normal = normals[normIndex]; + } + + Vector2 uv = Vector2.zero; + if (indices.Length > 1 && !string.IsNullOrEmpty(indices[1])) + { + int uvIndex = ParseIndex(indices[1], uvs.Count); + uv = uvs[uvIndex]; + } + + index = meshVertices.Count; + meshVertices.Add(vertex); + if (normals.Count > 0) meshNormals.Add(normal); + if (uvs.Count > 0) meshUVs.Add(uv); + + vertexIndexMap[key] = index; } - unity_faces.Add(unity_vertices.Count-1); + triangles.Add(index); } } - Mesh mesh = new Mesh + private static int ParseIndex(string index, int count) { - vertices = unity_vertices.ToArray(), - normals = unity_normals.ToArray(), - uv = unity_uvs.ToArray(), - triangles = unity_faces.ToArray() - }; - mesh.RecalculateNormals(); // Recalculate normals based on the vertices and triangles - return mesh; - } + int result = int.Parse(index); + if (result < 0) + { + result = count + result; + } + else + { + result = result - 1; + } + return result; + } - private static Vector3 ParseVector3(string[] parts) - { - float x = float.Parse(parts[1], CultureInfo.InvariantCulture); - float y = float.Parse(parts[2], CultureInfo.InvariantCulture); - float z = float.Parse(parts[3], CultureInfo.InvariantCulture); - return new Vector3(x, y, z); - } + private static Vector3 ParseVector3(string[] parts) + { + float x = float.Parse(parts[1], CultureInfo.InvariantCulture); + float y = float.Parse(parts[2], CultureInfo.InvariantCulture); + float z = float.Parse(parts[3], CultureInfo.InvariantCulture); + return new Vector3(x, y, z); + } - private static Vector2 ParseVector2(string[] parts) - { - float x = float.Parse(parts[1], CultureInfo.InvariantCulture); - float y = float.Parse(parts[2], CultureInfo.InvariantCulture); - return new Vector2(x, y); + private static Vector2 ParseVector2(string[] parts) + { + float x = float.Parse(parts[1], CultureInfo.InvariantCulture); + float y = float.Parse(parts[2], CultureInfo.InvariantCulture); + return new Vector2(x, y); + } } } \ No newline at end of file