~ubuntu-branches/ubuntu/maverick/acm/maverick

« back to all changes in this revision

Viewing changes to src/runway.c

  • Committer: Bazaar Package Importer
  • Author(s): Phil Brooke
  • Date: 2003-04-01 14:05:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030401140551-f6nsguhoi81jguav
Tags: upstream-5.0
ImportĀ upstreamĀ versionĀ 5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  acm : an aerial combat simulator for X
 
3
 *  Copyright (C) 1991-1997  Riley Rainey
 
4
 *
 
5
 *  This program is free software; you can redistribute it and/or modify
 
6
 *  it under the terms of the GNU General Public License as published by
 
7
 *  the Free Software Foundation; version 2 dated June, 1991.
 
8
 *
 
9
 *  This program is distributed in the hope that it will be useful,
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 *  GNU General Public License for more details.
 
13
 *
 
14
 *  You should have received a copy of the GNU General Public License
 
15
 *  along with this program;  if not, write to the Free Software
 
16
 *  Foundation, Inc., 675 Mass Ave., Cambridge, MA 02139, USA.
 
17
 */
 
18
 
 
19
/*
 
20
 *  Runway markings are designed to conform to FAA AC 150/5340-1G
 
21
 *  dated 9/27/93.
 
22
 */
 
23
 
 
24
#include "pm.h"
 
25
 
 
26
void
 
27
          AddSymmetricPolygons(VMatrix * RWYtoXYZ, double x, double y, int count,
 
28
                                                           double length, double width, double margin,
 
29
                                                           VPolygon ** p, int p_count);
 
30
 
 
31
#define CENTERLINE_WIDTH                FEETtoMETERS(3.0)
 
32
#define CENTERLINE_LENGTH               FEETtoMETERS(120.0)
 
33
#define CENTERLINE_X_OFFSET             FEETtoMETERS(400.0)
 
34
#define CENTERLINE_GAP                  FEETtoMETERS(80.0)
 
35
#define TOUCHDOWN_ZONE_WIDTH            FEETtoMETERS(6.0)
 
36
#define TOUCHDOWN_ZONE_LENGTH           FEETtoMETERS(75.0)
 
37
#define TOUCHDOWN_ZONE_OFFSET           FEETtoMETERS(500.0)
 
38
#define TOUCHDOWN_ZONE_MARGIN           FEETtoMETERS(5.0)
 
39
#define THRESHOLD_STRIPE_WIDTH          FEETtoMETERS(5.75)
 
40
#define THRESHOLD_STRIPE_LENGTH         FEETtoMETERS(150.0)
 
41
#define THRESHOLD_STRIPE_X_OFFSET       FEETtoMETERS(20.0)
 
42
#define THRESHOLD_STRIPE_Y_OFFSET       FEETtoMETERS(3.0)
 
43
#define THRESHOLD_STRIPE_MARGIN         FEETtoMETERS(5.75)
 
44
#define FIXED_MARKER_LENGTH             FEETtoMETERS(150.0)
 
45
#define FIXED_MARKER_WIDTH              FEETtoMETERS(30.0)
 
46
#define FIXED_MARKER_Y_OFFSET           FEETtoMETERS(3.0)
 
47
#define FIXED_MARKER_X_OFFSET           FEETtoMETERS(1000.0)
 
48
#define WHITE_PAINT                     "#ccc"
 
49
 
 
50
#define RUNWAY_CULL_DISTANCE            50000.0         /* fifty kilometers */
 
51
#define MARKING_CULL_DISTANCE           5000.0  /* five kilometers */
 
52
 
 
53
void
 
54
AddRunway(VMatrix * RWYtoXYZ, double length, double width, int flags,
 
55
                  VPolygon *** poly, int *poly_count)
 
56
{
 
57
        VPoint    tmp, vertex[8];
 
58
        double    start, stop, x, y;
 
59
        int       i, stripes;
 
60
        VPolygon **p;
 
61
 
 
62
        *poly_count = i = 0;
 
63
        p = (VPolygon **) Vmalloc(sizeof(VPolygon *));
 
64
 
 
65
/*
 
66
 *  First, add the runway surface polygon ...
 
67
 */
 
68
 
 
69
        tmp.x = length / 2.0;
 
70
        tmp.y = width / 2.0;
 
71
        tmp.z = 0.0;
 
72
        VTransform(&tmp, RWYtoXYZ, &vertex[0]);
 
73
        tmp.x = -length / 2.0;
 
74
        tmp.y = width / 2.0;
 
75
        tmp.z = 0.0;
 
76
        VTransform(&tmp, RWYtoXYZ, &vertex[1]);
 
77
        tmp.x = -length / 2.0;
 
78
        tmp.y = -width / 2.0;
 
79
        tmp.z = 0.0;
 
80
        VTransform(&tmp, RWYtoXYZ, &vertex[2]);
 
81
        tmp.x = length / 2.0;
 
82
        tmp.y = -width / 2.0;
 
83
        tmp.z = 0.0;
 
84
        VTransform(&tmp, RWYtoXYZ, &vertex[3]);
 
85
 
 
86
        p[i] = VCreatePolygon(4, vertex,
 
87
                                                  VAllocDepthCueuedColor("#b7b19f", 1));
 
88
        p[i]->flags |= PolyUseCullDistance;
 
89
        p[i]->cullDistance = RUNWAY_CULL_DISTANCE;
 
90
        i++;
 
91
 
 
92
/*
 
93
 *  Now the runway centerline markings.
 
94
 */
 
95
 
 
96
        start = (0.5 * -length) + CENTERLINE_X_OFFSET - 0.5 * CENTERLINE_LENGTH;
 
97
        stop = (0.5 * length) - CENTERLINE_X_OFFSET;
 
98
 
 
99
        for (x = start; x < stop; x += CENTERLINE_LENGTH + CENTERLINE_GAP) {
 
100
                tmp.x = x - CENTERLINE_LENGTH / 2.0;
 
101
                tmp.y = CENTERLINE_WIDTH / 2.0;
 
102
                tmp.z = 0.0;
 
103
                VTransform(&tmp, RWYtoXYZ, &vertex[0]);
 
104
                tmp.x = x + CENTERLINE_LENGTH / 2.0;
 
105
                tmp.y = CENTERLINE_WIDTH / 2.0;
 
106
                tmp.z = 0.0;
 
107
                VTransform(&tmp, RWYtoXYZ, &vertex[1]);
 
108
                tmp.x = x + CENTERLINE_LENGTH / 2.0;
 
109
                tmp.y = -CENTERLINE_WIDTH / 2.0;
 
110
                tmp.z = 0.0;
 
111
                VTransform(&tmp, RWYtoXYZ, &vertex[2]);
 
112
                tmp.x = x - CENTERLINE_LENGTH / 2.0;
 
113
                tmp.y = -CENTERLINE_WIDTH / 2.0;
 
114
                tmp.z = 0.0;
 
115
                VTransform(&tmp, RWYtoXYZ, &vertex[3]);
 
116
                p = realloc(p, sizeof(VPolygon *) * (i + 1));
 
117
                p[i] = VCreatePolygon(4, vertex,
 
118
                                                          VAllocDepthCueuedColor(WHITE_PAINT, 1));
 
119
                p[i]->flags |= PolyUseCullDistance;
 
120
                p[i]->cullDistance = MARKING_CULL_DISTANCE;
 
121
                i++;
 
122
        }
 
123
 
 
124
        /*
 
125
         * Runway threshold stripes
 
126
         */
 
127
 
 
128
        /* From the Aeronautical Information Manual */
 
129
 
 
130
        if (width >= 18.0) {
 
131
 
 
132
                stripes = 0;
 
133
 
 
134
                if (width >= 60.0) {
 
135
                        stripes = 16;
 
136
                }
 
137
                else if (width >= 45.0) {
 
138
                        stripes = 12;
 
139
                }
 
140
                else if (width >= 30.0) {
 
141
                        stripes = 8;
 
142
                }
 
143
                else if (width >= 23.0) {
 
144
                        stripes = 6;
 
145
                }
 
146
                else if (width >= 18.0) {
 
147
                        stripes = 4;
 
148
                }
 
149
 
 
150
                stripes >>= 1;
 
151
 
 
152
                x = 0.5 * length - THRESHOLD_STRIPE_X_OFFSET;
 
153
                y = width / 2.0 - THRESHOLD_STRIPE_Y_OFFSET;
 
154
 
 
155
                for (; stripes > 0; --stripes,
 
156
                         y -= THRESHOLD_STRIPE_WIDTH + THRESHOLD_STRIPE_MARGIN) {
 
157
 
 
158
                        p = realloc(p, sizeof(VPolygon *) * (i + 4));
 
159
 
 
160
                        tmp.x = x;
 
161
                        tmp.y = y;
 
162
                        tmp.z = 0.0;
 
163
                        VTransform(&tmp, RWYtoXYZ, &vertex[0]);
 
164
                        tmp.x = x - THRESHOLD_STRIPE_LENGTH;
 
165
                        tmp.y = y;
 
166
                        tmp.z = 0.0;
 
167
                        VTransform(&tmp, RWYtoXYZ, &vertex[1]);
 
168
                        tmp.x = x - THRESHOLD_STRIPE_LENGTH;
 
169
                        tmp.y = y - THRESHOLD_STRIPE_WIDTH;
 
170
                        tmp.z = 0.0;
 
171
                        VTransform(&tmp, RWYtoXYZ, &vertex[2]);
 
172
                        tmp.x = x;
 
173
                        tmp.y = y - THRESHOLD_STRIPE_WIDTH;
 
174
                        tmp.z = 0.0;
 
175
                        VTransform(&tmp, RWYtoXYZ, &vertex[3]);
 
176
                        p[i] = VCreatePolygon(4, vertex,
 
177
                                                                  VAllocDepthCueuedColor(WHITE_PAINT, 1));
 
178
                        p[i]->flags |= PolyUseCullDistance;
 
179
                        p[i]->cullDistance = MARKING_CULL_DISTANCE;
 
180
                        i++;
 
181
 
 
182
                        /*
 
183
                         *  Opposite stripe on same runway end
 
184
                         */
 
185
 
 
186
                        tmp.x = x;
 
187
                        tmp.y = -y;
 
188
                        tmp.z = 0.0;
 
189
                        VTransform(&tmp, RWYtoXYZ, &vertex[0]);
 
190
                        tmp.x = x;
 
191
                        tmp.y = -y + THRESHOLD_STRIPE_WIDTH;
 
192
                        tmp.z = 0.0;
 
193
                        VTransform(&tmp, RWYtoXYZ, &vertex[1]);
 
194
                        tmp.x = x - THRESHOLD_STRIPE_LENGTH;
 
195
                        tmp.y = -y + THRESHOLD_STRIPE_WIDTH;
 
196
                        tmp.z = 0.0;
 
197
                        VTransform(&tmp, RWYtoXYZ, &vertex[2]);
 
198
                        tmp.x = x - THRESHOLD_STRIPE_LENGTH;
 
199
                        tmp.y = -y;
 
200
                        tmp.z = 0.0;
 
201
                        VTransform(&tmp, RWYtoXYZ, &vertex[3]);
 
202
                        p[i] = VCreatePolygon(4, vertex,
 
203
                                                                  VAllocDepthCueuedColor(WHITE_PAINT, 1));
 
204
                        p[i]->flags |= PolyUseCullDistance;
 
205
                        p[i]->cullDistance = MARKING_CULL_DISTANCE;
 
206
                        i++;
 
207
 
 
208
                        /*
 
209
                         *  Stripe on opposite runway end
 
210
                         */
 
211
 
 
212
                        tmp.x = -x;
 
213
                        tmp.y = y;
 
214
                        tmp.z = 0.0;
 
215
                        VTransform(&tmp, RWYtoXYZ, &vertex[0]);
 
216
                        tmp.x = -x;
 
217
                        tmp.y = y - THRESHOLD_STRIPE_WIDTH;
 
218
                        tmp.z = 0.0;
 
219
                        VTransform(&tmp, RWYtoXYZ, &vertex[1]);
 
220
                        tmp.x = -x + THRESHOLD_STRIPE_LENGTH;
 
221
                        tmp.y = y - THRESHOLD_STRIPE_WIDTH;
 
222
                        tmp.z = 0.0;
 
223
                        VTransform(&tmp, RWYtoXYZ, &vertex[2]);
 
224
                        tmp.x = -x + THRESHOLD_STRIPE_LENGTH;
 
225
                        tmp.y = y;
 
226
                        tmp.z = 0.0;
 
227
                        VTransform(&tmp, RWYtoXYZ, &vertex[3]);
 
228
                        p[i] = VCreatePolygon(4, vertex,
 
229
                                                                  VAllocDepthCueuedColor(WHITE_PAINT, 1));
 
230
                        p[i]->flags |= PolyUseCullDistance;
 
231
                        p[i]->cullDistance = MARKING_CULL_DISTANCE;
 
232
                        i++;
 
233
 
 
234
                        /*
 
235
                         *  Opposite stripe on opposite runway end
 
236
                         */
 
237
 
 
238
                        tmp.x = -x;
 
239
                        tmp.y = -y;
 
240
                        tmp.z = 0.0;
 
241
                        VTransform(&tmp, RWYtoXYZ, &vertex[0]);
 
242
                        tmp.x = -x + THRESHOLD_STRIPE_LENGTH;
 
243
                        tmp.y = -y;
 
244
                        tmp.z = 0.0;
 
245
                        VTransform(&tmp, RWYtoXYZ, &vertex[1]);
 
246
                        tmp.x = -x + THRESHOLD_STRIPE_LENGTH;
 
247
                        tmp.y = -y + THRESHOLD_STRIPE_WIDTH;
 
248
                        tmp.z = 0.0;
 
249
                        VTransform(&tmp, RWYtoXYZ, &vertex[2]);
 
250
                        tmp.x = -x;
 
251
                        tmp.y = -y + THRESHOLD_STRIPE_WIDTH;
 
252
                        tmp.z = 0.0;
 
253
                        VTransform(&tmp, RWYtoXYZ, &vertex[3]);
 
254
                        p[i] = VCreatePolygon(4, vertex,
 
255
                                                                  VAllocDepthCueuedColor(WHITE_PAINT, 1));
 
256
                        p[i]->flags |= PolyUseCullDistance;
 
257
                        p[i]->cullDistance = MARKING_CULL_DISTANCE;
 
258
                        i++;
 
259
                }
 
260
 
 
261
        }
 
262
 
 
263
        /*
 
264
         *  Fixed distance marker
 
265
         */
 
266
 
 
267
        if (length > FEETtoMETERS(3000.0)) {
 
268
 
 
269
                p = realloc(p, sizeof(VPolygon *) * (i + 4));
 
270
 
 
271
                AddSymmetricPolygons(RWYtoXYZ,
 
272
                                                         0.5 * length - FIXED_MARKER_X_OFFSET,
 
273
                                                         0.5 * width - FIXED_MARKER_Y_OFFSET,
 
274
                                                         1,
 
275
                                                         FIXED_MARKER_LENGTH, FIXED_MARKER_WIDTH, 0.0,
 
276
                                                         p, i);
 
277
 
 
278
                i += 4;
 
279
        }
 
280
 
 
281
        *poly_count = i;
 
282
        *poly = p;
 
283
}
 
284
 
 
285
void
 
286
AddSymmetricPolygons(VMatrix * RWYtoXYZ, double x, double y, int count,
 
287
                                         double length, double width, double margin,
 
288
                                         VPolygon ** p, int p_count)
 
289
{
 
290
        VPoint    tmp, vertex[4];
 
291
 
 
292
        for (; count > 0; --count, y -= width + margin) {
 
293
                tmp.x = x;
 
294
                tmp.y = y;
 
295
                tmp.z = 0.0;
 
296
                VTransform(&tmp, RWYtoXYZ, &vertex[0]);
 
297
                tmp.x = x - length;
 
298
                tmp.y = y;
 
299
                tmp.z = 0.0;
 
300
                VTransform(&tmp, RWYtoXYZ, &vertex[1]);
 
301
                tmp.x = x - length;
 
302
                tmp.y = y - width;
 
303
                tmp.z = 0.0;
 
304
                VTransform(&tmp, RWYtoXYZ, &vertex[2]);
 
305
                tmp.x = x;
 
306
                tmp.y = y - width;
 
307
                tmp.z = 0.0;
 
308
                VTransform(&tmp, RWYtoXYZ, &vertex[3]);
 
309
                p[p_count] = VCreatePolygon(4, vertex,
 
310
                                                                 VAllocDepthCueuedColor(WHITE_PAINT, 1));
 
311
                p[p_count]->flags |= PolyUseCullDistance;
 
312
                p[p_count]->cullDistance = MARKING_CULL_DISTANCE;
 
313
                p_count++;
 
314
 
 
315
                /*
 
316
                 *  Opposite stripe on same runway end
 
317
                 */
 
318
 
 
319
                tmp.x = x;
 
320
                tmp.y = -y;
 
321
                tmp.z = 0.0;
 
322
                VTransform(&tmp, RWYtoXYZ, &vertex[0]);
 
323
                tmp.x = x;
 
324
                tmp.y = -y + width;
 
325
                tmp.z = 0.0;
 
326
                VTransform(&tmp, RWYtoXYZ, &vertex[1]);
 
327
                tmp.x = x - length;
 
328
                tmp.y = -y + width;
 
329
                tmp.z = 0.0;
 
330
                VTransform(&tmp, RWYtoXYZ, &vertex[2]);
 
331
                tmp.x = x - length;
 
332
                tmp.y = -y;
 
333
                tmp.z = 0.0;
 
334
                VTransform(&tmp, RWYtoXYZ, &vertex[3]);
 
335
                p[p_count] = VCreatePolygon(4, vertex,
 
336
                                                                 VAllocDepthCueuedColor(WHITE_PAINT, 1));
 
337
                p[p_count]->flags |= PolyUseCullDistance;
 
338
                p[p_count]->cullDistance = MARKING_CULL_DISTANCE;
 
339
                p_count++;
 
340
 
 
341
                /*
 
342
                 *  Stripe on opposite runway end
 
343
                 */
 
344
 
 
345
                tmp.x = -x;
 
346
                tmp.y = y;
 
347
                tmp.z = 0.0;
 
348
                VTransform(&tmp, RWYtoXYZ, &vertex[0]);
 
349
                tmp.x = -x;
 
350
                tmp.y = y - width;
 
351
                tmp.z = 0.0;
 
352
                VTransform(&tmp, RWYtoXYZ, &vertex[1]);
 
353
                tmp.x = -x + length;
 
354
                tmp.y = y - width;
 
355
                tmp.z = 0.0;
 
356
                VTransform(&tmp, RWYtoXYZ, &vertex[2]);
 
357
                tmp.x = -x + length;
 
358
                tmp.y = y;
 
359
                tmp.z = 0.0;
 
360
                VTransform(&tmp, RWYtoXYZ, &vertex[3]);
 
361
                p[p_count] = VCreatePolygon(4, vertex,
 
362
                                                                 VAllocDepthCueuedColor(WHITE_PAINT, 1));
 
363
                p[p_count]->flags |= PolyUseCullDistance;
 
364
                p[p_count]->cullDistance = MARKING_CULL_DISTANCE;
 
365
                p_count++;
 
366
 
 
367
                /*
 
368
                 *  Opposite stripe on opposite runway end
 
369
                 */
 
370
 
 
371
                tmp.x = -x;
 
372
                tmp.y = -y;
 
373
                tmp.z = 0.0;
 
374
                VTransform(&tmp, RWYtoXYZ, &vertex[0]);
 
375
                tmp.x = -x + length;
 
376
                tmp.y = -y;
 
377
                tmp.z = 0.0;
 
378
                VTransform(&tmp, RWYtoXYZ, &vertex[1]);
 
379
                tmp.x = -x + length;
 
380
                tmp.y = -y + width;
 
381
                tmp.z = 0.0;
 
382
                VTransform(&tmp, RWYtoXYZ, &vertex[2]);
 
383
                tmp.x = -x;
 
384
                tmp.y = -y + width;
 
385
                tmp.z = 0.0;
 
386
                VTransform(&tmp, RWYtoXYZ, &vertex[3]);
 
387
                p[p_count] = VCreatePolygon(4, vertex,
 
388
                                                                 VAllocDepthCueuedColor(WHITE_PAINT, 1));
 
389
                p[p_count]->flags |= PolyUseCullDistance;
 
390
                p[p_count]->cullDistance = MARKING_CULL_DISTANCE;
 
391
                p_count++;
 
392
        }
 
393
}