KITASENJU DESIGN BLOG

memo, html, javascript, unity

台形補正

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MeshTest : MonoBehaviour
{
    [SerializeField] private MeshFilter _meshFilter;
    [SerializeField] private MeshRenderer _meshRenderer;
    [SerializeField] private GameObject _prefab;
    private Dictionary<string,GameObject> _balls;
    [SerializeField] private int _vertCount;
    [SerializeField] private int _numX=11;
    [SerializeField] private int _numY=11;

    [SerializeField] private Transform _pointA;
    [SerializeField] private Transform _pointB;
    [SerializeField] private Transform _pointC;
    [SerializeField] private Transform _pointD;
    private Mesh _mesh;
    

    // Start is called before the first frame update
    void Start()
    {
        _balls = new Dictionary<string,GameObject>();
        _vertCount=_meshFilter.mesh.vertexCount;
        for(int i=0;i<_meshFilter.mesh.vertexCount;i++){

            var b = Instantiate(_prefab,transform,false);
            int ix = i%_numX;
            int iy = Mathf.FloorToInt(i/_numX);
            b.name = GetIndex(ix,iy);

            _balls[b.name] = b;

        }
        _prefab.gameObject.SetActive(false);

    }

    private string GetIndex(int ix, int iy){
        
        return ix.ToString("00") +"x"+ iy.ToString("00");

    }

    // Update is called once per frame
    void Update()
    {
        
        //if(Input.GetKeyDown(KeyCode.UpArrow)){
        if(true){
            
            if(_mesh==null)_mesh = MeshUtils.CloneMesh(_meshFilter.sharedMesh,"mesh");

            var m = _mesh;

            var points = m.vertices;
            for(int j=0;j<_numY;j++){
                for(int i=0;i<_numX;i++){
    
                    var b = _balls[GetIndex(i,j)];
                    
                    var ratioX = (float)i/(float)(_numX-1);
                    var ratioY = (float)j/(float)(_numY-1);

                    var top     = Vector3.Lerp(_pointA.position,_pointB.position,ratioX);
                    var bottom  = Vector3.Lerp(_pointD.position,_pointC.position,ratioX);

                    var left    = Vector3.Lerp(_pointA.position,_pointD.position,ratioY);
                    var right   = Vector3.Lerp(_pointB.position,_pointC.position,ratioY);

                    Vector2 intersection = new Vector2(0,0);
                    
                    LineSegmentsIntersection(
                        new Vector2(top.x,top.y),
                        new Vector2(bottom.x,bottom.y),
                        new Vector2(left.x,left.y),
                        new Vector2(right.x,right.y),
                        out intersection
                    );

                    b.transform.position = new Vector3(
                        intersection.x,
                        intersection.y,
                        0
                    );

                    points[j*_numY+i%_numX] = b.transform.position;
 
                }
            }
            m.vertices = points;

            _meshFilter.sharedMesh = m;

        }

    }

    public static bool LineSegmentsIntersection(
        Vector2 p1,
        Vector2 p2,
        Vector2 p3,
        Vector2 p4,
        out Vector2 intersection)
    {
        intersection = Vector2.zero;

        var d = (p2.x - p1.x) * (p4.y - p3.y) - (p2.y - p1.y) * (p4.x - p3.x);

        if (d == 0.0f)
        {
            return false;
        }

        var u = ((p3.x - p1.x) * (p4.y - p3.y) - (p3.y - p1.y) * (p4.x - p3.x)) / d;
        var v = ((p3.x - p1.x) * (p2.y - p1.y) - (p3.y - p1.y) * (p2.x - p1.x)) / d;

        //if (u < 0.0f || u > 1.0f || v < 0.0f || v > 1.0f)
        //{
        //    return false;
        //}

        intersection.x = p1.x + u * (p2.x - p1.x);
        intersection.y = p1.y + u * (p2.y - p1.y);

        return true;
    }


}

"FOOTER"