# How can I draw a “vision cone” (targetting element) into the game world?

I'm wanting to indicate various things using a "pie slice" sort of shape as below. Similar to vision cones in stealth game minimaps, or targetting indicators in RTS type games for frontal area attacks. Something generic enough to be used for both would be ideal.

I need to be able to procedurally (and efficiently) change things like the slice width and length, color, transparency, position in the world, etc. For my particular situation, there's no concern with elevation, funky terrain, or really any third axis at all as far as this element is concerned.

I have two first inclinations on how to accomplish this: 1) Manually generate the vertices for a main triangle, (possibly two, superimposed to get the border effect), a handful more to approximate the arc at the end, and roll it into a mesh.

2) Use some sort of 2D drawing library to create a circle and mask it off at the right angles, render to texture, and use that.

For reference, I have some experience with Ogre3D, but I'm not attached to it as this is a mostly academic pursuit at the moment. Other technologies that might be better at accomplishing this are more than welcome.

Finally, I'm kind of curious about how to do a "flashlight" or similar 3D effect that could produce the same result, but on all surfaces in the lit area.

I happen to have some of that code handy. I created this direct drawing code for some 2D HUD type stuff. However, you should be able to easily convert it to store vertices and/or extend it to 3D. It takes a center as the pointy end and a start degree and end degree for how wide to span. Additionally, there's a sides parameter that will set the number of steps, more steps means smoother arch. This code creates a wedge on the xy plane.

  public static void DrawWedge(int centerX, int centerY, int sides, Color color,
float alpha, float radius, double startDegree, double endDegree) {
GL11.glBegin(GL11.GL_TRIANGLE_FAN);
GL11.glColor4f(color.getRed(), color.getGreen(), color.getBlue(), alpha);
GL11.glVertex3f(centerX, centerY, 0);
double degrees = endDegree - startDegree;
for (int i = 0; i <= sides; i++) { //create triangles to fill the wedge
GL11.glVertex3f((float) (centerX + (Math.sin(Math.toRadians(startDegree + (degrees * ((float) i / (float) sides)))) * radius)),
(float) (centerY - (Math.cos(Math.toRadians(startDegree + (degrees * ((float) i / (float) sides)))) * radius)),
0);
}
GL11.glColor4f(1, 1, 1, 1);
GL11.glEnd();
}


As a bonus, I also have some code that generates a loop segment.

public static void DrawLoopSegment(int centerX, int centerY, int sides, Color color, float alpha, int innerRadius, int outerRadius, double startDegree, double endDegree) {
GL11.glColor4f(color.getRed(), color.getGreen(), color.getBlue(), alpha);
double degrees = endDegree - startDegree;
for (int i = 0; i <= sides; i++) {
GL11.glVertex3f((float) (centerX + (Math.sin(Math.toRadians(startDegree + (degrees * ((float) i / (float) sides)))) * innerRadius)),
(float) (centerY - (Math.cos(Math.toRadians(startDegree + (degrees * ((float) i / (float) sides)))) * innerRadius)), 0);
GL11.glVertex3f((float) (centerX + (Math.sin(Math.toRadians(startDegree + (degrees * ((float) i / (float) sides)))) * outerRadius)),
(float) (centerY - (Math.cos(Math.toRadians(startDegree + (degrees * ((float) i / (float) sides)))) * outerRadius)), 0);
}
GL11.glEnd();
GL11.glColor4f(1, 1, 1, 1);
}


That code could be used from something that had a minimum and maximum firing range.

The image below was not produced by this code, since I'm away from my dev machine. But it gives an idea of the two types of shapes produced.

Where the blue section would be produced by the DrawLoopSegment() code and the red by the DrawWedge() code.

• Interesting, for some reason I hadn't thought of using the lower level drawing functions for this. Triangle Fan is practically designed for this exact scenario. Something like this would seat nicely with Ogre's Manual Object, and should be fast enough to generate it each frame if it's changing that much. Thanks! – gkimsey Jun 28 '12 at 22:31
• No problem! Like I mention in the answer, you don't need to use the direct draw functionality. I just wrote it that way to see if it worked, then never got around to converting it :) Good luck! – MichaelHouse Jun 28 '12 at 22:46