| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using o0.Geometry2D;
- using o0.Geometry2D.Float;
- using UnityEngine;
- namespace ZIM.Unity
- {
- // 屏幕识别使用,记录摄像机画面内的四边形
- public class QuadrilateralInCamera
- {
- public Vector CameraSize;
- public OrdinalQuadrilateral Quad;
- // 固定的顶点顺序: 左下,右下,左上,右上
- public QuadrilateralInCamera(Vector2 a, Vector2 b, Vector2 c, Vector2 d, Vector2 cameraSize)
- {
- CameraSize = cameraSize.o0Vector();
- Quad = new OrdinalQuadrilateral(a.o0Vector(), b.o0Vector(), c.o0Vector(), d.o0Vector());
- }
- // 固定的顶点顺序: 左下,右下,左上,右上
- public QuadrilateralInCamera(Vector a, Vector b, Vector c, Vector d, Vector cameraSize)
- {
- CameraSize = cameraSize;
- Quad = new OrdinalQuadrilateral(a, b, c, d);
- }
- // 固定的顶点顺序: 左下,右下,左上,右上
- public QuadrilateralInCamera(IEnumerable<Vector> enumable, Vector cameraSize)
- {
- CameraSize = cameraSize;
- Quad = new OrdinalQuadrilateral(enumable);
- }
- // 固定的顶点顺序: 左下,右下,左上,右上
- public QuadrilateralInCamera(IEnumerable<Vector2> enumable, Vector cameraSize)
- {
- CameraSize = cameraSize;
- Quad = new OrdinalQuadrilateral(enumable.Select((i => i.o0Vector())));
- }
- public QuadrilateralInCamera(OrdinalQuadrilateral quad, Vector cameraSize)
- {
- CameraSize = cameraSize;
- Quad = quad;
- }
- public string SizeString => $"({CameraSize.x}, {CameraSize.y})";
- public string QuadString => $"[({Quad.A.x}, {Quad.A.y}), ({Quad.B.x}, {Quad.B.y}), ({Quad.C.x}, {Quad.C.y}), ({Quad.D.x}, {Quad.D.y})]";
- public override string ToString() => $"CameraSize: {SizeString}, Vertices: {QuadString}";
- // 需要标准化的坐标(即数值范围0-1)时使用,会自动根据当前的CameraSize转换
- private List<Vector> ScreenVertexListNormalized
- {
- get
- {
- return new List<Vector> {
- Quad.A / CameraSize,
- Quad.B / CameraSize,
- Quad.C / CameraSize,
- Quad.D / CameraSize
- };
- }
- set
- {
- for (int i = 0; i < Quad.Count; i++)
- Quad[i] = value[i] * CameraSize;
- }
- }
- // 这里是标准化坐标(即数值范围0-1)
- public List<Vector2> GetUnityVertexNormalizedList()
- {
- return new List<Vector2>() {
- new Vector2(Quad.A.x / CameraSize.x, Quad.A.y / CameraSize.y),
- new Vector2(Quad.B.x / CameraSize.x, Quad.B.y / CameraSize.y),
- new Vector2(Quad.C.x / CameraSize.x, Quad.C.y / CameraSize.y),
- new Vector2(Quad.D.x / CameraSize.x, Quad.D.y / CameraSize.y)
- };
- }
- // 线段顺序: 下、右、上、左
- public Line[] GetLines() => new Line[4]
- {
- new Line(Quad.A, Quad.B),
- new Line(Quad.B, Quad.D),
- new Line(Quad.C, Quad.D),
- new Line(Quad.A, Quad.C)
- };
- // 摄像机分辨率变化时调用
- public void ReSize(Vector sizeNew, AspectRatioSetting viewAspectRatioSetting)
- {
- if (CameraSize != sizeNew)
- {
- float ratio;
- Func<Vector, Vector> Translate;
- List<Vector> vertices;
- switch (viewAspectRatioSetting)
- {
- case AspectRatioSetting.FixedAll:
- var scale = new Vector(sizeNew.x / CameraSize.x, sizeNew.y / CameraSize.y);
- CameraSize = sizeNew;
- for (int i = 0; i < Quad.Count; i++)
- Quad[i] *= scale;
- break;
- case AspectRatioSetting.FixedHeight:
- var wOld = CameraSize.x / CameraSize.y; // 宽度比高度
- var wNew = sizeNew.x / sizeNew.y;
- ratio = wOld / wNew;
- Translate = (v) =>
- {
- var x = v.x - 0.5f;
- return new Vector(x * ratio + 0.5f, v.y);
- };
- vertices = ScreenVertexListNormalized;
- for (int i = 0; i < vertices.Count; i++)
- vertices[i] = Translate(vertices[i]);
- CameraSize = sizeNew; // 这里要先设置Size
- ScreenVertexListNormalized = vertices;
- break;
- case AspectRatioSetting.FixedWidth:
- var hOld = CameraSize.y / CameraSize.x; // 高度比宽度
- var hNew = sizeNew.y / sizeNew.x;
- ratio = hOld / hNew;
- Translate = (v) =>
- {
- var y = v.y - 0.5f;
- return new Vector(v.x, y * ratio + 0.5f);
- };
- vertices = ScreenVertexListNormalized;
- for (int i = 0; i < vertices.Count; i++)
- vertices[i] = Translate(vertices[i]);
- CameraSize = sizeNew;
- ScreenVertexListNormalized = vertices;
- break;
- }
- }
- }
- // 四边形是否完整的在屏幕内
- public bool IsQuadComplete()
- {
- if (Quad.A.x < Quad.B.x && Quad.A.y < Quad.C.y && Quad.B.y < Quad.D.y && Quad.C.x < Quad.D.x && Quad.A.x > 0 && Quad.A.y > 0 &&
- Quad.B.x < CameraSize.x && Quad.B.y > 0 && Quad.C.x > 0 && Quad.C.y < CameraSize.y && Quad.D.x < CameraSize.x && Quad.D.y < CameraSize.y)
- return true;
- return false;
- }
- }
- }
|