Game Development Community

Give an object a 'field of view

by Brian Doig · in Torque X 2D · 01/12/2007 (1:14 pm) · 7 replies

What is the best way to give an object a 'field of view' in TGBX? What sort of code would you need to detect which objects are inside it's 'field of view' so that it can do things like flocking and attacking when an enemy comes in view. I'm primarily looking for the methods and which objects you would need to use to find out if something is in your field of view. Is there any place in the example code I can look for a sample of how to do this?

#1
01/12/2007 (2:49 pm)
@Brian
I haven't seen any TXE specific API to deal with this type of thing, but I'm still pretty new. This seems similar to collision detection or visual surface determination problems (bsp's, quads, octs, etc.). With flocking/boid thingies a dist^2 approach should work fine if you don't have lots of calculations to do.

Vector2 diff = PosA - PosB;
float distsquare = diff.x^2 + dist.y^2;

If you have a huge map and lots of enemies/thingies you should consider a data struct that'll only compare objs in the same area. For field of vision you cull out objects not in the same field by comparing the direction vector to the diff vector above if the objects are always looking where they are going.

@Torque folks
How does TXE handles it's collsion detection? Does the engine have an optimized internal structure to keep the number of object comparisons down for collisons in the same scene/object types, or does it just compare all of the objects to one another in some n^2 fashion? Would it help performance of the engine when determining collisions by setting the T2DCollisionComponent.OnCollsion to none or setting the CollidesWith to something unused/unique? There are also CollisionsEnabled/Collision fields in the T2DSceneObject, perhaps that would be better to optmize tick cycles? Thanks.

-Stu
#2
01/12/2007 (10:39 pm)
@Brian - There are some nice C# AI APIs out there, do a search for C# AI and you'll come up with a couple. Most all have flocking code in them.

#3
01/13/2007 (9:46 pm)
A good way to determine field of view is by using the cross product between the vector of the AI's viewing angle and the vector that connects the AI and its current target. Solving the cross product for the angle will give you exactly what you need, field of view. Its vector math so some background/research into it will help a little.

It is what I have used in the past for AI 'sight,' but I don't know if there is anything like this already in the code. There might be something more efficient, however.

Edit: It's actually the dot product, not the cross product. :P
#4
05/19/2009 (7:58 pm)
interesting.. thanks a lot!
#5
07/20/2009 (9:53 am)
cool thanks for this one..
#6
07/20/2009 (10:31 am)
If you wanted a simple hack for reducing the tests needed, I could see using a blank scene object which is kept in front of the seeing object. With a trigger component, it could detect when things enter or leave its area to tell what it can see, and when it can no longer see it. That would not account for a wall being in the way, but it would reduce the number of things that could potentially be seen. Then for those objects, you test for a clear line of sight. That way you're not testing against everything all the time.

It would be nice to mount such a thing, but I've found that mounted objects do not get checked for collision. Not sure how that would affect a trigger component, but you might then have to manually manage the position/orientation of it.

Just a thought.
#7
07/20/2009 (3:06 pm)
@Brian

I spent some time working on this awhile back and ended up doing something like what Ross talks about. What I ended up doing was doing a search for nearby objects, used the dot product to eliminate any objects behind my AI agent and test to see if there were any obstructions between my agent and his targets. Anything that was left after this was visible. This probably isn't the most efficient method but I haven't taken any performance hits and it serves my purposes so it's good enough. I'm happy to share my code if you're interested.

The main bit of code you'll likely be interested in is

T2DSceneGraph graph = TorqueObjectDatabase.Instance.FindObject<T2DSceneCamera>("Camera").SceneGraph as T2DSceneGraph;

graph.FindObjects(SceneObject.Position, Range, Detects, (uint)0xFFFFFFFF, _visibleObjects);

FindObjects finds the specified object types, Detects, within a certain range, Range, of a particular object's position, in this case, SceneObject.Position. Any objects found are stored in _visibleObjects.