2 * $Logfile: /Freespace2/code/Mission/MissionGrid.cpp $
7 * C module for grid specific functions
10 * Revision 1.1 2002/05/03 03:28:09 root
14 * 2 10/07/98 10:53a Dave
17 * 1 10/07/98 10:49a Dave
19 * 7 10/03/97 8:55a John
20 * moved Fred's grid_render code out of MissionGrid and into Fred. Added
21 * code to turn background under overlays grey.
23 * 6 7/28/97 2:21p John
24 * changed vecmat functions to not return src. Started putting in code
25 * for inline vector math. Fixed some bugs with optimizer.
27 * 5 7/14/97 12:04a Lawrance
28 * added function that navmap calls to draw elevation lines
30 * 4 6/24/97 3:47p Hoffoss
31 * Changed the default grid elevation to 0 instead of -10.
33 * 3 6/18/97 11:36p Lawrance
34 * move grid rendering code to MissionGrid.cpp
36 * 2 6/12/97 11:25a Lawrance
37 * added grid_read_camera_controls()
39 * 1 6/12/97 10:17a Lawrance
46 #include "missiongrid.h"
54 int double_fine_gridlines = 0;
56 void grid_read_camera_controls( control_info * ci, float frametime )
61 float temp = ci->heading;
62 float temp1 = ci->pitch;
63 memset( ci, 0, sizeof(control_info) );
69 kh = key_down_timef(KEY_PAD6) - key_down_timef(KEY_PAD4);
73 if (ci->heading < 0.0f)
76 if (ci->heading > 0.0f)
80 kh = key_down_timef(KEY_PAD8) - key_down_timef(KEY_PAD2);
91 ci->bank = (key_down_timef(KEY_PAD7) - key_down_timef(KEY_PAD9));
92 ci->forward = (key_down_timef(KEY_A) - key_down_timef(KEY_Z));
93 ci->sideways = (key_down_timef(KEY_PAD3) - key_down_timef(KEY_PAD1));
94 ci->vertical = (key_down_timef(KEY_PADMINUS) - key_down_timef(KEY_PADPLUS));
97 // Project the viewer's position onto the grid plane. If more than threshold distance
98 // from grid center, move grid center.
99 void maybe_create_new_grid(grid* gridp, vector *pos, matrix *orient, int force)
105 float square_size, ux, uy, uz;
107 ux = tplane.A = gridp->gmatrix.uvec.x;
108 uy = tplane.B = gridp->gmatrix.uvec.y;
109 uz = tplane.C = gridp->gmatrix.uvec.z;
110 tplane.D = gridp->planeD;
112 compute_point_on_plane(&c, &tplane, pos);
113 dist_to_plane = fl_abs(vm_dist_to_plane(pos, &gridp->gmatrix.uvec, &c));
115 while (dist_to_plane >= 25.0f)
117 square_size *= 10.0f;
118 dist_to_plane /= 10.0f;
121 if (fvi_ray_plane(&gpos, &gridp->center, &gridp->gmatrix.uvec, pos, &orient->fvec, 0.0f)<0.0f) {
123 vm_vec_scale_add(&p,pos,&orient->fvec, 100.0f );
124 compute_point_on_plane(&gpos, &tplane, &p );
127 if (vm_vec_dist(&gpos, &c) > 50.0f * square_size)
129 vm_vec_sub(&tmp, &gpos, &c);
130 vm_vec_normalize(&tmp);
131 vm_vec_scale_add(&gpos, &c, &tmp, 50.0f * square_size);
134 roundoff = (int) square_size * 10;
136 gpos.x = fl_roundoff(gpos.x, roundoff);
138 gpos.y = fl_roundoff(gpos.y, roundoff);
140 gpos.z = fl_roundoff(gpos.z, roundoff);
142 if ((square_size != gridp->square_size) ||
143 (gpos.x != gridp->center.x) ||
144 (gpos.y != gridp->center.y) ||
145 (gpos.z != gridp->center.z) || force)
147 gridp->square_size = square_size;
148 gridp->center = gpos;
154 // *forward is vector pointing forward
155 // *right is vector pointing right
156 // *center is center point of grid
157 // length is length of grid
158 // width is width of grid
159 // square_size is size of a grid square
161 // *forward = (0.0, 0.0, 1.0)
162 // *right = (1.0, 0.0, 0.0)
163 // *center = (0.0, 0.0, 0.0)
166 // square_size = 10.0
167 // will generate a grid of squares 10 long by 5 wide.
168 // Each grid square will be 10.0 x 10.0 units.
169 // The center of the grid will be at the global origin.
170 // The grid will be parallel to the xz plane (because the normal is 0,1,0).
171 // (In fact, it will be the xz plane because it is centered on the origin.)
173 // Stuffs grid in *gridp. If gridp == NULL, mallocs and returns a grid.
174 grid *create_grid(grid *gridp, vector *forward, vector *right, vector *center, int nrows, int ncols, float square_size)
176 int i, ncols2, nrows2, d = 1;
177 vector dfvec, drvec, cur, cur2, tvec, uvec, save, save2;
179 Assert(square_size > 0.0);
180 if (double_fine_gridlines)
184 gridp = (grid *) malloc(sizeof(grid));
188 gridp->center = *center;
189 gridp->square_size = square_size;
191 // Create the plane equation.
192 Assert(!IS_VEC_NULL(forward));
193 Assert(!IS_VEC_NULL(right));
195 vm_vec_copy_normalize(&dfvec, forward);
196 vm_vec_copy_normalize(&drvec, right);
198 vm_vec_cross(&uvec, &dfvec, &drvec);
200 Assert(!IS_VEC_NULL(&uvec));
202 gridp->gmatrix.uvec = uvec;
204 gridp->planeD = -(center->x * uvec.x + center->y * uvec.y + center->z * uvec.z);
205 Assert(!_isnan(gridp->planeD));
207 gridp->gmatrix.fvec = dfvec;
208 gridp->gmatrix.rvec = drvec;
210 vm_vec_scale(&dfvec, square_size);
211 vm_vec_scale(&drvec, square_size);
213 vm_vec_scale_add(&cur, center, &dfvec, (float) -nrows * d / 2);
214 vm_vec_scale_add2(&cur, &drvec, (float) -ncols * d / 2);
215 vm_vec_scale_add(&cur2, center, &dfvec, (float) -nrows * 5 / 2);
216 vm_vec_scale_add2(&cur2, &drvec, (float) -ncols * 5 / 2);
220 gridp->ncols = ncols;
221 gridp->nrows = nrows;
224 Assert(ncols < MAX_GRIDLINE_POINTS && nrows < MAX_GRIDLINE_POINTS);
226 // Create the points along the edges of the grid, so we can just draw lines
227 // between them to form the grid.
228 for (i=0; i<=ncols*d; i++) {
229 gridp->gpoints1[i] = cur; // small, dark gridline points
230 vm_vec_scale_add(&tvec, &cur, &dfvec, (float) nrows * d);
231 gridp->gpoints2[i] = tvec;
232 vm_vec_add2(&cur, &drvec);
235 for (i=0; i<=ncols2; i++) {
236 gridp->gpoints5[i] = cur2; // large, brighter gridline points
237 vm_vec_scale_add(&tvec, &cur2, &dfvec, (float) nrows2 * 10);
238 gridp->gpoints6[i] = tvec;
239 vm_vec_scale_add2(&cur2, &drvec, 10.0f);
244 for (i=0; i<=nrows*d; i++) {
245 gridp->gpoints3[i] = cur; // small, dark gridline points
246 vm_vec_scale_add(&tvec, &cur, &drvec, (float) ncols * d);
247 gridp->gpoints4[i] = tvec;
248 vm_vec_add2(&cur, &dfvec);
251 for (i=0; i<=nrows2; i++) {
252 gridp->gpoints7[i] = cur2; // large, brighter gridline points
253 vm_vec_scale_add(&tvec, &cur2, &drvec, (float) ncols2 * 10);
254 gridp->gpoints8[i] = tvec;
255 vm_vec_scale_add2(&cur2, &dfvec, 10.0f);
261 // Create a nice grid -- centered at origin, 10x10, 10.0 size squares, in xz plane.
262 grid *create_default_grid(void)
265 vector fvec, rvec, cvec;
267 rgrid = create_grid(&Global_grid, vm_vec_make(&fvec, 0.0f, 0.0f, 1.0f),
268 vm_vec_make(&rvec, 1.0f, 0.0f, 0.0f),
269 vm_vec_make(&cvec, 0.0f, 0.0f, 0.0f), 100, 100, 5.0f);
271 physics_init(&rgrid->physics);
275 // Rotate and project points and draw a line.
276 void rpd_line(vector *v0, vector *v1)
280 g3_rotate_vertex(&tv0, v0);
281 g3_rotate_vertex(&tv1, v1);
282 g3_draw_line(&tv0, &tv1);
286 void modify_grid(grid *gridp)
288 create_grid(gridp, &gridp->gmatrix.fvec, &gridp->gmatrix.rvec, &gridp->center,
289 gridp->nrows, gridp->ncols, gridp->square_size);
292 void grid_render_elevation_line(vector *pos, grid* gridp)
294 vector gpos; // Location of point on grid.
300 tplane.A = gridp->gmatrix.uvec.x;
301 tplane.B = gridp->gmatrix.uvec.y;
302 tplane.C = gridp->gmatrix.uvec.z;
303 tplane.D = gridp->planeD;
305 compute_point_on_plane(&gpos, &tplane, pos);
307 dxz = vm_vec_dist(pos, &gpos)/8.0f;
309 gv = &gridp->gmatrix.uvec;
310 if (gv->x * pos->x + gv->y * pos->y + gv->z * pos->z < -gridp->planeD)
311 gr_set_color(127, 127, 127);
313 gr_set_color(255, 255, 255); // white
315 rpd_line(&gpos, pos); // Line from grid to object center.
319 vm_vec_scale_add2(&gpos, &gridp->gmatrix.rvec, -dxz/2);
320 vm_vec_scale_add2(&gpos, &gridp->gmatrix.fvec, -dxz/2);
322 vm_vec_scale_add2(&tpos, &gridp->gmatrix.rvec, dxz/2);
323 vm_vec_scale_add2(&tpos, &gridp->gmatrix.fvec, dxz/2);
325 rpd_line(&gpos, &tpos);
327 vm_vec_scale_add2(&gpos, &gridp->gmatrix.rvec, dxz);
328 vm_vec_scale_add2(&tpos, &gridp->gmatrix.rvec, -dxz);
330 rpd_line(&gpos, &tpos);