aeroson

C# Occlusion.ConvexPolygon

Nov 8th, 2014
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.24 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using Extensions;
  4.  
  5. namespace Occlusion
  6. {
  7. // based on idWinding class from Doom 3 BFG source by ID
  8. public class ConvexPolygon
  9. {
  10. //public Plane plane;
  11. public List<Vector3> points = new List<Vector3>();
  12.  
  13. public ConvexPolygon Clone()
  14. {
  15. return new ConvexPolygon() { points = new List<Vector3>(this.points) };
  16. }
  17.  
  18. public void DebugOnTick()
  19. {
  20. DebugDrawLines(Color.blue);
  21. var oldPoints = this.points.ToArray();
  22. var planes = GeometryUtility.CalculateFrustumPlanes(Camera.main);
  23. var excludeNormal = Camera.main.transform.forward;
  24. foreach (var plane in planes)
  25. {
  26. var d = plane.normal.Dot(excludeNormal);
  27. if (d < 0.9f && d > -0.9f) Clip(plane);
  28. }
  29. DebugDrawLines(Color.red);
  30. points = new List<Vector3>(oldPoints);
  31. }
  32.  
  33.  
  34. public void DebugDrawLines(Color color = default(Color))
  35. {
  36. int numPoints = points.Count;
  37. for (int i = 0; i < numPoints; i++)
  38. {
  39. Debug.DrawLine(points[i], points[(i + 1) % numPoints], color);
  40. }
  41. }
  42.  
  43. public bool Clip(Plane plane, float epsilon = 0.0f)
  44. {
  45. const int SIDE_BEHIND = 0;
  46. const int SIDE_FRONT = 1;
  47. const int SIDE_ON = 2;
  48.  
  49. List<Vector3> newPoints = new List<Vector3>();
  50. int numPoints = points.Count;
  51.  
  52. float dist = 0;
  53. int[] sides = new int[numPoints];
  54. float[] dists = new float[numPoints];
  55. int[] counts = new int[3];
  56.  
  57. for (int i = 0; i < numPoints; i++)
  58. {
  59. dists[i] = dist = plane.GetDistanceToPoint(points[i]);
  60. if (dist > epsilon) sides[i] = SIDE_FRONT;
  61. else if (dist < -epsilon) sides[i] = SIDE_BEHIND;
  62. else sides[i] = SIDE_ON;
  63. counts[sides[i]]++;
  64. }
  65.  
  66. // no point is clipped
  67. if (counts[SIDE_BEHIND] == 0) return true;
  68. if (counts[SIDE_FRONT] + counts[SIDE_ON] == 0) return false;
  69.  
  70. for (int i = 0; i < numPoints; i++)
  71. {
  72. if (sides[i] == SIDE_BEHIND)
  73. {
  74. continue;
  75. }
  76.  
  77. if (sides[i] == SIDE_FRONT || sides[i] == SIDE_ON)
  78. {
  79. newPoints.Add(points[i]);
  80. }
  81.  
  82. int otherI;
  83. bool insertAtEnd = true;
  84.  
  85. if (sides[otherI = (i + 1) % numPoints] == SIDE_BEHIND) insertAtEnd = true;
  86. else if (sides[otherI = (numPoints + i - 1) % numPoints] == SIDE_BEHIND) insertAtEnd = false;
  87. else continue;
  88.  
  89. float t = dists[i] / (dists[i] - dists[otherI]);
  90.  
  91. newPoints.Insert(
  92. insertAtEnd ? newPoints.Count : newPoints.Count - 1,
  93. points[i] * (1 - t) + points[otherI] * (t)
  94. );
  95.  
  96. }
  97.  
  98. points = newPoints;
  99. return true;
  100.  
  101. }
  102.  
  103. }
  104.  
  105.  
  106. }
Advertisement
Add Comment
Please, Sign In to add comment