`mapcolor(37,l45,90,0);
`mapcolor(38,155,97,0);
`mapco]or(39,165,105,0);
`mapcolor(40,l75,110,0);
`mapcolor(4l,185,ll3,0);
`mapcolor(42,190,118,0);
`mapcolor(43,200,127,0);
`mapcolor(44,210,l35,30);
`mapcolor(45,225,145,35);
`mapcolor(46,240,155,45);
`mapcolor(47,255,l65,55);
`for (i=64;
`i<128; i++) mapcolor(i,0,0,255);
`for (i=128; K256; i++) mapcolor(i,255,0,0);
`mapcolor(851,0,150,0);
`/* set up colors for instruction box */
`mapcolor(852,255,165,55);
`mapcolor(853,95,60,0);
`mapcolor(854,0,0,0);
`
`/* color for indicator box background*/
`
`138
`
`151
`
`151
`
`
`
`COMPASS
`
`/"= compute the compass heading in degrees of the input direction. */
`
`#include "fogm.h"
`
`/* fogm constants
`
`*/
`
`float compass(direction)
`double direction;
`{
`
`float compassdir;
`
`compassdir : RTOD * direction;
`if (compassdir <= 90.0)
`compassdir = 90.0 - compassdir;
`
`else
`
`compassdir = 450.0 - compassdir;
`
`return(compassdir);
`
`139
`
`152
`
`152
`
`
`
`DISPLAY_TERRAIN
`
`/* Compute which polygons need to be drawn to display the terrain and
`output them in an order such that the polygons farthest from the viewer
`are drawn first and those closest are drawn last.
`
`Note: Eventhough this seems like along routine, it is broken into 8
`independent cases based on the direction the camera is looking.
`If you understand one case the others are merely mirror images of the
`algorighm for other octants.
`*/
`
`#include "fogm.h"
`#include "ma.th.h"
`#include "gl.h"
`
`displayiterrain(vx, vy, vz, px, py, pz, fovy,
`firstxgrid, firstzgrid, lastxgrid, lastzgrid)
`
`Coord vx, vy, vz, px, py, pz;
`int
`fovy',
`short firstxgrid, firstzgrid, lastxgrid, lastzgrid;
`
`{
`
`extern float ground_planel4][3];
`extern long gnd_plane_color;
`extern Object road;99]{99];
`extern Object targetl99H99];
`extern float savetrianglelQQl[99H2l'3]l3];
`extern long gridcolor[99]’99];
`
`double lookdir;
`int threshold, count, startx, startz;
`short xgrid, zgrid;
`float tanval;
`float y;
`
`if (TV) viewport(0,474,0,474];
`else viewport[0,767,0,767);
`pushmatrix();
`
`color(SKYBLUE);
`clear”;
`
`ortho2(0.0,1023.0,0.0,767.0);
`color(BLACK);
`recti(0,0,1023,767);
`popmatrix();
`
`/* outline the screen */
`
`pushmatrix();
`perspective(fovy,l.0,0.0,19500.0);
`lookat(vx,vy,vz,px,py,pz,0.0);
`
`140
`
`153
`
`153
`
`
`
`/* determine the direction of the line of sight */
`lookdir = (double)atan2((float)(vz - pz), (float)(-(vx - px)));
`if (lookdir < 0.0) lookdir += TVVOPI;
`
`/* lay down the ground plane */
`color(gnd_plane_color);
`polf(4, ground_plane);
`
`/* put the grid objects through the geometry engine in an order
`based on the lookdir. */
`if (lookdir > SEVEN_QTR_PI)
`{
`
`/* 8th OCTANT */
`threshold = (int)(tan(lookdir+HALFPI) + 0.5);
`
`count = 0;
`startx : lastxgrid;
`startz = firstzgrid;
`while (startz <: lastzgrid) {
`zgrid = startz;
`xgrid = startx;
`
`while ((xgrid <= lastxgrid) && (zgrid <= lastzgrid)) {
`
`color(gridcolor[zgrid] [xgrid] );
`polf(3,&savetriangle[zgridl[xgridHOHOHOD;
`polf(3,&savetrianglelzgrid][xgridilIHOHOD;
`
`if [roadlzgridegrid] != O) callobj(road[zgrid][xgrid]);
`if [target[xgrid]lzgridl l: 0) callobj(target[xgrid][zgrid]);
`/* check if tank should be drawn now */
`
`zgrid += 1;
`count += 1;
`
`if [count >= threshold) {
`xgrid += 1;
`count = O;
`
`} s
`
`tartx -= 1;
`count = 0;
`
`if (startx < firstxgrid) {
`startx : firstxgrid;
`startz +2 threshold;
`
`}
`
`} e
`
`{
`
`lse if ((lookdir > THREE_HALVES_PI) && (lookdir <= SEVEN_QTR_PI))
`
`141
`
`154
`
`154
`
`
`
`/* 7th OCTANT */
`tanval = tan(lookdir+HALFPI);
`if (tanval :—_- 0.0)
`threshold 2 1000;
`
`else
`
`threshold = (int)((l.0/tanval) + 0.5);
`
`count = 0;
`startx : lastxgrid;
`startz = firstzgrid;
`while (startx >= firstxgrid) {
`zgrid = startz;
`xgrid = startx;
`
`while ((xgrid >= firstxgrid) && (zgrid >= firstzgrid)) {
`
`color(gridcolor[zgrid][xgrid]);
`polf(3,&savetriangle[zgridl[xgrid][0][0][0));
`polf(3,&savetriangle)zgrid)[xgrid][l][0][0));
`if(road[zgrid]1'xgrid] l: 0) callobj(road[zgrid][xgrid]);
`if (targefixgridl'zgrid) != 0) callobj(target[xgrid][zgrid]);
`
`xgrid -= 1;
`count += 1;
`
`if (count >2 threshold) {
`zgrid -: 1;
`count = 0;
`
`} s
`
`tartz +: 1;
`count = 0;
`
`if (startz > lastzgrid) {
`startz = lastzgrid;
`startx -= threshold;
`
`}
`
`} e
`
`{
`
`lse if ((lookdir > FIVE_QTR‘PI) && (lookdir <= THREE_HALVES_PI))
`
`/* 6th OCTANT */
`tanval = -tan(lookdir+HALFPI);
`if (tanval == 0.0)
`threshold : 1000;
`
`else
`
`threshold = (int)((l.0/tanval) + 0.5);
`
`count = 0;
`startx : firstxgrid;
`startz = firstzgrid;
`
`142
`
`155
`
`155
`
`
`
`while (startx <= lastxgrid) {
`zgrid = startz;
`xgrid = startx;
`
`while ((xgrid <= lastxgrid) && (zgrid >= firstzgrid» {
`
`color(gridcolor|zgrid] ngrid] );
`polf(3,&savetriangle[zgrid] [xgrid] [0] [0] [0] );
`polf(3,&savetriangle[zgrid][xgrid][1][0][0]);
`
`if (roadlzgridllxgrid) l: 0) callobj(road[zgrid][xgrid]);
`if (target[xgrid][zgrid] l= 0) callobj(target[xgrid][zgrid]);
`xgrid += 1;
`count. += 1;
`
`if (count >= threshold) {
`zgrid -: 1;
`count = 0;
`
`}
`
`} s
`
`tartz += 1;
`count. = 0;
`
`if (startz > lastzgrid) {
`startz = lastzgrid;
`startx += threshold;
`
`}
`
`} e
`
`{
`
`lse if ((lookdir > PI) && (lookdir <= FIVE_QTR_PI))
`
`/* 51h OCTANT */
`threshold = (inL)(-tan(lookdiH—HALFPI) + 05);
`
`count. = 0;
`startx = firstxgrid;
`startz = firstzgrid;
`while (startz <= lastzgrid) {
`zgrid = startz;
`xgrid = startx;
`
`while [(xgrid >= firstxgrid) && (zgrid <= lastzgrid)) {
`color(gridcolor[zgrid][xgrid]);
`polf(3,&savetriangle[zgrid][xgridHO][0][0]);
`polf(3,&savetriangle[zgrid][xgridHl][0][0]);
`
`if (road[zgrid][xgrid] l: 0) callobj(road|zgrid][xgrid]);
`if (targetlxgridllzgridl l: 0) callobj(ta.rget[xgrid]lzgridl);
`zgrid += 1;
`count += 1;
`
`143
`
`156
`
`156
`
`
`
`if (count >= threshold) {
`xgrid -= 1;
`count = 0;
`
`}
`
`} s
`
`tartx += 1;
`count = 0;
`
`if (startx > lastxgrid) {
`startx = lastxgrid;
`startz += threshold;
`
`}
`
`} e
`
`{
`
`lse if ((lookdir > TIIREE_QTR_PI) && (lookdir <= pm
`
`/* m1 OCTANT */
`threshold 2 (int)(Lan(lookdir+HALFPI) + 0.5);
`
`count = 0;
`startx = firstxgrid;
`startz = lastzgrid;
`while (startz )2 firstzgrid) {
`zgrid : startz;
`xgrid = startx;
`
`while ((xgrid >= firstxgrid) && (zgrid >= firstzgrid)) {
`
`color(gridcolor{zgrid][xgrid]);
`polf(3,&savetriangle[zgrid][xgrid][0][0”0]);
`polf(3,&savetriangle[zgrid][xgrid][l]l0l[0]);
`if (road[zgrid][xgrid: != 0) callobj(r0ad[zgrid][xgrid]);
`if (targetlxgridegridl != 0) callobj(targetlxgridllzgridl);
`
`zgrid -= 1;
`count. += 1;
`
`if (count >= threshold) {
`xgrid -= 1;
`count = 0;
`
`}
`
`} s
`
`tartx += 1;
`count. = 0;
`
`if (startx > lastxgrid) {
`startx = lastxgrid;
`startz -= threshold;
`
`144
`
`157
`
`157
`
`
`
`} e
`
`{
`
`lse if ((lookdir > HALFPI) && (lookdir <= THREE_QTR_PI))
`
`/* 3rd OCTANT */
`tanval = tan(lookdir+HALFPl);
`if (tanval == 0.0)
`threshold 2 1000;
`
`else
`
`threshold 2 (int)((l.O/tanval) + 0.5);
`
`count = 0;
`startx = firstxgrid;
`startz = lastzgrid;
`
`while (startx <= lastxgrid) {
`zgrid = startz;
`xgrid = startx;
`
`while ((xgrid <= lastxgrid) && (zgrid <= lastzgrid)) {
`
`color(gridcolor[zgrid) [xgrid]);
`polf(3,&savetriangle[zgrid] [xgrid] [0] l0] l0] );
`polf(3 ,&savetriangle[zgrid] [xgrid] [ l I '0] [0]);
`
`if (road[zgrid)[xgrid] l: 0) callobj(road[zgrid][xgrid]);
`if (targetlxgridegrid) l: 0) callobj(target[xgrid][zgrid]);
`xgrid += 1;
`count += 1;
`
`if (count >Z threshold) {
`zgrid += 1;
`count = 0;
`
`}
`
`} s
`
`tartz -= 1;
`count = 0;
`
`if (startz < firstzgrid) {
`startz = firstzgrid;
`startx += threshold;
`
`}
`
`} e
`
`{
`
`lse if [(lookdir > QTR_PI) && (lookdir <2 HALFPI))
`
`/* 2nd OCTANT */
`tanval = -(tan(lookdir+HALFPI));
`if (tanval =2 0.0)
`threshold = 1000;
`
`else
`
`threshold 2 (int)((1.0/tanval) + 0.5);
`
`145
`
`158
`
`158
`
`
`
`count = O;
`startx = lastxgrid;
`startz = lastzgrid;
`while (startx >= firstxgrid) {
`zgrid = startz;
`xgrid = startx;
`
`while ((zgrid <= lastzgrid) && (xgrid >= firstxgrid)) {
`
`01M);
`OllOl);
`
`] 1
`
`color(gridcolor[zgrid] [xgrid] );
`polf(3 , &savetriangle[z grid] [xgrid] [0
`1
`polf(3 , &savetriangle[zgrid] [xgridH
`
`if (road[zgrid][xgrid] != 0) callobj(road[zgridl[xgrid]);
`if (target[xgrid][zgridl l= 0) callobj(target:xgrid][zgrid]);
`xgrid -: 1;
`count += 1;
`
`if (count >= threshold) {
`zgrid += 1;
`count = 0;
`
`}
`
`} s
`
`tartz -= 1',
`count = 0;
`
`if (startz < firstzgrid) {
`startz : firstzgrid;
`startx -= threshold;
`
`}
`
`}
`}
`else if ((lookdir >: 0.0) && (lookdir <: QTR_PI))
`{
`
`/* lst OCTANT */
`threshold = (int)(-tan(lookdir+HALFPl) + 0.5);
`
`count = 0;
`startx = lastxgrid;
`startz = lastzgrid;
`while (startz )2 firstzgrid) {
`zgrid = startz;
`xgrid = startx;
`
`while ((xgrid <= lastxgrid) && (zgrid )2 firstzgrid)) {
`
`color(gridcolorlzgridflxgridl)g
`polf[3,&savetriang|e[zgrid][xgrid]l0][0][0]);
`polf(3,&savetriang|e[zgrid][xgrid][1][0][0]);
`
`if (road[zgrid][xgrid] != O) callobj(road[zgrid][xgrid]);
`
`146
`
`159
`
`159
`
`
`
`if (target[xgrid][zgrid] != 0) callobj(targetlxgridegridD;
`zgrid —= 1;
`count. += 1;
`
`opmatrix”;
`
`if (startx < firstxgrid) {
`startx = firstxgrid;
`startz -= threshold;
`
`}
`
`} p
`
`if (count >= threshold) {
`xgrid +2 1;
`count = 0;
`
`} s
`
`tartx -= I;
`count = 0;
`
`160
`
`
`
`DIST_TO LOS
`
`#include "gl.h"
`#include "math.h"
`float dist_to_los(vx,vy,vz,px,py,pz,point)
`/* compute the distance from the point "point" to the line of sight */
`
`Coord vx,vy,vz,px,py,p2;
`float point[3];
`
`{
`
`}
`
`/* direction numbers of line of sight =*/
`
`float a,b,c;
`float d,e,f;
`float dist;
`
`a = (Hoat)(px - vx);
`b = (float)(Py - W);
`C = (float)(pz - vz);
`
`d : point[0] - (float)vx;
`e : point[l] - (float)vy;
`f: point[2] - (float)vz;
`
`dist = sqrt((up_i(e*c - f*b,2) + up_i(f*a - d*c,2) + up_i(d*b - e*a,2))/
`(up_i(a,2) + up_i[b.2) + up_i(c,2)));
`
`return(dist);
`
`148
`
`161
`
`161
`
`
`
`DO_BOUNDARY
`
`#include "gl.h”
`#include "math.h"
`#include "stdio.h”
`#include ”fogm.h"
`
`#define X 0
`#define Y 1
`#define Z
`2
`
`#define DIAGONAL 0
`#define HORIZONTAL 1
`#define VERTICAL 2
`
`#define LOWER
`#define UPPER
`
`0
`
`1
`
`0
`#define NONE
`#define INTERSECT 1
`#define PROPER
`2
`
`do_boundary(bounditype, which_t.riangle, xgrid, zgrid,
`bound start, bound end, left start,
`left end, right. starttright
`en—d, start corner flag,
`end:corner_fla§, poly], ver—tex_cnt) —
`—
`
`int bound_type, which_triangle, xgrid, zgrid;
`
`float boundwstart‘l’x], bound_endl3l, left.*start[3], left_end[3],
`rightful-H3], rightfiendi3];
`
`int *start_corner_flag, *end_corner_flag;
`
`float polyl[10][3l;
`
`int. *vertex cm;
`
`int test_index, cnt, index;
`
`float. bound_rightlB], bound_left.[3], bound_start_edge[3],
`bound_end _edge[3];
`
`float vertex_array[lOH3]‘,
`float road_poly[10”3];
`float grid_poly[10][3];
`
`int intersect_cnt;
`
`149
`
`162
`
`162
`
`
`
`int intersect_type, decending_sort;
`
`float upper_bound, lower_bound;
`
`float gnd__level();
`
`int in__this_poly();
`
`intersect_cnt = -l;
`
`/* compute the verticies of the road segment currently
`being worked on */
`for (index = 0; index < 3; ++index) {
`road_poly[0][index] = left_start[indexl;
`road_poly[1][index] = left ‘endlindexl;
`road_poly[2][index] = right__end|index];
`roadipolyliillindex] = right_startlindex|;
`
`} /
`
`* compute the verticies of the grid triangle associated with
`this boundary */
`grid_poly[0}[X] = (float)(xgrid*FT~100M);
`grid_poly[0‘lIZ] = (float)((zgrid+l)*FT_lOOM);
`grid_poly[llI'X] = (float)((xgrid+l)*FT_lOOM);
`grid_poly[lj Z] = (float)(zgrid*FT_100M);
`if (which_triangle 2: UPPER) {
`grid_poly;2][X] = (float)((xgrid+1)*FT_100M);
`grid_poly:2]'ZI = (float)((zgrid+l)*FT_100M);
`
`} e
`
`lse {
`
`grid_poly{2l'X] = (float)(xgrid*FT_100M);
`grid_polyl2] Z] = (fioat)(zgrid*FT_100M);
`
`} i
`
`f (bound‘type == HORIZONTAL) {
`test_index : X;
`
`} e
`
`lse if (bound_type == VERTICAL) {
`test_index = Z;
`
`} e
`
`lse if (bound_type 2: DIAGONAL) {
`test_index : Z;
`
`} i
`
`f (bound_startltest_index] < bound_end[test_index}) {
`lower_bound = bound_startltest._index];
`upper_bound : bound_end[test_index];
`
`lower_bound = bound_end[test_index];
`upper_bound = bound_start|test_index];
`
`} e
`
`}
`
`lse {
`
`150
`
`163
`
`163
`
`
`
`/* determine points of intersection between left and right sides
`of the road and the boundary
`*/
`
`line_intersect2(bound_start, bound_end, right_start, right_end,
`b0und_right, &intersectitype);
`if (intersect_type :2 PROPER) {
`
`/* intersection lies on road line segment, add intersection
`to array */
`intersect cnt += 1;
`vertex arraylintersect cntHX] = bound_right[X];
`vertex:a.rray[intersect:cnt][Z] = bound_right|Z];
`vertex_array|intersect_cnt][Y] = gnd_level(bound_right[X],
`-bound_right[Z]);
`
`}
`else if ((intersect_type == INTERSECT) &&
`(in_this_poly(grid_poly, 3, right_start)) &&
`(bound_right[test_index] > lower_bound) &&
`(bound_right[test_index] < upper_bound)) {
`
`/* intersection point is beyond the bound of the road’s right
`line segment7 but the right start point is inside the polygon so
`add the road’s right start point to the vertex array */
`
`intersect cnt += 1',
`vertex arraylintersect cnt][X] 2 right_start[X];
`vertex:array[intersect:cnt][Z] = rightAstart[Z];
`vertex_array[intersect'cnt][Y] = gnd_level(right_start[X],
`-right_start[Z});
`
`}
`else if ((intersect_type == INTERSECT) &&
`(in_this_poly(grid_poly, 3, rightAend)) &&
`(bound_right[test_index] > lower_bound) &&
`(bound_right[test_index] < upper_bound)) {
`
`/* intersection point is beyond the bound of the road’s right
`line segment, but the right end point is inside the polygon so
`add the road’s right end point to the vertex array */
`
`intersect_cnt += 1;
`vertex_a.rray[intersect_cntHX] : right_end[X];
`vertex_a.rray[intersect_cntHZ] = right_endlZ];
`vertex_array[intersect_cntl[Y] = gnd_level(right_end[X],
`-right_end[Z]);
`
`}
`line_intersect2(bound_start, bound_end, left_start, left_end,
`bound_left, &intersect_type);
`if (intersect_type == PROPER) {
`/* intersection lies on road line segment, add intersection
`to array */
`intersect_cnt += 1;
`vertex_array[intersect_cnt][X] = bound_left[X];
`
`151
`
`164
`
`164
`
`
`
`vertex_array[intersect_cnt][Z] = bound_1eft[Z];
`vertex_array[intersect_cnt][Y] = gnd_level(bound_left[X],
`—bound_left[Z]);
`
`} e
`
`lse if ((intersect_type :2 INTERSECT) &&
`(in_this_poly(grid_poly7 3, left_start)) &&
`(bound_left[test_index] > lower_bound) &&
`(boundwleft[test_index] < upper_bound)) {
`
`/* intersection point is beyond the bound of the road’s left
`line segment, but the left start point is inside the polygon so
`add the road’s left start point to the vertex array */
`
`intersect_cnt += 1;
`vertex_array[intersect_cnt][X] : left start[X];
`vertex_array[intersect_cnt]:Z] = left:start[Z];
`vertex_array[intersect_cnt][Y] = gnd_level(left_start[X],
`-left_start[Z]);
`
`} e
`
`lse if ((intersect_type == INTERSECT) &&
`(in this_poly(grid_poly, 3, left end)) &&
`(boimd_left[test_index] > lower— bound) &&
`(bound_left[test_index] < upper:bound)) {
`
`/* intersection point is beyond the bound of the road’s left
`line segment, but the left end point is inside the polygon so
`add the road’s left end point to the vertex array */
`
`intersect cnt += 1;
`vertex#a;ray[intersect_cnt][X] : left_end{X];
`vertex_array[intersecticnt][Z] = leftiendlzl;
`vertex_array[intersect_cnt]EY] = gnd_level(left_end[X],
`-left_end[Z]);
`
`} /
`
`* if either of the bound’s end points fall within the bounds of the
`road, add them to the array*/
`if ((!*start cornerifiag) && (in_this_poly(road_poly, 4, bound_start))) {
`/* pu—t in start bound point */
`*start_corner_flag = TRUE;
`intersect_cnt +2 1;
`vertex_array[intersect_cnt][X] = bound_start[X];
`vertex_array[intersect_cnt]IZ] = bound_start[Z];
`vertex_array[intersect_cnt]{Y} = bound.start[Y];
`
`if ((!*end_corner_flag) && (in_this_poly(road_poly, 4, bound_end))) {
`/* put in end bound point */
`*end__corner_fiag = TRUE;
`intersect_cnt += 1;
`vertex_array[intersect‘cnt][X] = bound_end|X];
`vertex-a.rray[intersect_cnt][Z] = bound‘endIZ];
`vertex_array[intersectvcnt][Y] = bound_end|Y];
`
`152
`
`165
`
`165
`
`
`
`} /
`
`* determine the point of intersection between the start and end
`bound of the road and the grid boundary */
`line intersect2(bound_start, bound_end, left_start, right_start,
`bound__start_edge, &intersect_type);
`if (intersectfitype 2: PROPER) {
`/* intersection lies on road line segment, add intersection
`to array */
`intersectAcnt += 1',
`vertex_a.rray[intersect_cnt][X] = bound_start_edge[X];
`vertex array[intersect cntHZ] = bound__start_edge[Z];
`vertex:array[intersect:cnt][Y] 2 gnd_level(bound_start_edge[X],
`-bound_start_edge[Z]);
`
`} l
`
`ine_intersect2(bound_start, bound_end, 1eft_end, right_end,
`bound_end_edge, &intersect_type);
`if (intersect
`type 2: PROPER) {
`/* inte—rsection lies on road line segment, add intersection
`to array */
`intersecticnt += 1',
`vertex_array[intersect_cnt][X] 2 bound_end_edge[X];
`vertex_array[intersect_cnt][Z] = bound end edgelZ];
`vertexwarray[intersect_cnt][Y] = gndwle_vel(la—ound_end_edge[X],
`-bound_end_edge[Z]);
`
`} /
`
`* put the points from the vertex_array into the poly] array in
`the proper order =‘/
`decending_sort = (bound_start[test_index] != lower bound);
`sort_array(vertex_array, intersect_cnt, decending_sort, test_index);
`
`for (cnt = 0; cnt <= intersect_cnt; ++cnt) {
`*vertex_cnt 4—: 1;
`II
`vertex_array[cnt]|X];
`polyl[*vertex_cnt][X]
`polyl[*vertex_cnt][Y] = vertex_array[cntHY];
`polyl[*vertex_cnt][Z] = -vertex_array[cnt][Z];
`
`153
`
`166
`
`166
`
`
`
`EDIT_INDBOX
`
`/* update the control settings of the indicator box */
`#include "fogm.h"
`#include "gl.h"
`
`edit_indbox(indbox, speedtag, headingtag, elevtag, altmsltag,
`zoomtag, tilttag, pantag, desigtag, speed, compassdir,
`vx, vy, vz, pan, tilt, zoom, designate)
`
`Object indbox;
`
`Tag speedtag, headingtag, elevtag, altmsltag, zoomtag, tilttag, pantag,
`desigtag;
`
`float speed, compassdir;
`
`Coord vx, vy, vz;
`
`double pan, tilt;
`
`int designate;
`
`int zoom;
`{
`
`char chspeed[5], chheadingl5l, chelevlS‘, chaltmsl[5];
`float gnd_level();
`float zoomtic, pantic, tilttic;
`
`/* convert speed to string */
`sprintf(chspeed,"%4.0F',speed);
`/* convert heading to str */
`sprintf(chheading,"%3.0f“,compassdir);
`sprintf(chelev,"%4.0f",vy - gnd_level(vx,vz));
`/* convert elev AGL to str */
`sprintf(chaltmsl,"%4.01",vy);
`/* convert alt MSL to str */
`
`/* compute new location for zoom, pan, and tilt indicators
`zoomtic = zoom *
`-0.2766 + 222.128;
`tilttic = tilt * 721.9268? + 365.0;
`pantic = pan * -72l.92682 + 435.0;
`
`*/
`
`/* update the indicator display */
`
`editobj(indbox);
`objreplace(speedtag)',
`charstr(chspeed);
`objreplace(headingtag);
`charstr(chheading);
`objreplace(elevtag);
`charstr(chelev);
`objreplace(altmsltag);
`charstr(chaltmsl);
`objreplace(zoomtag);
`move2(28.0,zoomtic);
`objreplace(tilttag);
`
`154
`
`167
`
`167
`
`
`
`move2(42.0,tilttic);
`objreplace(pantag);
`move2(pantic,27.0);
`objreplace(desigtag);
`cmov2i(designate ? 10 : 19,10);
`charstr(designate ? "DESIGNATE" : "REJECT");
`
`closeobj ();
`
`168
`
`
`
`EDIT_NAVBOX
`
`#include "fogm.h"
`#include "math.h"
`#include "gl.h"
`
`edit navbox(navbox, arrowtag, vx, vz, direction,firstxgrid, firstzgrid,
`last£grid, lastzgrid)
`Object navbox;
`Tag arrowtag;
`Coord vx, vz;
`double direction;
`short firstxgrid, firstzgrid, lastxgrid, lastzgrid;
`{
`
`Coord arrowx, arrowy, larrowx, larrowy, rarrowx, rarrowy;
`
`/* compute coordinates of arrow line segments for new control box */
`arrowx 2 vx + cos(direction) * 2.0 * FEETPERGRID;
`arr0wy = vz - sin(direction) * 2.0 * FEETPERGRID;
`larrowx 2 arrowx + cos(direction - 2.3561945) * FEETPERGRID;
`larrowy = arrowy - sin(direction - 2.3561945) * FEETPERGRID;
`rarrowx = arrowx + cos(direction + 2.3561954) * FEETPERGRID;
`rarrowy = arrowy - sin(direction + 2.3561945) * FEETPERGRID;
`
`*/
`
`/* update the contour map display with new info
`editobj(navbox);
`objreplace(arrowtag);
`move2(vx,vz);
`draw2(arrowx, arrowy);
`draw2(larrowx, larrowy);
`move2(arrowx, arrowy);
`draw2(rarrowx, rarrowy);
`rect(firstxgrid*FT_100M,—firstzgrid*FT_100M,
`(lastxgrid+l)*FT_100M, (-lastzgrid-1)*FT_1OOM);
`closeobj();
`
`156
`
`169
`
`169
`
`
`
`#include "gl.h"
`
`explosion()
`
`{.
`
`int i,j;
`
`pushviewport();
`viewport(0,1023,0,767);
`color(BLACK);
`clear();
`swapbuffersO;
`color(RED);
`clear”;
`swapbufferso;
`swapbuHerSO;
`color(YELLOW);
`clear”;
`swapbufTersO;
`swapbuflersO;
`color(RED);
`clear“;
`swapbufl'erso;
`swapbuflerso;
`color(YELLOW);
`clear”;
`swapbufl'erso;
`swapbuflerso;
`color(RED);
`clear”;
`swapbufiers();
`swapbufferso;
`for (i = 0; i < 100000; i++)
`for (j = O;j<10;j++);
`popviewport();
`
`EXPLOSION
`
`157
`
`170
`
`170
`
`
`
`FOGM (MAIN)
`
`/* fogm.c -— an IRIS-2400 program by Doug Smith & Dale Streyle
`It reads in a 10km x 10km section of a terrain map, computes a lighting
`and shading model for the terrain, and allows overflight
`*/
`
`#include "gl.h"
`#include "device.h"
`#include "fogm.h"
`#include "math.h"
`#include "get.h"
`#include "stdio.h"
`#include "sys/signal.h"
`#include <sys/types.h>
`#include <sys/times.h>
`
`*/
`/* get the graphics defs
`/* get the graphics device defs
`/"‘ constants
`*/
`/* math function declarations
`/‘* monitor type include file
`
`*/
`
`*/
`
`*/
`
`*/
`/* used for screen dump utility
`/* contains the time sturcture tms */
`/* for time calls
`*./
`
`short gridpixel[100][100]; /* DMA elevation and vegatation data
`float savetrianglei99][99][2i[3:[3];
`long gridcolor[99l[99];
`Object road|99][99];
`Object target[99]|99];
`
`*/
`
`float ground_p|ane[4][31;
`long gnd'plane_color;
`float tgt_poslMAX_TGTS][3l;
`short tgt_grid_idx|MAX_TGTS][2];
`short tgt‘dir MAXiTGTS], tgt‘total = 0;
`float randx, randy, randz; /* random offsets from tank reference point */
`
`int framecnt;
`
`float min_elev, max_elev;
`
`Coord tankx7 tanlty7 tankz;
`
`float frames_sec[1000][2];
`
`main()
`{
`
`int greyscale = FALSE;
`
`/* FALSE 2 color, TRUE 2 greys */
`
`int designate;
`
`/* boolean indicating desig/reject status
`
`*/
`
`int flying = TRUE;
`
`/* boolean controlling flying loop
`
`*/
`
`int active = TRUE;
`
`/* boolean controlling main program loop
`
`int nbyte, socket, connect.client(); /* networking variables & subroutine */
`
`158
`
`171
`
`171
`
`
`
`struct tms timestruct;
`
`/* structure for real-time clock calls
`
`*/
`
`int tgtflidx;
`
`/* index of designated target
`
`double direction;
`
`/* direction of travel in radians
`
`float speed;
`
`/* speed of travel in knots
`
`*/
`
`*/
`
`*/
`
`float compassdir;
`
`/* desired direction of travel in compass deg
`
`*/
`
`int fovy = 550;
`
`/* field of view in perspective command
`
`*/
`
`double pan = 0.0,
`tilt = ~15.0 * DTOR;
`
`/* pan and tilt angles
`
`*/
`
`*/
`/* contour map, indicator, instruction
`Object contour, navbox, indbox, instrbox;
`Object tank, preflAObj 7];
`
`Tag headingtag, elevtag, speedtag, zoomtag, arrowtag, tilttag, pantag;
`Tag desigtag, altmsltag, pre__l_tag[6];
`
`Colorindex unmask;
`
`Coord vx, vy, vz;
`
`/* viewer x y and z coordinates */
`
`Coord px, py, pz;
`
`/* reference x y z coordinates for lookat */
`
`Coord tgtx, tgty, tgtz;
`
`/* targeted position on tank */
`
`float randseed();
`
`/* random number generator initialization */
`
`int frames 2 -1;
`long seconds, lastseconds, totalseconds = 0;
`int numpolys;
`float elapsed;
`int idx;
`FILE *f'open(), *fp;
`
`/* first and last x and z indexes of the grid objects to draw */
`short firstxgrid, firstzgrid, lastxgrid7 lastzgrid;
`
`readdata();
`
`/* read the data file into the gridpixel array */
`
`/* get SOcket number for networking */
`/*if (NETWORKING) socket = connectbclient("npscs-irisl",3); */
`
`/* initialize the iris */
`init_iris();
`unmask = (1<<getplanes()) - l;
`writemask(unmask);
`
`randseed(times(×truct));
`
`/* seed the random # generator */
`
`159
`
`172
`
`172
`
`
`
`init_tgts();
`
`/* define targets */
`
`Screen_Dump(SCREENDUMP);
`
`/* enable screen dumping =l'/
`
`billboard();
`
`/* produce intro screen */
`
`colorramp(greyscale,TRUE);
`
`/* build all color ramps */
`
`makescreens(pre_l_obj, pre_l_tag);
`makemap(&contour);
`pre_l_obj[CONTOUR] = contour;
`
`/* build objects for prelaunch */
`/* build map object */
`
`prelaunch(&vx, &vy, &vz, &direction, &compassdir,
`&active, pre_lhobj, pre‘l_tag);
`
`if (active) {
`maketank(&tank);
`
`/* build object for a tank */
`
`build_road();
`
`/* build the objects that comprise the roads */
`
`/* process terrain data to build polygons and compute lighting */
`buildterrain();
`
`/* build object for the navigation display contour map */
`drawnavbox(&navbox, &arrowtag);
`
`I” build an object for the indicator box */
`makeindbox(&indbox,&headingtag,&elevtag,&altmsltag,&speedtag,
`&zoomtag,&tilttag,&pantag,&desigtag);
`
`makeinstrbox(&instrbox);
`
`/* build object for control instruction box */
`
`}
`
`/* end of if (active) block */
`
`while (active) {
`
`framecnt = 0;
`
`/* initialize the operator controls (mouse and dials) */
`init_controls(&pan, &tilt, &fovy, vy, greyscale, compassdir);
`
`pushviewport();
`viewport(0,1023,0,767);
`color(SKYBLUE);
`clear();
`popview port();
`callobj(instrbox);
`callobj(indbox);
`editobj(contour);
`objreplace(STARTTAG);
`viewport(768,1023,512,767);
`
`160
`
`173
`
`173
`
`
`
`closeobj ( );
`callobj(contour);
`swapbufiers();
`callobj(instrbox);
`callobj(contour);
`ed itobj (contour);
`objreplace(STARTTAG);
`vieWport(0,768,0,768);
`closeobj();
`
`flying : TRUE;
`designate = TRUE;
`
`/* missile is flying */
`/* a. target can be designated */
`
`while(flying)
`
`{
`
`/* until tgt is hit or 3-button exit */
`
`/* get values from user contols (mouse and dials) */
`read_controls[&designate, &greyscale, &Hying, &active,
`&speed, &direction, &compassdir, &vy,
`&pan, &tilt, &fovy);
`
`/* calculate which target was closest to the line of
`sight */
`if (Ydesignate) {
`nearest_tgt(vx,vy,vz,px,py,pz,&tgt_idx);
`
`} /
`
`* update targets’ positions */
`get_tgt_posit(socket, designate, tgt_idx, &tgtx, &tgty, &tgtz, tank);
`
`/* update missile position */
`update_missile_posit(&direction, &compassdir, speed,
`designate, tgtx, tgty, tgtz,
`&vx, &vy, &vz, &flying);
`
`/* update camera lookat position */
`update_look_posit(direction, pan, tilt, vx, vy, vz,
`tgtx, tgty, tgtz, designate, &px, 85p)!7 &pz);
`
`/* determine which polygons need to be drawn */
`view_b0unds(vx, vy, vz, px, py, pz, tilt, fovy,
`&firstxgrid, &firstzgrid, &lastxgrid, &lastzgrid);
`
`/* edit control display objects to reflect new values */
`edit_navbox(navbox, arrowtag, vx, vz, direction, firstxgrid,
`firstzgrid, lastxgrid, lastzgrid);
`edit_indbox(indbox, speedtag, headingtag, elevtag, altmsltag,
`zoomtag, tilttag, pantag, desigtag, speed,
`compassdir, vx, vy, vz, pan, tilt, fovy, designate);
`
`/* display the 3-D view of the terrain as seen by
`
`161
`
`174
`
`174
`
`
`
`*/
`the camera
`display_terrain(vx7 vy, vzY px, py, pz, fovyl
`firstxgrid, firstzgrid, lastxgrid, lastzgrid);
`
`/* display the control boxes */
`writemask(SAVEMAP);
`callobj(navbox);
`writemask(unmask);
`callobj(indbox);
`
`swapbufiers();
`
`seconds : times(×truct);
`numpolys = (lastxgrid - firstxgrid)*(lastzgrid-firstzgrid)*2;
`elapsed : (float)(seconds - lastseconds)/60.0;
`if ((frames >= 0) && (frames < 1000) ){
`frames_sec[frames)[0) = (float)numpolys;
`frames_sec[frames)[l) = 1.0/elapsed;
`
`} t
`
`otalseconds += (seconds-lastseconds);
`if (totalseconds > 7200) {
`compactify();
`/* do garbage collection every 2 mins */
`totalseconds : 0.0;
`
`} l
`
`astseconds 2 seconds;
`frames += 1;
`
`}
`
`/* end of flying loop */
`
`/* explode & restart */
`if (active) {
`explosion”;
`prelaunch(&vx, &vy, &vz, &direction, &compassdir,
`&active, preAl'obj, pre_l_tag);
`
`}
`
`} /* end of active loop */
`
`/* write out. performance stats */
`fp = fopen("speed.data", "w");
`if (frames > 999) frames 2 999;
`for (idx = 0; idx <= frames; ++idx) {
`fprintf(fp,"%.2f %.2f0, frames_sec[idxll0), frames_sec[idx][1));
`
`l
`
`162
`
`175
`
`175
`
`
`
`}
`
`/* gracefully exit */
`if (NETWORKING) close(sockec);
`setmonitor(HZ60);
`color-(BLACK);
`clear();
`swapbufl'erso;
`clear();
`gexitt);
`Lext‘iniLO;
`exit“;
`
`/* end of main */
`
`176
`
`
`
`FILES.H
`
`/* These are the files which contain data for the terrain elevations
`and roads
`*/
`#define TERRAIN_FILE "/work/terrain/tenkmsq.dat"
`#define ROAD_FILE "/work/terrain/Road.data"
`
`FOGM.H
`
`#define
`
`elev_mask
`
`Oxlfff
`
`/* mask to obtain elev value from datum */
`
`#define veg_mask
`
`#define
`
`RD
`
`/* mask to obtain vegatation value from
`0x0007
`shifted datum */
`/* code for reading a file in "open"
`
`*/
`
`0
`
`#define MAX
`
`2800
`
`/* max elev (ft) in contour map
`
`*/
`
`#define MIN
`
`967
`
`/" min elev (ft) in contour map
`
`*/
`
`#define SKYBLUE
`
`4095
`
`/* color index for sky color
`
`*/
`
`#define ROADGREY
`
`850
`
`/* color index for the road
`
`*/
`
`#define DELTAFOVY
`
`50
`
`/* field of view (zoom) increment of 5 deg */
`
`#define PI
`
`3.1415927
`
`#define TVVOPI
`
`6.2831853
`
`#define HALFPI
`
`1.5707963
`
`#define THREE_HALVES_PI 4.7123889
`
`#define QTR_PI
`
`0.7853982
`
`#defineTHREE_QTR_PI
`
`2.3561945
`
`#define FIVE_QTR_PI
`
`3.9269908
`
`#define SEVENiQTR_PI
`
`5.4977871
`
`#define RTOD
`
`57.29578 /* radians to degrees conversion factor
`
`*/
`
`#define DTOR
`
`0.0174533 /* degrees to radians conversion factor
`
`*/
`
`#define FPS_TO_KTS
`
`35.525148 /* convert feet per 60th seconds to knots */
`
`164
`
`177
`
`177
`
`
`
`#define PANSENS
`
`/* scale factors (sensitivity) for
`30.0
`navigaion controls (mouse and dials)
`
`*/
`
`#define SPEEDSENS
`
`20
`
`#define TILTSENS
`
`50.0
`
`#define DIRSENS
`
`20.0
`
`/* maximum distance that the camera can
`#define MAXLOOKDIST 32808.0
`look ahead in feet
`*/
`
`#define FEETPERGRID 3280.8
`
`/* number of feet in 1000 meters
`
`*/
`
`/* altitude expansion factor, altitudes are
`#define ALTSCALE 1.05
`raised to this power to give an
`exagerrated effect
`
`*/
`
`#define NUMXGRIDS
`
`/* number of 1K grid squares in the East-
`10
`West direction
`*/
`
`#define NUMZGRIDS
`
`/* number of 1k grid squares in the North-
`10
`South direction
`*/
`
`#define FT_IOK
`
`32808
`
`/* number FT in lOKm
`
`#define FT_1001\1
`
`328.08
`
`/* number FT in 100m
`
`*/
`
`*/
`
`#define GRID_FACTOR
`
`13.03781 /* conversion factor
`
`*/
`
`#define TV
`
`0
`
`/* 0 for SGI monitor, 1 for TV
`
`*/
`
`#define SCREENDUMP
`
`#define NETWORKING
`
`#define INIT_PAN
`#define MIN_PAN
`#define MAX_PAN
`
`#define INIT_TILT
`#define MIN_TILT
`#define MAX_TILT
`
`l
`
`o
`
`0
`-25
`25
`
`~15
`-25
`15
`
`/* 1 to enable screen dumping, 0 otherwise */
`
`/* 1 for target networking, 0 otherwise
`
`*/
`
`/* initial, min and max pan angles in deg. */
`
`/* initial, min and max tilt angles in deg.*/
`
`#define MAX_ALT
`#define MIN_ALT
`
`17000
`
`0
`
`/* maximum altitude for missle
`/* minimum altitude for missle
`
`*/
`
`*/
`
`#define INIT_SPEED
`#defineMIN_SPEED
`#defineMAX‘SPEED
`
`200
`0
`400
`
`/* init, min and max spd (kts) for missle */
`
`#define INIT_FOVY
`
`550
`
`/* initial field of view in tenth degrees */
`
`165
`
`178
`
`178
`
`
`
`0
`
`/* lndicies for array obj
`
`6
`
`/* Indicies for array tag
`
`#define
`#define
`#define
`#define
`#define
`#define
`#define
`
`CONTOUR
`SCREENI
`SCREEN?
`SCREEN3
`INSTR
`STATS
`FLTPATH
`
`#define LAUNCH
`#define
`TARGET
`#define
`DIR
`#define
`HEAD
`#define
`TOT
`#define MISSILE
`
`4
`
`1
`2
`3
`4
`5
`
`O
`1
`2
`3
`
`5
`
`#defineMAX_TGT_COLOR 847
`#defineMIN_TGT_COLOR 668
`
`#define MAX_TGTS
`
`100
`
`#define
`
`SAVEMAP
`
`OXOOCO
`
`166
`
`179
`
`179
`
`
`
`GAMMARAMP
`
`/*
`
`This routine puts a gamma-corrected color ramp into the color map.
`
`*/
`
`#include <math.h>
`
`gammaram p(gammaconst ,firstcolor,ncolors,
`brightred,brightgreen,brightblue,
`darkred,darkgreen,darkblue)
`
`float gammaconst;
`
`/* Strength of Gamma correction (try 1.0) */
`
`long firstcolor;
`
`/"= index number of the first color to set ="/
`
`long ncolors;
`
`/* the number of colors to set */
`
`long brightred,brightgreen,brightblue;
`
`/* the bright end of the ramp */
`
`long darkred,darkgreen,darkblue;
`
`/* the dark end of the ramp
`
`*/
`
`{
`
`long i;
`
`/* temp loop index */
`
`float scl;
`
`/* scale factor for gamma correction */
`
`long gcred,gcgreen,gcblue;
`
`/* gamma corrected colors */
`
`for(i=0; i < ncolors; i++) /* for all colors...*/
`{
`
`/* compute the scale factor */
`scl = pow((float)i/[float)(ncolorS-l) , 1.0/gammaconst);
`
`/* compute the gamma corrected colors */
`gcred 2 SC] * (brightred - darkred) + darkred;
`gcgreen = scl * (brightgreen - darkgreen) + darkgreen;
`gcblue 2 SC] * (brightblue - darkblue) + darkblue;
`
`mapcolor(firstcolor+i, gcred, gcgreen, gcblue); /* set the color */
`
`167
`
`180
`
`180
`
`
`
`—'r'.
`
`GET_TGT_POS
`
`/* get targets’ positions from irisl if networking. Otherwise moves 10 targets
`in straight lines, reversing when they hit an edge
`*/
`
`#include "fogm.h"
`#include "gl.h"
`#include "math.h”
`#include <sys/types.h>
`#include <sys/times.h>
`
`/* contains the time sturcture tms */
`/* for time calls */
`
`get_tgt_posit(socket,designate,tgt_idx,tgtx,tgty,tgtz,tank)
`
`int socket, designate, tgt_idx;
`float *tgtx, *tgty, *tgtz;
`Object tank;
`
`{
`
`extern float tgtipos[MAXiTGTS] [3];
`extern float randx, randy, randz;
`extern Object target[99](99];
`extern short tgt_grid_idx[MAX_TGTS](2};
`extern short tgt_total, tgt_dir[MAX_TGTS];
`short i, tgt_num;
`int nbyte, addl();
`float gnd_level(), dir, dx, dz, distance;
`long dist, d2;
`static long seconds;
`static long lastsec = -999;
`struct trns timestruct;
`
`/* -999 is flag to indicate no value */
`
`seconds = times(×truct );
`
`if (lastsec == -999)
`distance 2 0.0;
`
`else
`
`/* compute distance targets move ahead */
`
`distance = (float)((15.0/FPS_TO_KTS)*(seconds - lastsec”;
`
`lastsec = seconds;
`
`/* save for next pass */
`
`/* delete targets from old positions */
`i < tgt_total; i++)
`for (i : O;
`if (target[tgt_grid_idx[i][0]][tgt_grid_idx[i][1”) {
`delobj(target(tgt_grid_idx(i][0]][tgt_grid_idx[i][l|]);
`targetitgt_grid_idx[i][0]][tgt_grid_idx[i]|l]] = 0;
`
`}
`
`if (NETWORKING) (
`nbyte = read(socket, &tgt_total, sizeof(tgt_total));
`for (i = 0; i < tgt_total; i++) (
`nbyte 2 read (socket, &tgt_grid_idx[i}[0], sizeof(short]);
`nbyte = read(socket, &tgt_grid_idx[i](l], sizeof(short]);
`
`168
`
`181
`
`181
`
`
`
`nbyte = read(socket, &tgt._pos[i][0], sizeof(float)),
`nbyte = read(socket, &tgt_pos[i][l], sizeof(float)]'
`1
`(
`l
`nbyte = read socket, &Lgt_p05[i][2], sizeof(float)
`(
`nbyte : read sock