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

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class MeshCurver : MonoBehaviour
{
[Header("References")]
[SerializeField]
private RotationController m_pivot;
[Header("Settings")]
[SerializeField]
private bool m_ApplyAtStart = true;
[SerializeField]
private bool m_UpdateCollider = true;
[Header("Debug")]
[SerializeField]
private bool m_CalculateEachUpdate = false;
private Mesh m_startMesh;
private MeshFilter m_meshFilter;
private MeshCollider m_meshCollider;
private void Start()
{
m_meshFilter = GetComponent<MeshFilter>();
m_meshCollider = GetComponent<MeshCollider>();
m_startMesh = m_meshFilter.mesh;
if (m_ApplyAtStart)
UpdateMesh();
}
private void Update()
{
if (m_CalculateEachUpdate)
UpdateMesh();
}
[ContextMenu("Update Mesh")]
public void UpdateMesh()
{
Mesh newMesh = UpdateMesh(m_pivot.Position, m_startMesh, m_pivot.RotationAxis, transform);
m_meshFilter.mesh = newMesh;
if (m_meshCollider != null && m_UpdateCollider)
m_meshCollider.sharedMesh = newMesh;
}
public Mesh UpdateMesh(Vector3 centre, Mesh mesh, Vector3 Axis, Transform origin)
{
List<Vector3> transformedVertices = new List<Vector3>();
Vector3[] vertices = mesh.vertices;
Vector3 closestPoint = origin.TransformPoint(vertices.OrderBy(p => Vector3.Distance(centre, origin.TransformPoint(p))).First());
Vector3 direction = closestPoint - centre;
Vector3 perpendicular = Vector3.Cross(Axis, direction).normalized;
Debug.DrawLine(centre, closestPoint, Color.red);
float radius = direction.magnitude;
foreach (Vector3 vertex in vertices)
{
Vector3 worldPosition = origin.TransformPoint(vertex);
Vector3 directionFromStartPoint = Vector3.ProjectOnPlane(worldPosition - closestPoint, Axis);
Vector3 planeOffset = Vector3.Project(worldPosition - closestPoint, Axis);
float heightOffset = radius - Vector3.Project(worldPosition-centre,direction.normalized).magnitude;
float arcLength = directionFromStartPoint.magnitude;
float angle = (arcLength / radius);
if (Vector3.Dot(directionFromStartPoint, perpendicular) < 0)
angle = -angle;
Vector3 directionFromCentre = Quaternion.AngleAxis(Mathf.Rad2Deg * angle, Axis) * ((direction));
transformedVertices.Add((origin.InverseTransformPoint(centre + directionFromCentre.normalized * (radius - heightOffset) + planeOffset)));
}
Mesh retVal = new Mesh();
retVal.vertices = transformedVertices.ToArray();
retVal.triangles = mesh.triangles;
retVal.uv = mesh.uv;
retVal.RecalculateNormals();
retVal.RecalculateTangents();
retVal.RecalculateBounds();
return retVal;
}
}