Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .vs/GearLib/DesignTimeBuild/.dtbcache.v2
Binary file not shown.
Binary file not shown.
Binary file added .vs/GearLib/v17/.futdcache.v2
Binary file not shown.
Binary file added .vs/GearLib/v17/.suo
Binary file not shown.
Binary file added .vs/GearLib/v17/.wsuo
Binary file not shown.
75 changes: 75 additions & 0 deletions .vs/GearLib/v17/DocumentLayout.json
Original file line number Diff line number Diff line change
@@ -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": ""
}
]
}
]
}
]
}
Binary file added .vs/ProjectEvaluation/gearlib.metadata.v8.bin
Binary file not shown.
Binary file added .vs/ProjectEvaluation/gearlib.projects.v8.bin
Binary file not shown.
Binary file added .vs/ProjectEvaluation/gearlib.strings.v8.bin
Binary file not shown.
6 changes: 6 additions & 0 deletions .vs/VSWorkspaceState.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"ExpandedNodes": [
"\\Utils"
],
"PreviewInSolutionExplorer": false
}
Binary file added .vs/slnx.sqlite
Binary file not shown.
9 changes: 8 additions & 1 deletion API/Part.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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}]");
Expand Down Expand Up @@ -182,6 +184,11 @@ public Part(
foreach (MonoBehaviour behaviour in game_object.GetComponentsInChildren<MonoBehaviour>())
behaviour.enabled = false;
}
else if (custom_collider) {
BoxCollisionVolume volume = collider.AddComponent<BoxCollisionVolume>();
volume.size = new Vector3(0.1f, 0.1f, 0.1f);
volume.center = custom_collider_position;
}
else
{
BoxCollisionVolume volume = collider.AddComponent<BoxCollisionVolume>();
Expand Down
4 changes: 3 additions & 1 deletion Utils/GearthonLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 != "")
Expand Down
182 changes: 109 additions & 73 deletions Utils/ObjParser.cs
Original file line number Diff line number Diff line change
@@ -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<Vector3> vertices = new List<Vector3>();
List<Vector3> normals = new List<Vector3>();
List<Vector2> uvs = new List<Vector2>();
List<string> faces = new List<string>();
public static Mesh ParseObj(string[] data)
{
List<Vector3> vertices = new List<Vector3>();
List<Vector3> normals = new List<Vector3>();
List<Vector2> uvs = new List<Vector2>();
List<int> triangles = new List<int>();

List<Vector3> meshVertices = new List<Vector3>();
List<Vector3> meshNormals = new List<Vector3>();
List<Vector2> meshUVs = new List<Vector2>();

foreach (string line in data)
{
string[] parts = line.Trim().Split(' ');
Dictionary<string, int> vertexIndexMap = new Dictionary<string, int>();

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<Vector3> unity_vertices = new List<Vector3>();
List<Vector3> unity_normals = new List<Vector3>();
List<Vector2> unity_uvs = new List<Vector2>();
List<int> unity_faces = new List<int>();
foreach (string face in faces)
private static void ParseFace(string[] parts, List<Vector3> vertices, List<Vector3> normals, List<Vector2> uvs,
List<Vector3> meshVertices, List<Vector3> meshNormals, List<Vector2> meshUVs,
List<int> triangles, Dictionary<string, int> 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);
}
}
}