XZOrientedQuad3D.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #if UNITY_EDITOR
  2. using UnityEngine;
  3. using System;
  4. using System.Collections.Generic;
  5. namespace O3DWB
  6. {
  7. [Serializable]
  8. public class XZOrientedQuad3D
  9. {
  10. #region Private Variables
  11. [SerializeField]
  12. private Vector2 _xzSize = Vector2.zero;
  13. [SerializeField]
  14. private CoordinateSystem _coordinateSystem = new CoordinateSystem();
  15. #endregion
  16. #region Public Static Properties
  17. public static Vector3 ModelSpaceRightAxis { get { return Vector3.right; } }
  18. public static Vector3 ModelSpacePlaneNormal { get { return Vector3.up; } }
  19. public static Vector3 ModelSpaceLookAxis { get { return Vector3.forward; } }
  20. #endregion
  21. #region Public Properties
  22. public Vector2 ModelSpaceXZSize { get { return _xzSize; } set { _xzSize = value.GetVectorWithAbsoluteValueComponents(); } }
  23. public Vector2 ScaledXZSize { get { return new Vector2(_xzSize.x * _coordinateSystem.TransformMatrix.XScale, _xzSize.y * _coordinateSystem.TransformMatrix.ZScale); } }
  24. public float SizeOnBothXZAxes { set { _xzSize = new Vector2(value, value); } }
  25. public Vector2 ModelSpaceXZExtents { get { return ModelSpaceXZSize * 0.5f; } }
  26. public Vector2 ScaledXZExtents { get { return ScaledXZSize * 0.5f; } }
  27. public Quaternion Rotation { get { return _coordinateSystem.GetRotation(); } set { _coordinateSystem.SetRotation(value); } }
  28. public Vector3 Center
  29. {
  30. get { return _coordinateSystem.GetOriginPosition(); }
  31. set { _coordinateSystem.SetOriginPosition(value); }
  32. }
  33. public Plane Plane { get { return new Plane(_coordinateSystem.GetAxisVector(CoordinateSystemAxis.PositiveUp), Center); } }
  34. public TransformMatrix TransformMatrix { get { return _coordinateSystem.TransformMatrix; } }
  35. public float ScaledArea
  36. {
  37. get
  38. {
  39. Vector2 scaledXZSize = ScaledXZSize;
  40. return scaledXZSize.x * scaledXZSize.y;
  41. }
  42. }
  43. #endregion
  44. #region Constructors
  45. public XZOrientedQuad3D()
  46. {
  47. }
  48. public XZOrientedQuad3D(Vector3 center)
  49. {
  50. Center = center;
  51. }
  52. public XZOrientedQuad3D(Vector3 center, Vector2 xzSize)
  53. {
  54. Center = center;
  55. ModelSpaceXZSize = xzSize;
  56. }
  57. public XZOrientedQuad3D(Vector3 center, Vector2 xzSize, Quaternion rotation)
  58. {
  59. Center = center;
  60. ModelSpaceXZSize = xzSize;
  61. Rotation = rotation;
  62. }
  63. public XZOrientedQuad3D(XZOrientedQuad3D source)
  64. {
  65. Center = source.Center;
  66. ModelSpaceXZSize = source.ModelSpaceXZSize;
  67. Rotation = source.Rotation;
  68. }
  69. #endregion
  70. #region Public Methods
  71. public void Transform(TransformMatrix transformMatrix)
  72. {
  73. _coordinateSystem.Transform(transformMatrix);
  74. }
  75. public void SetScale(float scale)
  76. {
  77. _coordinateSystem.SetScaleOnAllAxes(scale);
  78. }
  79. public void SetScale(Vector3 scale)
  80. {
  81. _coordinateSystem.SetScale(scale);
  82. }
  83. public void FaceInOppositeDirection()
  84. {
  85. _coordinateSystem.InvertAxisScale(CoordinateSystemAxis.PositiveUp);
  86. }
  87. public void InheritCoordinateSystem(CoordinateSystem coordinateSystem)
  88. {
  89. _coordinateSystem.SetTransformMatrix(coordinateSystem.TransformMatrix);
  90. }
  91. public Vector3 GetLocalAxis(CoordinateSystemAxis axis)
  92. {
  93. return _coordinateSystem.GetAxisVector(axis);
  94. }
  95. public Vector3 GetOriginPosition()
  96. {
  97. return _coordinateSystem.GetOriginPosition();
  98. }
  99. public Quaternion GetRotation()
  100. {
  101. return _coordinateSystem.GetRotation();
  102. }
  103. public List<Vector3> GetCenterAndCornerPoints()
  104. {
  105. Vector3 center = Center;
  106. Vector2 scaledXZExtents = ScaledXZExtents;
  107. Vector3 rightAxis = GetLocalAxis(CoordinateSystemAxis.PositiveRight);
  108. Vector3 lookAxis = GetLocalAxis(CoordinateSystemAxis.PositiveLook);
  109. var centerAndCornerPoints = new Vector3[XZOrientedQuad3DPoints.Count];
  110. centerAndCornerPoints[(int)XZOrientedQuad3DPoint.Center] = center;
  111. centerAndCornerPoints[(int)XZOrientedQuad3DPoint.TopLeft] = center - rightAxis * scaledXZExtents.x + lookAxis * scaledXZExtents.y;
  112. centerAndCornerPoints[(int)XZOrientedQuad3DPoint.TopRight] = center + rightAxis * scaledXZExtents.x + lookAxis * scaledXZExtents.y;
  113. centerAndCornerPoints[(int)XZOrientedQuad3DPoint.BottomRight] = center + rightAxis * scaledXZExtents.x - lookAxis * scaledXZExtents.y;
  114. centerAndCornerPoints[(int)XZOrientedQuad3DPoint.BottomLeft] = center - rightAxis * scaledXZExtents.x - lookAxis * scaledXZExtents.y;
  115. return new List<Vector3>(centerAndCornerPoints);
  116. }
  117. public List<Vector3> GetMidEdgePoints()
  118. {
  119. List<Segment3D> edges = GetBoundarySegments();
  120. var midEdgePoints = new List<Vector3>();
  121. foreach(var edge in edges)
  122. {
  123. midEdgePoints.Add(edge.GetPoint(0.5f));
  124. }
  125. return midEdgePoints;
  126. }
  127. public List<Vector3> GetCornerPoints()
  128. {
  129. Vector3 center = Center;
  130. Vector2 scaledXZExtents = ScaledXZExtents;
  131. Vector3 rightAxis = GetLocalAxis(CoordinateSystemAxis.PositiveRight);
  132. Vector3 lookAxis = GetLocalAxis(CoordinateSystemAxis.PositiveLook);
  133. var cornerPoints = new Vector3[XZOrientedQuad3DCornerPoints.Count];
  134. cornerPoints[(int)XZOrientedQuad3DCornerPoint.TopLeft] = center - rightAxis * scaledXZExtents.x + lookAxis * scaledXZExtents.y;
  135. cornerPoints[(int)XZOrientedQuad3DCornerPoint.TopRight] = center + rightAxis * scaledXZExtents.x + lookAxis * scaledXZExtents.y;
  136. cornerPoints[(int)XZOrientedQuad3DCornerPoint.BottomRight] = center + rightAxis * scaledXZExtents.x - lookAxis * scaledXZExtents.y;
  137. cornerPoints[(int)XZOrientedQuad3DCornerPoint.BottomLeft] = center - rightAxis * scaledXZExtents.x - lookAxis * scaledXZExtents.y;
  138. return new List<Vector3>(cornerPoints);
  139. }
  140. public Vector3 GetPointClosestToPoint(Vector3 point, bool includeMidEdgePoints)
  141. {
  142. if (includeMidEdgePoints)
  143. {
  144. List<Vector3> points = GetCenterAndCornerPoints();
  145. points.AddRange(GetMidEdgePoints());
  146. return Vector3Extensions.GetClosestPointToPoint(points, point);
  147. }
  148. else return Vector3Extensions.GetClosestPointToPoint(GetCenterAndCornerPoints(), point);
  149. }
  150. public List<Segment3D> GetBoundarySegments()
  151. {
  152. return Vector3Extensions.GetSegmentsBetweenPoints(GetCornerPoints(), true);
  153. }
  154. public List<Plane> GetBoundarySegmentPlanesFacingOutward()
  155. {
  156. List<Segment3D> boundarySegments = GetBoundarySegments();
  157. List<Plane> segmentPlanes = new List<Plane>(boundarySegments.Count);
  158. Plane quadPlane = Plane;
  159. for(int segmentIndex = 0; segmentIndex < boundarySegments.Count; ++segmentIndex)
  160. {
  161. Segment3D segment = boundarySegments[segmentIndex];
  162. Vector3 planeNormal = Vector3.Cross(segment.Direction, quadPlane.normal);
  163. planeNormal.Normalize();
  164. segmentPlanes.Add(new Plane(planeNormal, segment.StartPoint));
  165. }
  166. return segmentPlanes;
  167. }
  168. #endregion
  169. }
  170. }
  171. #endif