QuadrilateralInCamera.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using System;
  2. using System.Collections.Generic;
  3. using o0.Geometry2D;
  4. using o0.Geometry2D.Float;
  5. using UnityEngine;
  6. namespace ZIM.Unity
  7. {
  8. // 屏幕识别使用,记录摄像机画面内的四边形
  9. public class QuadrilateralInCamera
  10. {
  11. public Vector CameraSize;
  12. public OrdinalQuadrilateral Quad;
  13. // 固定的顶点顺序: 左下,右下,左上,右上
  14. public QuadrilateralInCamera(Vector2 a, Vector2 b, Vector2 c, Vector2 d, Vector2 cameraSize)
  15. {
  16. CameraSize = cameraSize.o0Vector();
  17. Quad = new OrdinalQuadrilateral(a.o0Vector(), b.o0Vector(), c.o0Vector(), d.o0Vector());
  18. }
  19. // 固定的顶点顺序: 左下,右下,左上,右上
  20. public QuadrilateralInCamera(Vector a, Vector b, Vector c, Vector d, Vector cameraSize)
  21. {
  22. CameraSize = cameraSize;
  23. Quad = new OrdinalQuadrilateral(a, b, c, d);
  24. }
  25. // 固定的顶点顺序: 左下,右下,左上,右上
  26. public QuadrilateralInCamera(IEnumerable<Vector> enumable, Vector cameraSize)
  27. {
  28. CameraSize = cameraSize;
  29. Quad = new OrdinalQuadrilateral(enumable);
  30. }
  31. public QuadrilateralInCamera(OrdinalQuadrilateral quad, Vector cameraSize)
  32. {
  33. CameraSize = cameraSize;
  34. Quad = quad;
  35. }
  36. // 需要标准化的坐标(即数值范围0-1)时使用,会自动根据当前的CameraSize转换
  37. private List<Vector> ScreenVertexListNormalized
  38. {
  39. get
  40. {
  41. return new List<Vector> {
  42. Quad.A / CameraSize,
  43. Quad.B / CameraSize,
  44. Quad.C / CameraSize,
  45. Quad.D / CameraSize
  46. };
  47. }
  48. set
  49. {
  50. for (int i = 0; i < Quad.Count; i++)
  51. Quad[i] = value[i] * CameraSize;
  52. }
  53. }
  54. // 这里是标准化坐标(即数值范围0-1)
  55. public List<Vector2> GetUnityVertexList()
  56. {
  57. return new List<Vector2>() {
  58. new Vector2(Quad.A.x / CameraSize.x, Quad.A.y / CameraSize.y),
  59. new Vector2(Quad.B.x / CameraSize.x, Quad.B.y / CameraSize.y),
  60. new Vector2(Quad.C.x / CameraSize.x, Quad.C.y / CameraSize.y),
  61. new Vector2(Quad.D.x / CameraSize.x, Quad.D.y / CameraSize.y)
  62. };
  63. }
  64. // 摄像机分辨率变化时调用
  65. public void ReSize(Vector sizeNew, AspectRatioSetting viewAspectRatioSetting)
  66. {
  67. float ratio;
  68. Func<Vector, Vector> Translate;
  69. List<Vector> vertices;
  70. switch (viewAspectRatioSetting)
  71. {
  72. case AspectRatioSetting.FixedAll:
  73. var scale = new Vector(sizeNew.x / CameraSize.x, sizeNew.y / CameraSize.y);
  74. CameraSize = sizeNew;
  75. for (int i = 0; i < Quad.Count; i++)
  76. Quad[i] *= scale;
  77. break;
  78. case AspectRatioSetting.FixedHeight:
  79. var wOld = CameraSize.x / CameraSize.y; // 宽度比高度
  80. var wNew = sizeNew.x / sizeNew.y;
  81. ratio = wOld / wNew;
  82. Translate = (v) =>
  83. {
  84. var x = v.x - 0.5f;
  85. return new Vector(x * ratio + 0.5f, v.y);
  86. };
  87. vertices = ScreenVertexListNormalized;
  88. for (int i = 0; i < vertices.Count; i++)
  89. vertices[i] = Translate(vertices[i]);
  90. CameraSize = sizeNew; // 这里要先设置Size
  91. ScreenVertexListNormalized = vertices;
  92. break;
  93. case AspectRatioSetting.FixedWidth:
  94. var hOld = CameraSize.y / CameraSize.x; // 高度比宽度
  95. var hNew = sizeNew.y / sizeNew.x;
  96. ratio = hOld / hNew;
  97. Translate = (v) =>
  98. {
  99. var y = v.y - 0.5f;
  100. return new Vector(v.x, y * ratio + 0.5f);
  101. };
  102. vertices = ScreenVertexListNormalized;
  103. for (int i = 0; i < vertices.Count; i++)
  104. vertices[i] = Translate(vertices[i]);
  105. CameraSize = sizeNew;
  106. ScreenVertexListNormalized = vertices;
  107. break;
  108. }
  109. }
  110. // 四边形是否完整的在屏幕内
  111. public bool IsQuadComplete()
  112. {
  113. 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 &&
  114. 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)
  115. return true;
  116. return false;
  117. }
  118. }
  119. }