using o0.Geometry2D.Float; using System; using System.Diagnostics; using UnityEngine; namespace ZIM.Unity { // 记录屏幕的位置,Quad表示屏幕4个点的坐标 // TransformToScreen可将摄像机空间的点映射到屏幕空间,反之用TransformToCamera public class ScreenMap { public Rect QuadRect { get; private set; } public Vector2 UVSize { get; private set; } // UV代表屏幕空间的坐标,UVSize代表屏幕坐标的取值范围 public bool Active => quad != null; public Quadrilateral Quad { get => quad; set { quad = value; if (value != null) { var x = Math.Min((value.A - value.B).Length, (value.C - value.D).Length); var y = Math.Min((value.A - value.C).Length, (value.B - value.D).Length); UVSize = new Vector2(x, y); perspective = new PerspectiveTransform(value, new Quadrilateral(new Vector(0, 0), new Vector(x, 0), new Vector(0, y), new Vector(x, y))); var aabb = value.AABBRect(); QuadRect = new Rect(aabb.Item1.x, aabb.Item1.y, aabb.Item2.x - aabb.Item1.x, aabb.Item2.y - aabb.Item1.y); //Debug.Log(QuadRect); } } } Quadrilateral quad; PerspectiveTransform perspective; public ScreenMap() { } public ScreenMap(Quadrilateral quad) { Quad = quad; } public bool UVInScreen(Vector2 v) { return v.x > 0 && v.x < UVSize.x && v.y > 0 && v.y < UVSize.y; } // UV归一化到[0, 1]范围,仅用于输出最终结果 public Vector2 UVNormalize(Vector2 location) { return new Vector2(location.x / UVSize.x, location.y / UVSize.y); } public Vector2 TransformToScreen(Vector2 vIn) { var v = perspective.Transform(vIn.x, vIn.y); return new Vector2(v.x, v.y); } public Vector2 TransformToCamera(Vector2 vIn) { var v = perspective.TransformInverse(vIn.x, vIn.y); return new Vector2(v.x, v.y); } } }