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.4 2002/06/17 06:33:09 relnev
19 * ryan's struct patch for gcc 2.95
21 * Revision 1.3 2002/06/09 04:41:22 relnev
22 * added copyright header
24 * Revision 1.2 2002/05/07 03:16:46 theoddone33
25 * The Great Newline Fix
27 * Revision 1.1.1.1 2002/05/03 03:28:09 root
31 * 2 10/07/98 10:53a Dave
34 * 1 10/07/98 10:49a Dave
36 * 7 10/03/97 8:55a John
37 * moved Fred's grid_render code out of MissionGrid and into Fred. Added
38 * code to turn background under overlays grey.
40 * 6 7/28/97 2:21p John
41 * changed vecmat functions to not return src. Started putting in code
42 * for inline vector math. Fixed some bugs with optimizer.
44 * 5 7/14/97 12:04a Lawrance
45 * added function that navmap calls to draw elevation lines
47 * 4 6/24/97 3:47p Hoffoss
48 * Changed the default grid elevation to 0 instead of -10.
50 * 3 6/18/97 11:36p Lawrance
51 * move grid rendering code to MissionGrid.cpp
53 * 2 6/12/97 11:25a Lawrance
54 * added grid_read_camera_controls()
56 * 1 6/12/97 10:17a Lawrance
63 #include "missiongrid.h"
71 int double_fine_gridlines = 0;
73 void grid_read_camera_controls( control_info * ci, float frametime )
78 float temp = ci->heading;
79 float temp1 = ci->pitch;
80 memset( ci, 0, sizeof(control_info) );
86 kh = key_down_timef(SDLK_KP_6) - key_down_timef(SDLK_KP_4);
90 if (ci->heading < 0.0f)
93 if (ci->heading > 0.0f)
97 kh = key_down_timef(SDLK_KP_8) - key_down_timef(SDLK_KP_2);
100 else if (kh > 0.0f) {
101 if (ci->pitch < 0.0f)
104 if (ci->pitch > 0.0f)
108 ci->bank = (key_down_timef(SDLK_KP_7) - key_down_timef(SDLK_KP_9));
109 ci->forward = (key_down_timef(SDLK_a) - key_down_timef(SDLK_z));
110 ci->sideways = (key_down_timef(SDLK_KP_3) - key_down_timef(SDLK_KP_1));
111 ci->vertical = (key_down_timef(SDLK_KP_MINUS) - key_down_timef(SDLK_KP_PLUS));
114 // Project the viewer's position onto the grid plane. If more than threshold distance
115 // from grid center, move grid center.
116 void maybe_create_new_grid(grid* gridp, vector *pos, matrix *orient, int force)
122 float square_size, ux, uy, uz;
124 ux = tplane.A = gridp->gmatrix.v.uvec.xyz.x;
125 uy = tplane.B = gridp->gmatrix.v.uvec.xyz.y;
126 uz = tplane.C = gridp->gmatrix.v.uvec.xyz.z;
127 tplane.D = gridp->planeD;
129 compute_point_on_plane(&c, &tplane, pos);
130 dist_to_plane = fl_abs(vm_dist_to_plane(pos, &gridp->gmatrix.v.uvec, &c));
132 while (dist_to_plane >= 25.0f)
134 square_size *= 10.0f;
135 dist_to_plane /= 10.0f;
138 if (fvi_ray_plane(&gpos, &gridp->center, &gridp->gmatrix.v.uvec, pos, &orient->v.fvec, 0.0f)<0.0f) {
140 vm_vec_scale_add(&p,pos,&orient->v.fvec, 100.0f );
141 compute_point_on_plane(&gpos, &tplane, &p );
144 if (vm_vec_dist(&gpos, &c) > 50.0f * square_size)
146 vm_vec_sub(&tmp, &gpos, &c);
147 vm_vec_normalize(&tmp);
148 vm_vec_scale_add(&gpos, &c, &tmp, 50.0f * square_size);
151 roundoff = (int) square_size * 10;
153 gpos.xyz.x = fl_roundoff(gpos.xyz.x, roundoff);
155 gpos.xyz.y = fl_roundoff(gpos.xyz.y, roundoff);
157 gpos.xyz.z = fl_roundoff(gpos.xyz.z, roundoff);
159 if ((square_size != gridp->square_size) ||
160 (gpos.xyz.x != gridp->center.xyz.x) ||
161 (gpos.xyz.y != gridp->center.xyz.y) ||
162 (gpos.xyz.z != gridp->center.xyz.z) || force)
164 gridp->square_size = square_size;
165 gridp->center = gpos;
171 // *forward is vector pointing forward
172 // *right is vector pointing right
173 // *center is center point of grid
174 // length is length of grid
175 // width is width of grid
176 // square_size is size of a grid square
178 // *forward = (0.0, 0.0, 1.0)
179 // *right = (1.0, 0.0, 0.0)
180 // *center = (0.0, 0.0, 0.0)
183 // square_size = 10.0
184 // will generate a grid of squares 10 long by 5 wide.
185 // Each grid square will be 10.0 x 10.0 units.
186 // The center of the grid will be at the global origin.
187 // The grid will be parallel to the xz plane (because the normal is 0,1,0).
188 // (In fact, it will be the xz plane because it is centered on the origin.)
190 // Stuffs grid in *gridp. If gridp == NULL, mallocs and returns a grid.
191 grid *create_grid(grid *gridp, vector *forward, vector *right, vector *center, int nrows, int ncols, float square_size)
193 int i, ncols2, nrows2, d = 1;
194 vector dfvec, drvec, cur, cur2, tvec, uvec, save, save2;
196 SDL_assert(square_size > 0.0);
197 if (double_fine_gridlines)
201 gridp = (grid *) malloc(sizeof(grid));
205 gridp->center = *center;
206 gridp->square_size = square_size;
208 // Create the plane equation.
209 SDL_assert(!IS_VEC_NULL(forward));
210 SDL_assert(!IS_VEC_NULL(right));
212 vm_vec_copy_normalize(&dfvec, forward);
213 vm_vec_copy_normalize(&drvec, right);
215 vm_vec_cross(&uvec, &dfvec, &drvec);
217 SDL_assert(!IS_VEC_NULL(&uvec));
219 gridp->gmatrix.v.uvec = uvec;
221 gridp->planeD = -(center->xyz.x * uvec.xyz.x + center->xyz.y * uvec.xyz.y + center->xyz.z * uvec.xyz.z);
222 SDL_assert(!isnan(gridp->planeD));
224 gridp->gmatrix.v.fvec = dfvec;
225 gridp->gmatrix.v.rvec = drvec;
227 vm_vec_scale(&dfvec, square_size);
228 vm_vec_scale(&drvec, square_size);
230 vm_vec_scale_add(&cur, center, &dfvec, (float) -nrows * d / 2);
231 vm_vec_scale_add2(&cur, &drvec, (float) -ncols * d / 2);
232 vm_vec_scale_add(&cur2, center, &dfvec, (float) -nrows * 5 / 2);
233 vm_vec_scale_add2(&cur2, &drvec, (float) -ncols * 5 / 2);
237 gridp->ncols = ncols;
238 gridp->nrows = nrows;
241 SDL_assert(ncols < MAX_GRIDLINE_POINTS && nrows < MAX_GRIDLINE_POINTS);
243 // Create the points along the edges of the grid, so we can just draw lines
244 // between them to form the grid.
245 for (i=0; i<=ncols*d; i++) {
246 gridp->gpoints1[i] = cur; // small, dark gridline points
247 vm_vec_scale_add(&tvec, &cur, &dfvec, (float) nrows * d);
248 gridp->gpoints2[i] = tvec;
249 vm_vec_add2(&cur, &drvec);
252 for (i=0; i<=ncols2; i++) {
253 gridp->gpoints5[i] = cur2; // large, brighter gridline points
254 vm_vec_scale_add(&tvec, &cur2, &dfvec, (float) nrows2 * 10);
255 gridp->gpoints6[i] = tvec;
256 vm_vec_scale_add2(&cur2, &drvec, 10.0f);
261 for (i=0; i<=nrows*d; i++) {
262 gridp->gpoints3[i] = cur; // small, dark gridline points
263 vm_vec_scale_add(&tvec, &cur, &drvec, (float) ncols * d);
264 gridp->gpoints4[i] = tvec;
265 vm_vec_add2(&cur, &dfvec);
268 for (i=0; i<=nrows2; i++) {
269 gridp->gpoints7[i] = cur2; // large, brighter gridline points
270 vm_vec_scale_add(&tvec, &cur2, &drvec, (float) ncols2 * 10);
271 gridp->gpoints8[i] = tvec;
272 vm_vec_scale_add2(&cur2, &dfvec, 10.0f);
278 // Create a nice grid -- centered at origin, 10x10, 10.0 size squares, in xz plane.
279 grid *create_default_grid(void)
282 vector fvec, rvec, cvec;
284 rgrid = create_grid(&Global_grid, vm_vec_make(&fvec, 0.0f, 0.0f, 1.0f),
285 vm_vec_make(&rvec, 1.0f, 0.0f, 0.0f),
286 vm_vec_make(&cvec, 0.0f, 0.0f, 0.0f), 100, 100, 5.0f);
288 physics_init(&rgrid->physics);
292 // Rotate and project points and draw a line.
293 void rpd_line(vector *v0, vector *v1)
297 g3_rotate_vertex(&tv0, v0);
298 g3_rotate_vertex(&tv1, v1);
299 g3_draw_line(&tv0, &tv1);
303 void modify_grid(grid *gridp)
305 create_grid(gridp, &gridp->gmatrix.v.fvec, &gridp->gmatrix.v.rvec, &gridp->center,
306 gridp->nrows, gridp->ncols, gridp->square_size);
309 void grid_render_elevation_line(vector *pos, grid* gridp)
311 vector gpos; // Location of point on grid.
317 tplane.A = gridp->gmatrix.v.uvec.xyz.x;
318 tplane.B = gridp->gmatrix.v.uvec.xyz.y;
319 tplane.C = gridp->gmatrix.v.uvec.xyz.z;
320 tplane.D = gridp->planeD;
322 compute_point_on_plane(&gpos, &tplane, pos);
324 dxz = vm_vec_dist(pos, &gpos)/8.0f;
326 gv = &gridp->gmatrix.v.uvec;
327 if (gv->xyz.x * pos->xyz.x + gv->xyz.y * pos->xyz.y + gv->xyz.z * pos->xyz.z < -gridp->planeD)
328 gr_set_color(127, 127, 127);
330 gr_set_color(255, 255, 255); // white
332 rpd_line(&gpos, pos); // Line from grid to object center.
336 vm_vec_scale_add2(&gpos, &gridp->gmatrix.v.rvec, -dxz/2);
337 vm_vec_scale_add2(&gpos, &gridp->gmatrix.v.fvec, -dxz/2);
339 vm_vec_scale_add2(&tpos, &gridp->gmatrix.v.rvec, dxz/2);
340 vm_vec_scale_add2(&tpos, &gridp->gmatrix.v.fvec, dxz/2);
342 rpd_line(&gpos, &tpos);
344 vm_vec_scale_add2(&gpos, &gridp->gmatrix.v.rvec, dxz);
345 vm_vec_scale_add2(&tpos, &gridp->gmatrix.v.rvec, -dxz);
347 rpd_line(&gpos, &tpos);