Optimized FOV Representation
This commit is contained in:
@@ -18,6 +18,9 @@ public class FieldOfView : MonoBehaviour
|
||||
public LayerMask obstacleMask;
|
||||
|
||||
public float meshResolution;
|
||||
public int edgeResolveIterations;
|
||||
public float edgeDistanceThreshold;
|
||||
|
||||
public MeshFilter periMeshFilter;
|
||||
public MeshFilter foveaMeshFilter;
|
||||
private Mesh periMesh;
|
||||
@@ -73,9 +76,10 @@ public class FieldOfView : MonoBehaviour
|
||||
|
||||
void DrawFOV(float startAngle, Mesh viewMesh, float viewAngle)
|
||||
{
|
||||
int stepCount = Mathf.RoundToInt(foveaAngle * meshResolution);
|
||||
int stepCount = Mathf.RoundToInt(viewAngle * meshResolution);
|
||||
float stepAngleSize = viewAngle / stepCount;
|
||||
List<Vector3> viewPoints = new List<Vector3>();
|
||||
ViewCastInfo oldViewCast = new ViewCastInfo();
|
||||
|
||||
for (int i = 0; i <= stepCount; i++)
|
||||
{
|
||||
@@ -84,7 +88,25 @@ public class FieldOfView : MonoBehaviour
|
||||
Debug.DrawLine(transform.position, transform.position + DirFromAngle(angle, true) * viewRadius, Color.red);
|
||||
|
||||
ViewCastInfo newViewCast = ViewCast(angle);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
bool edgeDistThresholdExeeded = Mathf.Abs(oldViewCast.distance - newViewCast.distance) > edgeDistanceThreshold;
|
||||
if (oldViewCast.didHit != newViewCast.didHit || (oldViewCast.didHit && newViewCast.didHit && edgeDistThresholdExeeded))
|
||||
{
|
||||
EdgeInfo edge = FingEdge(oldViewCast, newViewCast);
|
||||
if (edge.pointmin != Vector3.zero)
|
||||
{
|
||||
viewPoints.Add(edge.pointmin);
|
||||
}
|
||||
if (edge.pointmax != Vector3.zero)
|
||||
{
|
||||
viewPoints.Add(edge.pointmax);
|
||||
}
|
||||
}
|
||||
}
|
||||
viewPoints.Add(newViewCast.hitPoint);
|
||||
oldViewCast = newViewCast;
|
||||
}
|
||||
|
||||
int vertexcount = viewPoints.Count + 1;
|
||||
@@ -141,4 +163,44 @@ public class FieldOfView : MonoBehaviour
|
||||
angle = _angle;
|
||||
}
|
||||
}
|
||||
|
||||
public struct EdgeInfo
|
||||
{
|
||||
public Vector3 pointmin;
|
||||
public Vector3 pointmax;
|
||||
|
||||
public EdgeInfo(Vector3 _pointmin, Vector3 _pointmax)
|
||||
{
|
||||
pointmin = _pointmin;
|
||||
pointmax = _pointmax;
|
||||
}
|
||||
}
|
||||
|
||||
EdgeInfo FingEdge(ViewCastInfo minViewCast, ViewCastInfo maxViewCast)
|
||||
{
|
||||
float minAngle = minViewCast.angle;
|
||||
float maxAngle = maxViewCast.angle;
|
||||
Vector3 minPoint = Vector3.zero;
|
||||
Vector3 maxPoint = Vector3.zero;
|
||||
|
||||
for (int i = 0; i < edgeResolveIterations; i++)
|
||||
{
|
||||
float angle = (minAngle + maxAngle) / 2;
|
||||
ViewCastInfo newViewCast = ViewCast(angle);
|
||||
|
||||
bool edgeDistThresholdExeeded = Mathf.Abs(minViewCast.distance - newViewCast.distance) > edgeDistanceThreshold;
|
||||
if (newViewCast.didHit == minViewCast.didHit && !edgeDistThresholdExeeded)
|
||||
{
|
||||
minAngle = angle;
|
||||
minPoint = newViewCast.hitPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxAngle = angle;
|
||||
maxPoint = newViewCast.hitPoint;
|
||||
}
|
||||
}
|
||||
|
||||
return new EdgeInfo(minPoint, maxPoint);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user