2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/Mission/MissionGrid.cpp $
15 * C module for grid specific functions
18 * Revision 1.3 2002/06/09 04:41:22 relnev
19 * added copyright header
21 * Revision 1.2 2002/05/07 03:16:46 theoddone33
22 * The Great Newline Fix
24 * Revision 1.1.1.1 2002/05/03 03:28:09 root
28 * 2 10/07/98 10:53a Dave
31 * 1 10/07/98 10:49a Dave
33 * 7 10/03/97 8:55a John
34 * moved Fred's grid_render code out of MissionGrid and into Fred. Added
35 * code to turn background under overlays grey.
37 * 6 7/28/97 2:21p John
38 * changed vecmat functions to not return src. Started putting in code
39 * for inline vector math. Fixed some bugs with optimizer.
41 * 5 7/14/97 12:04a Lawrance
42 * added function that navmap calls to draw elevation lines
44 * 4 6/24/97 3:47p Hoffoss
45 * Changed the default grid elevation to 0 instead of -10.
47 * 3 6/18/97 11:36p Lawrance
48 * move grid rendering code to MissionGrid.cpp
50 * 2 6/12/97 11:25a Lawrance
51 * added grid_read_camera_controls()
53 * 1 6/12/97 10:17a Lawrance
60 #include "missiongrid.h"
68 int double_fine_gridlines = 0;
70 void grid_read_camera_controls( control_info * ci, float frametime )
75 float temp = ci->heading;
76 float temp1 = ci->pitch;
77 memset( ci, 0, sizeof(control_info) );
83 kh = key_down_timef(KEY_PAD6) - key_down_timef(KEY_PAD4);
87 if (ci->heading < 0.0f)
90 if (ci->heading > 0.0f)
94 kh = key_down_timef(KEY_PAD8) - key_down_timef(KEY_PAD2);
101 if (ci->pitch > 0.0f)
105 ci->bank = (key_down_timef(KEY_PAD7) - key_down_timef(KEY_PAD9));
106 ci->forward = (key_down_timef(KEY_A) - key_down_timef(KEY_Z));
107 ci->sideways = (key_down_timef(KEY_PAD3) - key_down_timef(KEY_PAD1));
108 ci->vertical = (key_down_timef(KEY_PADMINUS) - key_down_timef(KEY_PADPLUS));
111 // Project the viewer's position onto the grid plane. If more than threshold distance
112 // from grid center, move grid center.
113 void maybe_create_new_grid(grid* gridp, vector *pos, matrix *orient, int force)
119 float square_size, ux, uy, uz;
121 ux = tplane.A = gridp->gmatrix.uvec.x;
122 uy = tplane.B = gridp->gmatrix.uvec.y;
123 uz = tplane.C = gridp->gmatrix.uvec.z;
124 tplane.D = gridp->planeD;
126 compute_point_on_plane(&c, &tplane, pos);
127 dist_to_plane = fl_abs(vm_dist_to_plane(pos, &gridp->gmatrix.uvec, &c));
129 while (dist_to_plane >= 25.0f)
131 square_size *= 10.0f;
132 dist_to_plane /= 10.0f;
135 if (fvi_ray_plane(&gpos, &gridp->center, &gridp->gmatrix.uvec, pos, &orient->fvec, 0.0f)<0.0f) {
137 vm_vec_scale_add(&p,pos,&orient->fvec, 100.0f );
138 compute_point_on_plane(&gpos, &tplane, &p );
141 if (vm_vec_dist(&gpos, &c) > 50.0f * square_size)
143 vm_vec_sub(&tmp, &gpos, &c);
144 vm_vec_normalize(&tmp);
145 vm_vec_scale_add(&gpos, &c, &tmp, 50.0f * square_size);
148 roundoff = (int) square_size * 10;
150 gpos.x = fl_roundoff(gpos.x, roundoff);
152 gpos.y = fl_roundoff(gpos.y, roundoff);
154 gpos.z = fl_roundoff(gpos.z, roundoff);
156 if ((square_size != gridp->square_size) ||
157 (gpos.x != gridp->center.x) ||
158 (gpos.y != gridp->center.y) ||
159 (gpos.z != gridp->center.z) || force)
161 gridp->square_size = square_size;
162 gridp->center = gpos;
168 // *forward is vector pointing forward
169 // *right is vector pointing right
170 // *center is center point of grid
171 // length is length of grid
172 // width is width of grid
173 // square_size is size of a grid square
175 // *forward = (0.0, 0.0, 1.0)
176 // *right = (1.0, 0.0, 0.0)
177 // *center = (0.0, 0.0, 0.0)
180 // square_size = 10.0
181 // will generate a grid of squares 10 long by 5 wide.
182 // Each grid square will be 10.0 x 10.0 units.
183 // The center of the grid will be at the global origin.
184 // The grid will be parallel to the xz plane (because the normal is 0,1,0).
185 // (In fact, it will be the xz plane because it is centered on the origin.)
187 // Stuffs grid in *gridp. If gridp == NULL, mallocs and returns a grid.
188 grid *create_grid(grid *gridp, vector *forward, vector *right, vector *center, int nrows, int ncols, float square_size)
190 int i, ncols2, nrows2, d = 1;
191 vector dfvec, drvec, cur, cur2, tvec, uvec, save, save2;
193 Assert(square_size > 0.0);
194 if (double_fine_gridlines)
198 gridp = (grid *) malloc(sizeof(grid));
202 gridp->center = *center;
203 gridp->square_size = square_size;
205 // Create the plane equation.
206 Assert(!IS_VEC_NULL(forward));
207 Assert(!IS_VEC_NULL(right));
209 vm_vec_copy_normalize(&dfvec, forward);
210 vm_vec_copy_normalize(&drvec, right);
212 vm_vec_cross(&uvec, &dfvec, &drvec);
214 Assert(!IS_VEC_NULL(&uvec));
216 gridp->gmatrix.uvec = uvec;
218 gridp->planeD = -(center->x * uvec.x + center->y * uvec.y + center->z * uvec.z);
219 Assert(!_isnan(gridp->planeD));
221 gridp->gmatrix.fvec = dfvec;
222 gridp->gmatrix.rvec = drvec;
224 vm_vec_scale(&dfvec, square_size);
225 vm_vec_scale(&drvec, square_size);
227 vm_vec_scale_add(&cur, center, &dfvec, (float) -nrows * d / 2);
228 vm_vec_scale_add2(&cur, &drvec, (float) -ncols * d / 2);
229 vm_vec_scale_add(&cur2, center, &dfvec, (float) -nrows * 5 / 2);
230 vm_vec_scale_add2(&cur2, &drvec, (float) -ncols * 5 / 2);
234 gridp->ncols = ncols;
235 gridp->nrows = nrows;
238 Assert(ncols < MAX_GRIDLINE_POINTS && nrows < MAX_GRIDLINE_POINTS);
240 // Create the points along the edges of the grid, so we can just draw lines
241 // between them to form the grid.
242 for (i=0; i<=ncols*d; i++) {
243 gridp->gpoints1[i] = cur; // small, dark gridline points
244 vm_vec_scale_add(&tvec, &cur, &dfvec, (float) nrows * d);
245 gridp->gpoints2[i] = tvec;
246 vm_vec_add2(&cur, &drvec);
249 for (i=0; i<=ncols2; i++) {
250 gridp->gpoints5[i] = cur2; // large, brighter gridline points
251 vm_vec_scale_add(&tvec, &cur2, &dfvec, (float) nrows2 * 10);
252 gridp->gpoints6[i] = tvec;
253 vm_vec_scale_add2(&cur2, &drvec, 10.0f);
258 for (i=0; i<=nrows*d; i++) {
259 gridp->gpoints3[i] = cur; // small, dark gridline points
260 vm_vec_scale_add(&tvec, &cur, &drvec, (float) ncols * d);
261 gridp->gpoints4[i] = tvec;
262 vm_vec_add2(&cur, &dfvec);
265 for (i=0; i<=nrows2; i++) {
266 gridp->gpoints7[i] = cur2; // large, brighter gridline points
267 vm_vec_scale_add(&tvec, &cur2, &drvec, (float) ncols2 * 10);
268 gridp->gpoints8[i] = tvec;
269 vm_vec_scale_add2(&cur2, &dfvec, 10.0f);
275 // Create a nice grid -- centered at origin, 10x10, 10.0 size squares, in xz plane.
276 grid *create_default_grid(void)
279 vector fvec, rvec, cvec;
281 rgrid = create_grid(&Global_grid, vm_vec_make(&fvec, 0.0f, 0.0f, 1.0f),
282 vm_vec_make(&rvec, 1.0f, 0.0f, 0.0f),
283 vm_vec_make(&cvec, 0.0f, 0.0f, 0.0f), 100, 100, 5.0f);
285 physics_init(&rgrid->physics);
289 // Rotate and project points and draw a line.
290 void rpd_line(vector *v0, vector *v1)
294 g3_rotate_vertex(&tv0, v0);
295 g3_rotate_vertex(&tv1, v1);
296 g3_draw_line(&tv0, &tv1);
300 void modify_grid(grid *gridp)
302 create_grid(gridp, &gridp->gmatrix.fvec, &gridp->gmatrix.rvec, &gridp->center,
303 gridp->nrows, gridp->ncols, gridp->square_size);
306 void grid_render_elevation_line(vector *pos, grid* gridp)
308 vector gpos; // Location of point on grid.
314 tplane.A = gridp->gmatrix.uvec.x;
315 tplane.B = gridp->gmatrix.uvec.y;
316 tplane.C = gridp->gmatrix.uvec.z;
317 tplane.D = gridp->planeD;
319 compute_point_on_plane(&gpos, &tplane, pos);
321 dxz = vm_vec_dist(pos, &gpos)/8.0f;
323 gv = &gridp->gmatrix.uvec;
324 if (gv->x * pos->x + gv->y * pos->y + gv->z * pos->z < -gridp->planeD)
325 gr_set_color(127, 127, 127);
327 gr_set_color(255, 255, 255); // white
329 rpd_line(&gpos, pos); // Line from grid to object center.
333 vm_vec_scale_add2(&gpos, &gridp->gmatrix.rvec, -dxz/2);
334 vm_vec_scale_add2(&gpos, &gridp->gmatrix.fvec, -dxz/2);
336 vm_vec_scale_add2(&tpos, &gridp->gmatrix.rvec, dxz/2);
337 vm_vec_scale_add2(&tpos, &gridp->gmatrix.fvec, dxz/2);
339 rpd_line(&gpos, &tpos);
341 vm_vec_scale_add2(&gpos, &gridp->gmatrix.rvec, dxz);
342 vm_vec_scale_add2(&tpos, &gridp->gmatrix.rvec, -dxz);
344 rpd_line(&gpos, &tpos);