edgeInfo FindEdge(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 edgeDstThresholdExceeded = Mathf.Abs(minViewCast.dst - newViewCast.dst) > edgeDstThreshold; if (newViewCast.hit == minViewCast.hit && !edgeDstThresholdExceeded) { minAngle = angle; minPoint = newViewCast.point; } else { maxAngle = angle; maxPoint = newViewCast.point; } } return(new edgeInfo(minPoint, maxPoint)); }
void drawFieldOfView() { 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++) { float angle = transform.eulerAngles.y - viewAngle / 2 + stepAngleSize * i; viewCastInfo newViewCast = viewCast(angle); if (i > 0) { bool edgeDstThresholdExceeded = Mathf.Abs(oldViewCast.dst - newViewCast.dst) > edgeDstThreshold; if (oldViewCast.hit != newViewCast.hit || (oldViewCast.hit && newViewCast.hit && edgeDstThresholdExceeded)) { edgeInfo edge = FindEdge(oldViewCast, newViewCast); if (edge.pointA != Vector3.zero) { viewPoints.Add(edge.pointA); } if (edge.pointB != Vector3.zero) { viewPoints.Add(edge.pointB); } } } viewPoints.Add(newViewCast.point); oldViewCast = newViewCast; } int vertexCount = viewPoints.Count + 1; Vector3[] vertices = new Vector3[vertexCount]; int[] triangles = new int[(vertexCount - 2) * 3]; vertices [0] = Vector3.zero; for (int i = 0; i < vertexCount - 1; i++) { vertices [i + 1] = transform.InverseTransformPoint(viewPoints [i]); if (i < vertexCount - 2) { triangles [i * 3] = 0; triangles [i * 3 + 1] = i + 1; triangles [i * 3 + 2] = i + 2; } } viewMesh.Clear(); viewMesh.vertices = vertices; viewMesh.triangles = triangles; viewMesh.RecalculateNormals(); }
edgeInfo findEdge(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 < binarySearchIters; i++) { float angle = (minAngle + maxAngle) / 2; viewCastInfo newViewCast = viewCast(angle); if (newViewCast.hit == minViewCast.hit) { minAngle = angle; minPoint = newViewCast.point; } else { maxAngle = angle; maxPoint = newViewCast.point; } } return(new edgeInfo(minPoint, maxPoint)); }
void DrawFieldOfLight() { int stepCount = Mathf.RoundToInt(lightAngle * MeshResolution); float stepAngleSize = lightAngle / stepCount; List <Vector3> viewPoints = new List <Vector3>(); viewCastInfo oldViewCast = new viewCastInfo(); List <viewCastInfo> hitEdges = new List <viewCastInfo> (); List <Vector3> hitEdgesNow = new List <Vector3> (); for (int i = 0; i <= stepCount; i++) { float angle = transform.eulerAngles.y - lightAngle / 2 + stepAngleSize * i; //Debug.DrawLine (transform.position,transform.position + DirectionFromAngle (angle,true)*lightRadius,Color.red); viewCastInfo newViewCast = viewCast(angle); if (i > 0) { bool edgeDistanceThresholdExceeded = Mathf.Abs(oldViewCast.distance - newViewCast.distance) > edgeDistanceThreshold; if (oldViewCast.hit != newViewCast.hit || (oldViewCast.hit && newViewCast.hit && edgeDistanceThresholdExceeded)) { EdgeInfo edge = FindEdge(oldViewCast, newViewCast); if (edge.pointA != Vector3.zero) { viewPoints.Add(edge.pointA); } if (edge.pointB != Vector3.zero) { viewPoints.Add(edge.pointB); } } } viewPoints.Add(newViewCast.point); oldViewCast = newViewCast; if (newViewCast.hit) { hitEdgesNow.Add(newViewCast.point); } } int vertexCount = viewPoints.Count + 1; Vector3[] vertices = new Vector3[vertexCount]; int[] triangles = new int[(vertexCount - 2) * 3]; vertices [0] = Vector3.zero; for (int i = 0; i < vertexCount - 1; i++) { vertices[i + 1] = transform.InverseTransformPoint(viewPoints [i]) + Vector3.forward * maskCutAwayDistance; if (i < vertexCount - 2) { triangles[i * 3] = 0; triangles[i * 3 + 1] = i + 1; triangles[i * 3 + 2] = i + 2; } pingX = vertices [i + 1].x; pingY = vertices [i + 1].y; } viewMesh.Clear(); viewMesh.vertices = vertices; viewMesh.triangles = triangles; viewMesh.RecalculateNormals(); constructShadowSurface(farEdge(hitEdgesNow)); }