Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System.Collections.Generic;
- using Extensions;
- namespace Occlusion
- {
- // based on idWinding class from Doom 3 BFG source by ID
- public class ConvexPolygon
- {
- //public Plane plane;
- public List<Vector3> points = new List<Vector3>();
- public ConvexPolygon Clone()
- {
- return new ConvexPolygon() { points = new List<Vector3>(this.points) };
- }
- public void DebugOnTick()
- {
- DebugDrawLines(Color.blue);
- var oldPoints = this.points.ToArray();
- var planes = GeometryUtility.CalculateFrustumPlanes(Camera.main);
- var excludeNormal = Camera.main.transform.forward;
- foreach (var plane in planes)
- {
- var d = plane.normal.Dot(excludeNormal);
- if (d < 0.9f && d > -0.9f) Clip(plane);
- }
- DebugDrawLines(Color.red);
- points = new List<Vector3>(oldPoints);
- }
- public void DebugDrawLines(Color color = default(Color))
- {
- int numPoints = points.Count;
- for (int i = 0; i < numPoints; i++)
- {
- Debug.DrawLine(points[i], points[(i + 1) % numPoints], color);
- }
- }
- public bool Clip(Plane plane, float epsilon = 0.0f)
- {
- const int SIDE_BEHIND = 0;
- const int SIDE_FRONT = 1;
- const int SIDE_ON = 2;
- List<Vector3> newPoints = new List<Vector3>();
- int numPoints = points.Count;
- float dist = 0;
- int[] sides = new int[numPoints];
- float[] dists = new float[numPoints];
- int[] counts = new int[3];
- for (int i = 0; i < numPoints; i++)
- {
- dists[i] = dist = plane.GetDistanceToPoint(points[i]);
- if (dist > epsilon) sides[i] = SIDE_FRONT;
- else if (dist < -epsilon) sides[i] = SIDE_BEHIND;
- else sides[i] = SIDE_ON;
- counts[sides[i]]++;
- }
- // no point is clipped
- if (counts[SIDE_BEHIND] == 0) return true;
- if (counts[SIDE_FRONT] + counts[SIDE_ON] == 0) return false;
- for (int i = 0; i < numPoints; i++)
- {
- if (sides[i] == SIDE_BEHIND)
- {
- continue;
- }
- if (sides[i] == SIDE_FRONT || sides[i] == SIDE_ON)
- {
- newPoints.Add(points[i]);
- }
- int otherI;
- bool insertAtEnd = true;
- if (sides[otherI = (i + 1) % numPoints] == SIDE_BEHIND) insertAtEnd = true;
- else if (sides[otherI = (numPoints + i - 1) % numPoints] == SIDE_BEHIND) insertAtEnd = false;
- else continue;
- float t = dists[i] / (dists[i] - dists[otherI]);
- newPoints.Insert(
- insertAtEnd ? newPoints.Count : newPoints.Count - 1,
- points[i] * (1 - t) + points[otherI] * (t)
- );
- }
- points = newPoints;
- return true;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment