Skip to content
Snippets Groups Projects
Select Git revision
  • 14a8891f077869243e3706f0035fa11cc3a5caa4
  • main default protected
2 results

control_mouse.py

Blame
  • BlockDeform.cs 7.00 KiB
    using System;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class BlockDeform : MonoBehaviour
    {
        public GameObject deformAnchorPrefab;
        public float wrapDistance;
    
        private Mesh _mesh;
        private readonly DeformAnchor[] _deformAnchors = new DeformAnchor[6];
        private readonly GameObject[] _spawnedAnchors = new GameObject[6];
    
        private bool loadedType = false;
    
        private bool IsPointOnPlane(Vector3 point, Vector3 normal, Vector3 pointOnPlane, double epsilon)
        {
            double d = Vector3.Dot(normal, pointOnPlane);
            double eq = normal.x * point.x + normal.y * point.y + normal.z * point.z - d;
    
            if (Math.Abs(eq) < epsilon) return true;
            else return false;
        }
    
        public void HandleAnchorGrabbed(Transform endPosition, Vector3 startPosition, DeformAnchor anchor)
        {
            Vector3 normal = this.transform.rotation.normalized * anchor.GetNormal();
    
            // calculate deformation
            Vector3[] deformedMeshVertices = _mesh.vertices;
            for (int i = 0; i < deformedMeshVertices.Length; i++)
            {
                Vector3 vertex = (this.transform.rotation.normalized * deformedMeshVertices[i]) + this.transform.position;
                if (IsPointOnPlane(vertex, normal, startPosition, 0.1d))
                {
                    float distance = Vector3.Distance(startPosition, endPosition.position);
    
                    // Vector3 displacement = endPosition.position - startPosition;
                    // deformedMeshVertices[i] += displacement;
                    // Debug.Log("startpos: " + startPosition + " normal: " + normal + " vertex: " + vertex);
    
                    Vector3 displacement = anchor.GetNormal() * distance;
                    float direction = Vector3.Dot(endPosition.position - startPosition, normal);
                    deformedMeshVertices[i] += displacement * (direction > 0 ? 1 : -1);
                }
                else
                {
                    // Debug.LogError("startpos: " + startPosition + " normal: " + normal + " vertex: " + vertex);
                }
            }
    
            // check if it's a valid grab
            for (int i = 0; i < _deformAnchors.Length; i++)
            {
                if (_deformAnchors[i] == anchor) continue;
    
                float distance = Vector3.Distance(_deformAnchors[i].GetPosition(), anchor.GetPosition());
                if (distance < wrapDistance * 10)
                {
                    anchor.ResetPosition();
                    return;
                }
            }
    
            // set new vertices for mesh
            _mesh.vertices = deformedMeshVertices;
            _mesh.RecalculateBounds();
            MeshCollider collider = GetComponent<MeshCollider>();
            collider.sharedMesh = _mesh;
    
            UpdateDeformAnchors();
        }
    
    
    
        private void UpdateDeformAnchors()
        {
            // collect vertices on the same plane as the anchor
            for (int i = 0; i < _deformAnchors.Length; i++)
            {
                List<Vector3> vertices = new();
    
                Vector3 anchorNormal = this.transform.rotation.normalized * _deformAnchors[i].GetNormal();
                Vector3 anchorPosition = _deformAnchors[i].GetPosition();
    
                foreach (Vector3 vertex in _mesh.vertices)
                {
                    Vector3 rotatedVert = this.transform.rotation.normalized * vertex;
                    if (IsPointOnPlane(rotatedVert + this.transform.position, anchorNormal, anchorPosition, 0.1d))
                    {
                        if (vertices.IndexOf(rotatedVert) == -1)
                        {
                            vertices.Add(rotatedVert);
                        }
                    }
                }
    
                if (vertices.Count >= 4)
                    _deformAnchors[i].SetMeshScale(vertices);
                else
                    Debug.LogError("Couldn't find fitting vertices to update the deform anchors.");
            }
        }
    
        private void Awake()
        {
            _mesh = this.GetComponent<MeshFilter>().mesh;
        }
    
        // Start is called before the first frame update
        void Start()
        {
            if (!this.loadedType)
                InitAnchors();
        }
    
        private void InitAnchors()
        {
            Collider blockCollider = this.GetComponent<Collider>();
    
            for (int i = 0; i < 6; i++)
            {
                GameObject anchor = Instantiate(deformAnchorPrefab, this.transform.position, Quaternion.identity);
                anchor.transform.parent = this.transform;
                _deformAnchors[i] = anchor.GetComponent<DeformAnchor>();
                _spawnedAnchors[i] = anchor;
            }
    
            // z axis anchor setup
            _deformAnchors[0].SetupAnchor(this, this.transform.forward, blockCollider.bounds.extents, wrapDistance);
            _deformAnchors[1].SetupAnchor(this, -this.transform.forward, blockCollider.bounds.extents, wrapDistance);
    
            // y axis achor setup
            _deformAnchors[2].SetupAnchor(this, this.transform.up, blockCollider.bounds.extents, wrapDistance);
            _deformAnchors[3].SetupAnchor(this, -this.transform.up, blockCollider.bounds.extents, wrapDistance);
    
            // x axis anchor setup
            _deformAnchors[4].SetupAnchor(this, this.transform.right, blockCollider.bounds.extents, wrapDistance);
            _deformAnchors[5].SetupAnchor(this, -this.transform.right, blockCollider.bounds.extents, wrapDistance);
        }
    
        public void AdjustVertices(Vector3[] vertices, Vector3[] anchorPosition)
        {
            this.loadedType = true;
            InitAnchors();
    
            _mesh = this.GetComponent<MeshFilter>().mesh;
            if (_mesh.vertices.Length != vertices.Length)
            {
                Debug.LogError("cannot adjust vertices: different sized vertex arrays");
                return;
            }
    
            Vector3[] adjustedVertices = _mesh.vertices;
            for (int i = 0; i < adjustedVertices.Length; i++)
            {
                adjustedVertices[i] = vertices[i];
            }
    
            _mesh.vertices = adjustedVertices;
            _mesh.RecalculateBounds();
            MeshCollider collider = GetComponent<MeshCollider>();
            collider.sharedMesh = _mesh;
    
            for (int i = 0; i < _spawnedAnchors.Length; i++)
            {
                _spawnedAnchors[i].transform.localPosition = anchorPosition[i];
            }
    
            UpdateDeformAnchors();
        }
    
        private void FixedUpdate()
        {
            EditState.EditType mode = EditState.Instance._editState;
            foreach (GameObject anchor in _spawnedAnchors)
            {
                anchor.SetActive(mode == EditState.EditType.Deform);
            }
        }
    
        public GameObject[] GetAnchors()
        {
            return _spawnedAnchors;
        }
    
        public Vector3 GetPosition()
        {
            return transform.position;
        }
    
        public Quaternion GetRotation()
        {
            return transform.rotation;
        }
    
    
        public void EnableTransparency()
        {
            Color color = transform.GetComponent<Renderer>().material.GetColor("_BaseColor");
            // color.a = grabTransparency;
            transform.GetComponent<Renderer>().material.SetColor("_BaseColor", color);
        }
    
        public void DisableTransparency()
        {
            Color color = transform.GetComponent<Renderer>().material.GetColor("_BaseColor");
            color.a = 1.0f;
            transform.GetComponent<Renderer>().material.SetColor("_BaseColor", color);
        }
    }