Select Git revision
DeformAnchor.cs
DeformAnchor.cs 3.83 KiB
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.XR.CoreUtils;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
public class DeformAnchor : MonoBehaviour
{
private BlockDeform _blockDeform;
private Vector3 _normal;
private float _offset;
private GameObject _position;
private Vector3 _previousPosition;
private XRGrabInteractable grabInteractable;
private Mesh mesh;
public void SetupAnchor(BlockDeform blockDeform, Vector3 normal, Vector3 bounds, float offset)
{
this._blockDeform = blockDeform;
this._normal = normal;
this._offset = offset;
// create empty for real position of anchor
_position = new("Position Anchor");
_position.transform.parent = this.gameObject.transform;
// position setup
this.transform.position += Vector3.Scale(normal, bounds) + normal * _offset;
// rotation setup
this.transform.rotation = Quaternion.LookRotation(-_normal);
_position.transform.position = transform.position + (-_normal * _offset);
}
private void Awake()
{
mesh = this.GetComponent<MeshFilter>().mesh;
grabInteractable = GetComponent<XRGrabInteractable>();
grabInteractable.selectEntered.AddListener(HandleSelectEnter);
grabInteractable.selectExited.AddListener(HandleSelectExit);
grabInteractable.hoverEntered.AddListener(HandleHoverEntered);
grabInteractable.hoverExited.AddListener(HandleHoverExited);
}
private void HandleHoverExited(HoverExitEventArgs arg0)
{
this.gameObject.GetComponent<MeshRenderer>().enabled = false;
}
private void HandleHoverEntered(HoverEnterEventArgs arg0)
{
this.gameObject.GetComponent<MeshRenderer>().enabled = true;
}
private void HandleSelectExit(SelectExitEventArgs arg0)
{
_blockDeform.HandleAnchorGrabbed(_position.transform, _previousPosition, this);
}
private void HandleSelectEnter(SelectEnterEventArgs arg0)
{
_previousPosition = _position.transform.position;
}
public void SetMeshScale(List<Vector3> vertices)
{
// calculate center point for the anchor
Vector3 center = vertices[0];
for (int i = 1; i < vertices.Count; i++)
{
center += vertices[i];
}
center /= 4;
this.transform.position = _blockDeform.GetPosition() + center + _blockDeform.GetRotation().normalized * _normal * _offset;
// calculate scale multiplier
Vector3 scaleVec = Quaternion.Inverse(_blockDeform.GetRotation().normalized) * (vertices[0] - center);
double epsilon = 0.1;
int zeroCntr = 0;
Vector3 newVertex = new(0, 0, 0);
for (int i = 0; i < 3; i++)
{
if (Math.Abs(_normal[i]) < epsilon && zeroCntr < 2)
{
newVertex[zeroCntr] = scaleVec[i];
zeroCntr++;
}
}
// Debug.Log(scaleVec.ToString() + " reordered: " + newVertex.ToString());
if (Math.Abs(scaleVec.x) < epsilon)
{
this.transform.localScale = new Vector3(Math.Abs(newVertex.y * 2), Math.Abs(newVertex.x * 2), 1);
}
else
this.transform.localScale = new Vector3(Math.Abs(newVertex.x * 2), Math.Abs(newVertex.y * 2), 1);
}
public Vector3 GetNormal()
{
return _normal;
}
public Vector3 GetPosition()
{
return _position.transform.position;
}
public void ResetPosition()
{
this.transform.position = _previousPosition + _blockDeform.GetRotation().normalized * _normal * _offset;
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Gizmos.DrawLine(transform.position, transform.position + (_blockDeform.GetRotation().normalized * _normal));
}
}