ScreenMap.cs 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using o0.Geometry2D.Float;
  2. using System;
  3. using UnityEngine;
  4. namespace ZIM.Unity
  5. {
  6. // 记录屏幕的位置,QuadInCamera表示屏幕4个点在摄像机画面中的坐标
  7. // TransformToScreen可将摄像机空间的点映射到屏幕空间,反之用TransformToCamera
  8. public class ScreenMap
  9. {
  10. public Rect QuadRect { get; private set; }
  11. public Vector2 UVSize { get; private set; } // UV代表屏幕空间的坐标,UVSize代表屏幕坐标的取值范围
  12. public bool Active => quadInCamera != null;
  13. QuadrilateralInCamera quadInCamera; // 记录的分辨率和识别时的分辨率可能不同
  14. public QuadrilateralInCamera QuadInCamera
  15. {
  16. get => quadInCamera;
  17. set
  18. {
  19. quadInCamera = value;
  20. if (value != null)
  21. {
  22. var quad = value.Quad;
  23. var x = Math.Min((quad.A - quad.B).Length, (quad.C - quad.D).Length);
  24. var y = Math.Min((quad.A - quad.C).Length, (quad.B - quad.D).Length);
  25. UVSize = new Vector2(x, y);
  26. perspective = new ZIMPerspectiveTransform(quad, new OrdinalQuadrilateral2(new Vector(0, 0), new Vector(x, 0), new Vector(0, y), new Vector(x, y)));
  27. var aabb = quad.AABBRect();
  28. QuadRect = new Rect(aabb.Item1.x, aabb.Item1.y, aabb.Item2.x - aabb.Item1.x, aabb.Item2.y - aabb.Item1.y);
  29. //Debug.Log(QuadRect);
  30. }
  31. }
  32. }
  33. // 刷新分辨率
  34. public Vector2 CurCameraSize
  35. {
  36. get => QuadInCamera.CameraSize;
  37. set
  38. {
  39. if (QuadInCamera != null && QuadInCamera.CameraSize != value)
  40. {
  41. UnityEngine.Debug.Log("[ScreenMap]根据分辨率映射: from " + QuadInCamera.CameraSize + " to " + value);
  42. var scale = new o0.Geometry2D.Float.Vector(value.x / QuadInCamera.CameraSize.x, value.y / QuadInCamera.CameraSize.y);
  43. var quad = QuadInCamera.Quad;
  44. quad.Scale(scale);
  45. QuadInCamera = new QuadrilateralInCamera(quad, value);
  46. }
  47. }
  48. }
  49. ZIMPerspectiveTransform perspective;
  50. public ScreenMap()
  51. {
  52. }
  53. public ScreenMap(QuadrilateralInCamera quad)
  54. {
  55. QuadInCamera = quad;
  56. }
  57. public bool UVInScreen(Vector2 v)
  58. {
  59. return v.x > 0 && v.x < UVSize.x && v.y > 0 && v.y < UVSize.y;
  60. }
  61. // UV归一化到[0, 1]范围,仅用于输出最终结果
  62. public Vector2 UVNormalize(Vector2 location)
  63. {
  64. return new Vector2(location.x / UVSize.x, location.y / UVSize.y);
  65. }
  66. public Vector2 TransformToScreen(Vector2 vIn)
  67. {
  68. var v = perspective.Transform(vIn.x, vIn.y);
  69. return new Vector2(v.x, v.y);
  70. }
  71. public Vector2 TransformToCamera(Vector2 vIn)
  72. {
  73. var v = perspective.TransformInverse(vIn.x, vIn.y);
  74. return new Vector2(v.x, v.y);
  75. }
  76. }
  77. }