Skip to content

Commit 0190c4e

Browse files
ThatAmuzakahmed-shariff
authored andcommitted
moved mesh tasks to colliders manager, fixed naming scheme
1 parent 6e337df commit 0190c4e

7 files changed

+181
-167
lines changed

Editor/HPUIMeshContinuousInteractableEditor.cs

-25
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,6 @@ namespace ubco.ovilab.HPUI.Editor
99
[CustomEditor(typeof(HPUIMeshContinuousInteractable))]
1010
public class HPUIMeshContinuousInteractableEditor : HPUIBaseInteractableEditor
1111
{
12-
private HPUIMeshContinuousInteractable t;
13-
private SerializedProperty staticMesh;
14-
private SerializedProperty meshXResolution;
15-
16-
protected override List<string> EventPropertyNames => base.EventPropertyNames.Union(new List<string>()
17-
{
18-
"staticMesh",
19-
"meshXResolution",
20-
}).ToList();
21-
22-
protected override void OnEnable()
23-
{
24-
base.OnEnable();
25-
t = (HPUIMeshContinuousInteractable)target;
26-
staticMesh = serializedObject.FindProperty("staticHPUIMesh");
27-
meshXResolution = serializedObject.FindProperty("meshXResolution");
28-
}
2912

30-
protected override void DrawProperties()
31-
{
32-
base.DrawProperties();
33-
EditorGUILayout.Space();
34-
EditorGUILayout.LabelField("Static Mesh Configurations", EditorStyles.boldLabel);
35-
EditorGUILayout.PropertyField(staticMesh);
36-
EditorGUILayout.PropertyField(meshXResolution);
37-
}
3813
}
3914
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using UnityEngine;
5+
using UnityEditor;
6+
using ubco.ovilab.HPUI.Interaction;
7+
8+
namespace ubco.ovilab.HPUI.Editor
9+
{
10+
[CanEditMultipleObjects]
11+
[CustomEditor(typeof(MeshContinuousCollidersManager))]
12+
public class MeshContinuousCollidersManagerEditor : UnityEditor.Editor
13+
{
14+
private MeshContinuousCollidersManager t;
15+
private bool computedMeshXRes;
16+
private bool successfullyComputedMeshXRes;
17+
18+
public override void OnInspectorGUI()
19+
{
20+
21+
serializedObject.Update();
22+
23+
24+
SerializedProperty vertRemapData = serializedObject.FindProperty("vertexRemapData");
25+
t = (MeshContinuousCollidersManager)target;
26+
27+
GUIContent buttonContent = new GUIContent("Compute Vertex Remapping", "Run this with the mesh upright outside of play mode");
28+
29+
if (GUILayout.Button(buttonContent))
30+
{
31+
int[] remapData = RemapVertices();
32+
33+
// we can compute mesh x resolution
34+
// by leveraging pythagoras
35+
// that when the distance between two vertices after remapping
36+
// is greater than the distance between the previous two pairs
37+
// we know we're on the next row, so that's our last vertex
38+
// on the x-axis
39+
// .
40+
// | \ here the hypotenuse will always be greater than the x width, even for x = 2
41+
// .__.
42+
// this fails if for some reason mesh x res is 1
43+
// or if your differences are lesser than a nanometer
44+
// or if your mesh is not a rectangular grid
45+
// at which point, you're on your own
46+
47+
Mesh tempMesh = new Mesh();
48+
t.Mesh.BakeMesh(tempMesh);
49+
for (int i = 1; i < remapData.Length - 1; i++)
50+
{
51+
Vector3 prevVertex = tempMesh.vertices[remapData[i - 1]];
52+
Vector3 currVertex = tempMesh.vertices[remapData[i]];
53+
Vector3 nextVertex = tempMesh.vertices[remapData[i + 1]];
54+
float prevToCurrDist = Vector3.Distance(prevVertex, currVertex);
55+
float currToNextDist = Vector3.Distance(currVertex, nextVertex);
56+
if (Mathf.Abs(prevToCurrDist - currToNextDist)>0.0000001f)
57+
{
58+
t.MeshXResolution = i + 1;
59+
successfullyComputedMeshXRes = true;
60+
break;
61+
}
62+
}
63+
64+
computedMeshXRes = true;
65+
66+
vertRemapData.arraySize = remapData.Length;
67+
68+
for (int i = 0; i < remapData.Length; i++)
69+
{
70+
vertRemapData.GetArrayElementAtIndex(i).intValue = remapData[i];
71+
}
72+
73+
}
74+
75+
serializedObject.ApplyModifiedProperties();
76+
77+
if(computedMeshXRes)
78+
{
79+
if (successfullyComputedMeshXRes)
80+
{
81+
string message = $"Computed Mesh X Resolution as {t.MeshXResolution}";
82+
EditorGUILayout.HelpBox(message, MessageType.Info);
83+
}
84+
else
85+
{
86+
string message = "Failed to compute Mesh X Resolution! Please Set Manually!";
87+
EditorGUILayout.HelpBox(message, MessageType.Error);
88+
}
89+
}
90+
91+
DrawDefaultInspector();
92+
}
93+
94+
private int[] RemapVertices()
95+
{
96+
SkinnedMeshRenderer targetMesh = t.Mesh;
97+
Mesh tempMesh = new Mesh();
98+
if(targetMesh==null)
99+
{
100+
Debug.LogError("Please assign mesh first!");
101+
}
102+
targetMesh.BakeMesh(tempMesh, true);
103+
return GetRectifiedIndices(tempMesh, serializedObject.FindProperty("flipOrderForRecompute").boolValue);
104+
}
105+
106+
private int[] GetRectifiedIndices(Mesh mesh, bool flipOrder)
107+
{
108+
int vertexCount = mesh.vertexCount;
109+
Vector3[] vertices = mesh.vertices;
110+
int[] correctedIndices = new int[vertexCount];
111+
List<(Vector3 vertex, int index)> indexedVertices = new List<(Vector3 vertex, int index)>(vertexCount);
112+
for (int i = 0; i < vertexCount; i++)
113+
{
114+
indexedVertices.Add((vertices[i], i));
115+
}
116+
indexedVertices.Sort((a, b) =>
117+
{
118+
if (Math.Abs(a.vertex.y - b.vertex.y) > 0.00001)
119+
return a.vertex.y.CompareTo(b.vertex.y);
120+
return b.vertex.x.CompareTo(a.vertex.x);
121+
});
122+
123+
for (int i = 0; i < vertexCount; i++)
124+
{
125+
correctedIndices[i] = indexedVertices[i].index;
126+
}
127+
int[] remapData = flipOrder ? correctedIndices.Reverse().ToArray() : correctedIndices;
128+
return remapData;
129+
}
130+
}
131+
}

Editor/StaticMeshCollidersManagerEditor.cs

-78
This file was deleted.

Runtime/Interaction/HPUIMeshContinuousInteractable.cs

+16-35
Original file line numberDiff line numberDiff line change
@@ -2,75 +2,56 @@
22
using UnityEngine.XR.Interaction.Toolkit.Interactables;
33
namespace ubco.ovilab.HPUI.Interaction
44
{
5-
[RequireComponent(typeof(StaticMeshCollidersManager))]
5+
[RequireComponent(typeof(MeshContinuousCollidersManager))]
66
public class HPUIMeshContinuousInteractable : HPUIBaseInteractable, IHPUIContinuousInteractable
77
{
88
/// <inheritdoc />
9-
public float X_size { get => collidersManager.XWidth * collidersManager.MeshXResolution; }
9+
public float X_size { get => continuousCollidersManager.XWidth * continuousCollidersManager.MeshXResolution; }
1010
/// <inheritdoc />
11-
public float Y_size { get => collidersManager.YWidth * collidersManager.MeshYResolution; }
11+
public float Y_size { get => continuousCollidersManager.YWidth * continuousCollidersManager.MeshYResolution; }
1212
/// <summary>
1313
/// X width of a single collider based on the mesh provided, in Unity units.
1414
/// </summary>
15-
public float SingleColliderXWidth { get => collidersManager.XWidth; }
15+
public float SingleColliderXWidth { get => continuousCollidersManager.XWidth; }
1616
/// <summary>
1717
/// Y width of a single collider based on the mesh provided, in Unity units.
1818
/// </summary>
19-
public float SingleColliderYWidth { get => collidersManager.YWidth; }
19+
public float SingleColliderYWidth { get => continuousCollidersManager.YWidth; }
2020
/// <summary>
2121
/// X Center of interactable (across the width of the finger).
2222
/// </summary>
23-
public float OffsetX { get => collidersManager.OffsetX; }
23+
public float OffsetX { get => continuousCollidersManager.OffsetX; }
2424
/// <summary>
2525
/// Y Center of interactable (along the length of the finger).
2626
/// </summary>
27-
public float OffsetY { get => collidersManager.OffsetY; }
27+
public float OffsetY { get => continuousCollidersManager.OffsetY; }
2828
/// <summary>
2929
/// The X resolution of the associated mesh.
3030
/// This is the number of vertices along the length of the finger(s)
3131
/// </summary>
32-
public int MeshXResolution { get => collidersManager.MeshXResolution;}
32+
public int MeshXResolution { get => continuousCollidersManager.MeshXResolution;}
3333
/// <summary>
3434
/// The Y resolution of the associated mesh.
3535
/// This is the number of vertices along the width of the finger(s)
3636
/// </summary>
37-
public int MeshYResolution { get => collidersManager.MeshYResolution;}
38-
[Tooltip("The associated SkinnedMeshRenderer used by this interactable")]
39-
[SerializeField] private SkinnedMeshRenderer staticHPUIMesh;
40-
/// <summary>
41-
/// The associated SkinnedMeshRenderer used by this interactable
42-
/// </summary>
43-
public SkinnedMeshRenderer StaticHPUIMesh
44-
{
45-
get
46-
{
47-
if (staticHPUIMesh == null)
48-
{
49-
staticHPUIMesh = GetComponent<SkinnedMeshRenderer>();
50-
}
51-
return staticHPUIMesh;
52-
}
53-
set => staticHPUIMesh = value;
54-
}
55-
[Tooltip("The X resolution of the associated SkinnedMeshRenderer.")]
56-
[SerializeField] private int meshXResolution;
37+
public int MeshYResolution { get => continuousCollidersManager.MeshYResolution;}
5738

58-
private StaticMeshCollidersManager collidersManager;
39+
private MeshContinuousCollidersManager continuousCollidersManager;
5940

6041
/// <summary>
6142
/// The associated Colliders Manager.
6243
/// </summary>
63-
public StaticMeshCollidersManager CollidersManager
44+
public MeshContinuousCollidersManager ContinuousCollidersManager
6445
{
65-
get => collidersManager;
46+
get => continuousCollidersManager;
6647
}
6748

6849
protected override void Awake()
6950
{
7051
base.Awake();
71-
collidersManager = GetComponent<StaticMeshCollidersManager>();
72-
Debug.Assert(collidersManager!=null);
73-
colliders.AddRange(collidersManager.SetupColliders(StaticHPUIMesh, meshXResolution));
52+
continuousCollidersManager = GetComponent<MeshContinuousCollidersManager>();
53+
Debug.Assert(continuousCollidersManager!=null);
54+
colliders.AddRange(continuousCollidersManager.SetupColliders());
7455
}
7556
/// <inheritdoc />
7657
protected override void ComputeSurfaceBounds()
@@ -82,7 +63,7 @@ public override bool ComputeInteractorPosition(IHPUIInteractor interactor, out V
8263
if (interactor.GetDistanceInfo(this, out DistanceInfo info))
8364
{
8465
Vector2 offsetOnCollider = ComputeTargetPointOnTransformXZPlane(info.point, info.collider.transform);
85-
position = collidersManager.GetSurfacePointForCollider(info.collider) + offsetOnCollider;
66+
position = continuousCollidersManager.GetSurfacePointForCollider(info.collider) + offsetOnCollider;
8667
return true;
8768
}
8869
position = Vector2.zero;

0 commit comments

Comments
 (0)