Assignment for RMIT Mixed Reality in 2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
3.0 KiB

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. public class MeshCurver : MonoBehaviour
  6. {
  7. [Header("References")]
  8. [SerializeField]
  9. private RotationController m_pivot;
  10. [Header("Settings")]
  11. [SerializeField]
  12. private bool m_ApplyAtStart = true;
  13. [SerializeField]
  14. private bool m_UpdateCollider = true;
  15. [Header("Debug")]
  16. [SerializeField]
  17. private bool m_CalculateEachUpdate = false;
  18. private Mesh m_startMesh;
  19. private MeshFilter m_meshFilter;
  20. private MeshCollider m_meshCollider;
  21. private void Start()
  22. {
  23. m_meshFilter = GetComponent<MeshFilter>();
  24. m_meshCollider = GetComponent<MeshCollider>();
  25. m_startMesh = m_meshFilter.mesh;
  26. if (m_ApplyAtStart)
  27. UpdateMesh();
  28. }
  29. private void Update()
  30. {
  31. if (m_CalculateEachUpdate)
  32. UpdateMesh();
  33. }
  34. [ContextMenu("Update Mesh")]
  35. public void UpdateMesh()
  36. {
  37. Mesh newMesh = UpdateMesh(m_pivot.Position, m_startMesh, m_pivot.RotationAxis, transform);
  38. m_meshFilter.mesh = newMesh;
  39. if (m_meshCollider != null && m_UpdateCollider)
  40. m_meshCollider.sharedMesh = newMesh;
  41. }
  42. public Mesh UpdateMesh(Vector3 centre, Mesh mesh, Vector3 Axis, Transform origin)
  43. {
  44. List<Vector3> transformedVertices = new List<Vector3>();
  45. Vector3[] vertices = mesh.vertices;
  46. Vector3 closestPoint = origin.TransformPoint(vertices.OrderBy(p => Vector3.Distance(centre, origin.TransformPoint(p))).First());
  47. Vector3 direction = closestPoint - centre;
  48. Vector3 perpendicular = Vector3.Cross(Axis, direction).normalized;
  49. Debug.DrawLine(centre, closestPoint, Color.red);
  50. float radius = direction.magnitude;
  51. foreach (Vector3 vertex in vertices)
  52. {
  53. Vector3 worldPosition = origin.TransformPoint(vertex);
  54. Vector3 directionFromStartPoint = Vector3.ProjectOnPlane(worldPosition - closestPoint, Axis);
  55. Vector3 planeOffset = Vector3.Project(worldPosition - closestPoint, Axis);
  56. float heightOffset = radius - Vector3.Project(worldPosition-centre,direction.normalized).magnitude;
  57. float arcLength = directionFromStartPoint.magnitude;
  58. float angle = (arcLength / radius);
  59. if (Vector3.Dot(directionFromStartPoint, perpendicular) < 0)
  60. angle = -angle;
  61. Vector3 directionFromCentre = Quaternion.AngleAxis(Mathf.Rad2Deg * angle, Axis) * ((direction));
  62. transformedVertices.Add((origin.InverseTransformPoint(centre + directionFromCentre.normalized * (radius - heightOffset) + planeOffset)));
  63. }
  64. Mesh retVal = new Mesh();
  65. retVal.vertices = transformedVertices.ToArray();
  66. retVal.triangles = mesh.triangles;
  67. retVal.uv = mesh.uv;
  68. retVal.RecalculateNormals();
  69. retVal.RecalculateTangents();
  70. retVal.RecalculateBounds();
  71. return retVal;
  72. }
  73. }