Home Game Development unity – Fast way to calculate angular intervals and occlusion of circular objects in a 2D vision cone

unity – Fast way to calculate angular intervals and occlusion of circular objects in a 2D vision cone

0
unity – Fast way to calculate angular intervals and occlusion of circular objects in a 2D vision cone

[ad_1]

Say I have an agent in 2D in a world filled with circular obstacles of different kind.

The agent has some vision cone and can these obstacles and their kinds if they are within that cone.

I would like to be able to test how much of the agent’s cone is occupied by each sort of object and in what direction this happens.

I have already worked out what it takes to find how large a circle would appear in the field of vision of an agent. However, currently the agent can also just see through any object and also react to whatever is behind (the ultimate result is an average weighted by how large each kind of object appears)

Using Physics2D.OverlapCircleNonAlloc and an angle-based second check to see if things are still in the vision cone (and how big they are in that cone), I can find all seen objects in order of closeness and give them the appropriate weighting.
Currently I’m not doing anything with the ordering information.

I think what I roughly need to do is to define an interval, and fill it up with each object kind (something like a tuple of the kind index, and the left and right bounds of the interval) and check that no previous object already fell in those interval bounds. (If that part of the interval is already covered, clip to parts of the space that are still free)
After that I’d have to loop over each segment of the interval and accumulate the weighted average view accordingly.

However, that sounds quite slow. I have potentially hundreds of such agents able to see any kind of obstacle including each other, and even the simpler current vision system is definitely a bottleneck.

Are there ways to do this faster? (Keep in mind that each obstacle is a 2D circle that appears as a 1D line to an agent)


To get the part of an object that’s in the field of vision, I’m currently doing roughly this:

float r = object.GetObjectRadius(); // the radius of the seen object
Vector2 d = this.transform.position - base.transform.position;  // "this" being the seen object, "base" the agent. The vector from the agent to the target)

float rd2 = Mathf.Min(r * r / d.sqrMagnitude, 1f); // if it's smaller than 1, you are inside the object. Pretend you're just touching it

Vector2 d_tangent = d * (1f - rd2);
Vector2  d_perp_tangent = Vector2.Perpendicular(d) * rd2 * Mathf.Sqrt(1f / rd2 - 1f);

Vector2 left_tangent = d_tangent  + d_perp_tangent;
Vector2 right_tangent = d_tangent - d_perp_tangent

float fov_overlap = Mathf.Min(Vector2.SignedAngle(agentUpVect, left_tangent), half_view) + Mathf.Min(Vector2.SignedAngle(right_tangent, agentUpVect), half_view) // agentUpVect is the direction the agent faces in, half_view is half the vision cone. If fov_overlap < 0, the object is not seen.

This should give me the precise part of the view that’s occupied by a circular object of radius r which is |d| units away from an agent.
I tried figuring out the above myself and I’m fairly confident it’s right. I verified this by also implementing this math in GeoGebra:

enter image description here

[ad_2]