2 * $Logfile: /Freespace2/code/Mission/MissionGrid.cpp $
7 * C module for grid specific functions
10 * Revision 1.2 2002/05/07 03:16:46 theoddone33
11 * The Great Newline Fix
13 * Revision 1.1.1.1 2002/05/03 03:28:09 root
17 * 2 10/07/98 10:53a Dave
20 * 1 10/07/98 10:49a Dave
22 * 7 10/03/97 8:55a John
23 * moved Fred's grid_render code out of MissionGrid and into Fred. Added
24 * code to turn background under overlays grey.
26 * 6 7/28/97 2:21p John
27 * changed vecmat functions to not return src. Started putting in code
28 * for inline vector math. Fixed some bugs with optimizer.
30 * 5 7/14/97 12:04a Lawrance
31 * added function that navmap calls to draw elevation lines
33 * 4 6/24/97 3:47p Hoffoss
34 * Changed the default grid elevation to 0 instead of -10.
36 * 3 6/18/97 11:36p Lawrance
37 * move grid rendering code to MissionGrid.cpp
39 * 2 6/12/97 11:25a Lawrance
40 * added grid_read_camera_controls()
42 * 1 6/12/97 10:17a Lawrance
49 #include "missiongrid.h"
57 int double_fine_gridlines = 0;
59 void grid_read_camera_controls( control_info * ci, float frametime )
64 float temp = ci->heading;
65 float temp1 = ci->pitch;
66 memset( ci, 0, sizeof(control_info) );
72 kh = key_down_timef(KEY_PAD6) - key_down_timef(KEY_PAD4);
76 if (ci->heading < 0.0f)
79 if (ci->heading > 0.0f)
83 kh = key_down_timef(KEY_PAD8) - key_down_timef(KEY_PAD2);
94 ci->bank = (key_down_timef(KEY_PAD7) - key_down_timef(KEY_PAD9));
95 ci->forward = (key_down_timef(KEY_A) - key_down_timef(KEY_Z));
96 ci->sideways = (key_down_timef(KEY_PAD3) - key_down_timef(KEY_PAD1));
97 ci->vertical = (key_down_timef(KEY_PADMINUS) - key_down_timef(KEY_PADPLUS));
100 // Project the viewer's position onto the grid plane. If more than threshold distance
101 // from grid center, move grid center.
102 void maybe_create_new_grid(grid* gridp, vector *pos, matrix *orient, int force)
108 float square_size, ux, uy, uz;
110 ux = tplane.A = gridp->gmatrix.uvec.x;
111 uy = tplane.B = gridp->gmatrix.uvec.y;
112 uz = tplane.C = gridp->gmatrix.uvec.z;
113 tplane.D = gridp->planeD;
115 compute_point_on_plane(&c, &tplane, pos);
116 dist_to_plane = fl_abs(vm_dist_to_plane(pos, &gridp->gmatrix.uvec, &c));
118 while (dist_to_plane >= 25.0f)
120 square_size *= 10.0f;
121 dist_to_plane /= 10.0f;
124 if (fvi_ray_plane(&gpos, &gridp->center, &gridp->gmatrix.uvec, pos, &orient->fvec, 0.0f)<0.0f) {
126 vm_vec_scale_add(&p,pos,&orient->fvec, 100.0f );
127 compute_point_on_plane(&gpos, &tplane, &p );
130 if (vm_vec_dist(&gpos, &c) > 50.0f * square_size)
132 vm_vec_sub(&tmp, &gpos, &c);
133 vm_vec_normalize(&tmp);
134 vm_vec_scale_add(&gpos, &c, &tmp, 50.0f * square_size);
137 roundoff = (int) square_size * 10;
139 gpos.x = fl_roundoff(gpos.x, roundoff);
141 gpos.y = fl_roundoff(gpos.y, roundoff);
143 gpos.z = fl_roundoff(gpos.z, roundoff);
145 if ((square_size != gridp->square_size) ||
146 (gpos.x != gridp->center.x) ||
147 (gpos.y != gridp->center.y) ||
148 (gpos.z != gridp->center.z) || force)
150 gridp->square_size = square_size;
151 gridp->center = gpos;
157 // *forward is vector pointing forward
158 // *right is vector pointing right
159 // *center is center point of grid
160 // length is length of grid
161 // width is width of grid
162 // square_size is size of a grid square
164 // *forward = (0.0, 0.0, 1.0)
165 // *right = (1.0, 0.0, 0.0)
166 // *center = (0.0, 0.0, 0.0)
169 // square_size = 10.0
170 // will generate a grid of squares 10 long by 5 wide.
171 // Each grid square will be 10.0 x 10.0 units.
172 // The center of the grid will be at the global origin.
173 // The grid will be parallel to the xz plane (because the normal is 0,1,0).
174 // (In fact, it will be the xz plane because it is centered on the origin.)
176 // Stuffs grid in *gridp. If gridp == NULL, mallocs and returns a grid.
177 grid *create_grid(grid *gridp, vector *forward, vector *right, vector *center, int nrows, int ncols, float square_size)
179 int i, ncols2, nrows2, d = 1;
180 vector dfvec, drvec, cur, cur2, tvec, uvec, save, save2;
182 Assert(square_size > 0.0);
183 if (double_fine_gridlines)
187 gridp = (grid *) malloc(sizeof(grid));
191 gridp->center = *center;
192 gridp->square_size = square_size;
194 // Create the plane equation.
195 Assert(!IS_VEC_NULL(forward));
196 Assert(!IS_VEC_NULL(right));
198 vm_vec_copy_normalize(&dfvec, forward);
199 vm_vec_copy_normalize(&drvec, right);
201 vm_vec_cross(&uvec, &dfvec, &drvec);
203 Assert(!IS_VEC_NULL(&uvec));
205 gridp->gmatrix.uvec = uvec;
207 gridp->planeD = -(center->x * uvec.x + center->y * uvec.y + center->z * uvec.z);
208 Assert(!_isnan(gridp->planeD));
210 gridp->gmatrix.fvec = dfvec;
211 gridp->gmatrix.rvec = drvec;
213 vm_vec_scale(&dfvec, square_size);
214 vm_vec_scale(&drvec, square_size);
216 vm_vec_scale_add(&cur, center, &dfvec, (float) -nrows * d / 2);
217 vm_vec_scale_add2(&cur, &drvec, (float) -ncols * d / 2);
218 vm_vec_scale_add(&cur2, center, &dfvec, (float) -nrows * 5 / 2);
219 vm_vec_scale_add2(&cur2, &drvec, (float) -ncols * 5 / 2);
223 gridp->ncols = ncols;
224 gridp->nrows = nrows;
227 Assert(ncols < MAX_GRIDLINE_POINTS && nrows < MAX_GRIDLINE_POINTS);
229 // Create the points along the edges of the grid, so we can just draw lines
230 // between them to form the grid.
231 for (i=0; i<=ncols*d; i++) {
232 gridp->gpoints1[i] = cur; // small, dark gridline points
233 vm_vec_scale_add(&tvec, &cur, &dfvec, (float) nrows * d);
234 gridp->gpoints2[i] = tvec;
235 vm_vec_add2(&cur, &drvec);
238 for (i=0; i<=ncols2; i++) {
239 gridp->gpoints5[i] = cur2; // large, brighter gridline points
240 vm_vec_scale_add(&tvec, &cur2, &dfvec, (float) nrows2 * 10);
241 gridp->gpoints6[i] = tvec;
242 vm_vec_scale_add2(&cur2, &drvec, 10.0f);
247 for (i=0; i<=nrows*d; i++) {
248 gridp->gpoints3[i] = cur; // small, dark gridline points
249 vm_vec_scale_add(&tvec, &cur, &drvec, (float) ncols * d);
250 gridp->gpoints4[i] = tvec;
251 vm_vec_add2(&cur, &dfvec);
254 for (i=0; i<=nrows2; i++) {
255 gridp->gpoints7[i] = cur2; // large, brighter gridline points
256 vm_vec_scale_add(&tvec, &cur2, &drvec, (float) ncols2 * 10);
257 gridp->gpoints8[i] = tvec;
258 vm_vec_scale_add2(&cur2, &dfvec, 10.0f);
264 // Create a nice grid -- centered at origin, 10x10, 10.0 size squares, in xz plane.
265 grid *create_default_grid(void)
268 vector fvec, rvec, cvec;
270 rgrid = create_grid(&Global_grid, vm_vec_make(&fvec, 0.0f, 0.0f, 1.0f),
271 vm_vec_make(&rvec, 1.0f, 0.0f, 0.0f),
272 vm_vec_make(&cvec, 0.0f, 0.0f, 0.0f), 100, 100, 5.0f);
274 physics_init(&rgrid->physics);
278 // Rotate and project points and draw a line.
279 void rpd_line(vector *v0, vector *v1)
283 g3_rotate_vertex(&tv0, v0);
284 g3_rotate_vertex(&tv1, v1);
285 g3_draw_line(&tv0, &tv1);
289 void modify_grid(grid *gridp)
291 create_grid(gridp, &gridp->gmatrix.fvec, &gridp->gmatrix.rvec, &gridp->center,
292 gridp->nrows, gridp->ncols, gridp->square_size);
295 void grid_render_elevation_line(vector *pos, grid* gridp)
297 vector gpos; // Location of point on grid.
303 tplane.A = gridp->gmatrix.uvec.x;
304 tplane.B = gridp->gmatrix.uvec.y;
305 tplane.C = gridp->gmatrix.uvec.z;
306 tplane.D = gridp->planeD;
308 compute_point_on_plane(&gpos, &tplane, pos);
310 dxz = vm_vec_dist(pos, &gpos)/8.0f;
312 gv = &gridp->gmatrix.uvec;
313 if (gv->x * pos->x + gv->y * pos->y + gv->z * pos->z < -gridp->planeD)
314 gr_set_color(127, 127, 127);
316 gr_set_color(255, 255, 255); // white
318 rpd_line(&gpos, pos); // Line from grid to object center.
322 vm_vec_scale_add2(&gpos, &gridp->gmatrix.rvec, -dxz/2);
323 vm_vec_scale_add2(&gpos, &gridp->gmatrix.fvec, -dxz/2);
325 vm_vec_scale_add2(&tpos, &gridp->gmatrix.rvec, dxz/2);
326 vm_vec_scale_add2(&tpos, &gridp->gmatrix.fvec, dxz/2);
328 rpd_line(&gpos, &tpos);
330 vm_vec_scale_add2(&gpos, &gridp->gmatrix.rvec, dxz);
331 vm_vec_scale_add2(&tpos, &gridp->gmatrix.rvec, -dxz);
333 rpd_line(&gpos, &tpos);