Skip to content
Snippets Groups Projects
Select Git revision
  • 77800ef98d24cfa3eb82ed00b74c42862ce5e04f
  • master default protected
2 results

DeformAnchor.cs

Blame
  • 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));
        }
    }