~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/box2d/freeglut/freeglut_geometry.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * freeglut_geometry.c
 
3
 *
 
4
 * Freeglut geometry rendering methods.
 
5
 *
 
6
 * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
 
7
 * Written by Pawel W. Olszta, <olszta@sourceforge.net>
 
8
 * Creation date: Fri Dec 3 1999
 
9
 *
 
10
 * Permission is hereby granted, free of charge, to any person obtaining a
 
11
 * copy of this software and associated documentation files (the "Software"),
 
12
 * to deal in the Software without restriction, including without limitation
 
13
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
14
 * and/or sell copies of the Software, and to permit persons to whom the
 
15
 * Software is furnished to do so, subject to the following conditions:
 
16
 *
 
17
 * The above copyright notice and this permission notice shall be included
 
18
 * in all copies or substantial portions of the Software.
 
19
 *
 
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
21
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
22
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
23
 * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 
24
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
25
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
26
 */
 
27
 
 
28
#include "freeglut.h"
 
29
#include "freeglut_internal.h"
 
30
 
 
31
/*
 
32
 * TODO BEFORE THE STABLE RELEASE:
 
33
 *
 
34
 * Following functions have been contributed by Andreas Umbach.
 
35
 *
 
36
 *      glutWireCube()          -- looks OK
 
37
 *      glutSolidCube()         -- OK
 
38
 *
 
39
 * Those functions have been implemented by John Fay.
 
40
 *
 
41
 *      glutWireTorus()         -- looks OK
 
42
 *      glutSolidTorus()        -- looks OK
 
43
 *      glutWireDodecahedron()  -- looks OK
 
44
 *      glutSolidDodecahedron() -- looks OK
 
45
 *      glutWireOctahedron()    -- looks OK
 
46
 *      glutSolidOctahedron()   -- looks OK
 
47
 *      glutWireTetrahedron()   -- looks OK
 
48
 *      glutSolidTetrahedron()  -- looks OK
 
49
 *      glutWireIcosahedron()   -- looks OK
 
50
 *      glutSolidIcosahedron()  -- looks OK
 
51
 *
 
52
 *  The Following functions have been updated by Nigel Stewart, based
 
53
 *  on FreeGLUT 2.0.0 implementations:
 
54
 *
 
55
 *      glutWireSphere()        -- looks OK
 
56
 *      glutSolidSphere()       -- looks OK
 
57
 *      glutWireCone()          -- looks OK
 
58
 *      glutSolidCone()         -- looks OK
 
59
 */
 
60
 
 
61
 
 
62
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
 
63
 
 
64
/*
 
65
 * Draws a wireframed cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
 
66
 */
 
67
void FGAPIENTRY glutWireCube( GLdouble dSize )
 
68
{
 
69
    double size = dSize * 0.5;
 
70
 
 
71
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireCube" );
 
72
 
 
73
#   define V(a,b,c) glVertex3d( a size, b size, c size );
 
74
#   define N(a,b,c) glNormal3d( a, b, c );
 
75
 
 
76
    /* PWO: I dared to convert the code to use macros... */
 
77
    glBegin( GL_LINE_LOOP ); N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); glEnd();
 
78
    glBegin( GL_LINE_LOOP ); N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); glEnd();
 
79
    glBegin( GL_LINE_LOOP ); N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); glEnd();
 
80
    glBegin( GL_LINE_LOOP ); N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); glEnd();
 
81
    glBegin( GL_LINE_LOOP ); N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); glEnd();
 
82
    glBegin( GL_LINE_LOOP ); N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); glEnd();
 
83
 
 
84
#   undef V
 
85
#   undef N
 
86
}
 
87
 
 
88
/*
 
89
 * Draws a solid cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
 
90
 */
 
91
void FGAPIENTRY glutSolidCube( GLdouble dSize )
 
92
{
 
93
    double size = dSize * 0.5;
 
94
 
 
95
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidCube" );
 
96
 
 
97
#   define V(a,b,c) glVertex3d( a size, b size, c size );
 
98
#   define N(a,b,c) glNormal3d( a, b, c );
 
99
 
 
100
    /* PWO: Again, I dared to convert the code to use macros... */
 
101
    glBegin( GL_QUADS );
 
102
        N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+);
 
103
        N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+);
 
104
        N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+);
 
105
        N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-);
 
106
        N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+);
 
107
        N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-);
 
108
    glEnd();
 
109
 
 
110
#   undef V
 
111
#   undef N
 
112
}
 
113
 
 
114
/*
 
115
 * Compute lookup table of cos and sin values forming a cirle
 
116
 *
 
117
 * Notes:
 
118
 *    It is the responsibility of the caller to free these tables
 
119
 *    The size of the table is (n+1) to form a connected loop
 
120
 *    The last entry is exactly the same as the first
 
121
 *    The sign of n can be flipped to get the reverse loop
 
122
 */
 
123
 
 
124
static void fghCircleTable(double **sint,double **cost,const int n)
 
125
{
 
126
    int i;
 
127
 
 
128
    /* Table size, the sign of n flips the circle direction */
 
129
 
 
130
    const int size = abs(n);
 
131
 
 
132
    /* Determine the angle between samples */
 
133
 
 
134
    const double angle = 2*M_PI/(double)( ( n == 0 ) ? 1 : n );
 
135
 
 
136
    /* Allocate memory for n samples, plus duplicate of first entry at the end */
 
137
 
 
138
    *sint = (double *) calloc(sizeof(double), size+1);
 
139
    *cost = (double *) calloc(sizeof(double), size+1);
 
140
 
 
141
    /* Bail out if memory allocation fails, fgError never returns */
 
142
 
 
143
    if (!(*sint) || !(*cost))
 
144
    {
 
145
        free(*sint);
 
146
        free(*cost);
 
147
        fgError("Failed to allocate memory in fghCircleTable");
 
148
    }
 
149
 
 
150
    /* Compute cos and sin around the circle */
 
151
 
 
152
    (*sint)[0] = 0.0;
 
153
    (*cost)[0] = 1.0;
 
154
 
 
155
    for (i=1; i<size; i++)
 
156
    {
 
157
        (*sint)[i] = sin(angle*i);
 
158
        (*cost)[i] = cos(angle*i);
 
159
    }
 
160
 
 
161
    /* Last sample is duplicate of the first */
 
162
 
 
163
    (*sint)[size] = (*sint)[0];
 
164
    (*cost)[size] = (*cost)[0];
 
165
}
 
166
 
 
167
/*
 
168
 * Draws a solid sphere
 
169
 */
 
170
void FGAPIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
 
171
{
 
172
    int i,j;
 
173
 
 
174
    /* Adjust z and radius as stacks are drawn. */
 
175
 
 
176
    double z0,z1;
 
177
    double r0,r1;
 
178
 
 
179
    /* Pre-computed circle */
 
180
 
 
181
    double *sint1,*cost1;
 
182
    double *sint2,*cost2;
 
183
 
 
184
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidSphere" );
 
185
 
 
186
    fghCircleTable(&sint1,&cost1,-slices);
 
187
    fghCircleTable(&sint2,&cost2,stacks*2);
 
188
 
 
189
    /* The top stack is covered with a triangle fan */
 
190
 
 
191
    z0 = 1.0;
 
192
    z1 = cost2[(stacks>0)?1:0];
 
193
    r0 = 0.0;
 
194
    r1 = sint2[(stacks>0)?1:0];
 
195
 
 
196
    glBegin(GL_TRIANGLE_FAN);
 
197
 
 
198
        glNormal3d(0,0,1);
 
199
        glVertex3d(0,0,radius);
 
200
 
 
201
        for (j=slices; j>=0; j--)
 
202
        {
 
203
            glNormal3d(cost1[j]*r1,        sint1[j]*r1,        z1       );
 
204
            glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius);
 
205
        }
 
206
 
 
207
    glEnd();
 
208
 
 
209
    /* Cover each stack with a quad strip, except the top and bottom stacks */
 
210
 
 
211
    for( i=1; i<stacks-1; i++ )
 
212
    {
 
213
        z0 = z1; z1 = cost2[i+1];
 
214
        r0 = r1; r1 = sint2[i+1];
 
215
 
 
216
        glBegin(GL_QUAD_STRIP);
 
217
 
 
218
            for(j=0; j<=slices; j++)
 
219
            {
 
220
                glNormal3d(cost1[j]*r1,        sint1[j]*r1,        z1       );
 
221
                glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius);
 
222
                glNormal3d(cost1[j]*r0,        sint1[j]*r0,        z0       );
 
223
                glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius);
 
224
            }
 
225
 
 
226
        glEnd();
 
227
    }
 
228
 
 
229
    /* The bottom stack is covered with a triangle fan */
 
230
 
 
231
    z0 = z1;
 
232
    r0 = r1;
 
233
 
 
234
    glBegin(GL_TRIANGLE_FAN);
 
235
 
 
236
        glNormal3d(0,0,-1);
 
237
        glVertex3d(0,0,-radius);
 
238
 
 
239
        for (j=0; j<=slices; j++)
 
240
        {
 
241
            glNormal3d(cost1[j]*r0,        sint1[j]*r0,        z0       );
 
242
            glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius);
 
243
        }
 
244
 
 
245
    glEnd();
 
246
 
 
247
    /* Release sin and cos tables */
 
248
 
 
249
    free(sint1);
 
250
    free(cost1);
 
251
    free(sint2);
 
252
    free(cost2);
 
253
}
 
254
 
 
255
/*
 
256
 * Draws a wire sphere
 
257
 */
 
258
void FGAPIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
 
259
{
 
260
    int i,j;
 
261
 
 
262
    /* Adjust z and radius as stacks and slices are drawn. */
 
263
 
 
264
    double r;
 
265
    double x,y,z;
 
266
 
 
267
    /* Pre-computed circle */
 
268
 
 
269
    double *sint1,*cost1;
 
270
    double *sint2,*cost2;
 
271
 
 
272
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireSphere" );
 
273
 
 
274
    fghCircleTable(&sint1,&cost1,-slices  );
 
275
    fghCircleTable(&sint2,&cost2, stacks*2);
 
276
 
 
277
    /* Draw a line loop for each stack */
 
278
 
 
279
    for (i=1; i<stacks; i++)
 
280
    {
 
281
        z = cost2[i];
 
282
        r = sint2[i];
 
283
 
 
284
        glBegin(GL_LINE_LOOP);
 
285
 
 
286
            for(j=0; j<=slices; j++)
 
287
            {
 
288
                x = cost1[j];
 
289
                y = sint1[j];
 
290
 
 
291
                glNormal3d(x,y,z);
 
292
                glVertex3d(x*r*radius,y*r*radius,z*radius);
 
293
            }
 
294
 
 
295
        glEnd();
 
296
    }
 
297
 
 
298
    /* Draw a line loop for each slice */
 
299
 
 
300
    for (i=0; i<slices; i++)
 
301
    {
 
302
        glBegin(GL_LINE_STRIP);
 
303
 
 
304
            for(j=0; j<=stacks; j++)
 
305
            {
 
306
                x = cost1[i]*sint2[j];
 
307
                y = sint1[i]*sint2[j];
 
308
                z = cost2[j];
 
309
 
 
310
                glNormal3d(x,y,z);
 
311
                glVertex3d(x*radius,y*radius,z*radius);
 
312
            }
 
313
 
 
314
        glEnd();
 
315
    }
 
316
 
 
317
    /* Release sin and cos tables */
 
318
 
 
319
    free(sint1);
 
320
    free(cost1);
 
321
    free(sint2);
 
322
    free(cost2);
 
323
}
 
324
 
 
325
/*
 
326
 * Draws a solid cone
 
327
 */
 
328
void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks )
 
329
{
 
330
    int i,j;
 
331
 
 
332
    /* Step in z and radius as stacks are drawn. */
 
333
 
 
334
    double z0,z1;
 
335
    double r0,r1;
 
336
 
 
337
    const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 );
 
338
    const double rStep = base / ( ( stacks > 0 ) ? stacks : 1 );
 
339
 
 
340
    /* Scaling factors for vertex normals */
 
341
 
 
342
    const double cosn = ( height / sqrt ( height * height + base * base ));
 
343
    const double sinn = ( base   / sqrt ( height * height + base * base ));
 
344
 
 
345
    /* Pre-computed circle */
 
346
 
 
347
    double *sint,*cost;
 
348
 
 
349
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidCone" );
 
350
 
 
351
    fghCircleTable(&sint,&cost,-slices);
 
352
 
 
353
    /* Cover the circular base with a triangle fan... */
 
354
 
 
355
    z0 = 0.0;
 
356
    z1 = zStep;
 
357
 
 
358
    r0 = base;
 
359
    r1 = r0 - rStep;
 
360
 
 
361
    glBegin(GL_TRIANGLE_FAN);
 
362
 
 
363
        glNormal3d(0.0,0.0,-1.0);
 
364
        glVertex3d(0.0,0.0, z0 );
 
365
 
 
366
        for (j=0; j<=slices; j++)
 
367
            glVertex3d(cost[j]*r0, sint[j]*r0, z0);
 
368
 
 
369
    glEnd();
 
370
 
 
371
    /* Cover each stack with a quad strip, except the top stack */
 
372
 
 
373
    for( i=0; i<stacks-1; i++ )
 
374
    {
 
375
        glBegin(GL_QUAD_STRIP);
 
376
 
 
377
            for(j=0; j<=slices; j++)
 
378
            {
 
379
                glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn);
 
380
                glVertex3d(cost[j]*r0,   sint[j]*r0,   z0  );
 
381
                glVertex3d(cost[j]*r1,   sint[j]*r1,   z1  );
 
382
            }
 
383
 
 
384
            z0 = z1; z1 += zStep;
 
385
            r0 = r1; r1 -= rStep;
 
386
 
 
387
        glEnd();
 
388
    }
 
389
 
 
390
    /* The top stack is covered with individual triangles */
 
391
 
 
392
    glBegin(GL_TRIANGLES);
 
393
 
 
394
        glNormal3d(cost[0]*sinn, sint[0]*sinn, cosn);
 
395
 
 
396
        for (j=0; j<slices; j++)
 
397
        {
 
398
            glVertex3d(cost[j+0]*r0,   sint[j+0]*r0,   z0    );
 
399
            glVertex3d(0,              0,              height);
 
400
            glNormal3d(cost[j+1]*sinn, sint[j+1]*sinn, cosn  );
 
401
            glVertex3d(cost[j+1]*r0,   sint[j+1]*r0,   z0    );
 
402
        }
 
403
 
 
404
    glEnd();
 
405
 
 
406
    /* Release sin and cos tables */
 
407
 
 
408
    free(sint);
 
409
    free(cost);
 
410
}
 
411
 
 
412
/*
 
413
 * Draws a wire cone
 
414
 */
 
415
void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks)
 
416
{
 
417
    int i,j;
 
418
 
 
419
    /* Step in z and radius as stacks are drawn. */
 
420
 
 
421
    double z = 0.0;
 
422
    double r = base;
 
423
 
 
424
    const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 );
 
425
    const double rStep = base / ( ( stacks > 0 ) ? stacks : 1 );
 
426
 
 
427
    /* Scaling factors for vertex normals */
 
428
 
 
429
    const double cosn = ( height / sqrt ( height * height + base * base ));
 
430
    const double sinn = ( base   / sqrt ( height * height + base * base ));
 
431
 
 
432
    /* Pre-computed circle */
 
433
 
 
434
    double *sint,*cost;
 
435
 
 
436
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireCone" );
 
437
 
 
438
    fghCircleTable(&sint,&cost,-slices);
 
439
 
 
440
    /* Draw the stacks... */
 
441
 
 
442
    for (i=0; i<stacks; i++)
 
443
    {
 
444
        glBegin(GL_LINE_LOOP);
 
445
 
 
446
            for( j=0; j<slices; j++ )
 
447
            {
 
448
                glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn);
 
449
                glVertex3d(cost[j]*r,    sint[j]*r,    z   );
 
450
            }
 
451
 
 
452
        glEnd();
 
453
 
 
454
        z += zStep;
 
455
        r -= rStep;
 
456
    }
 
457
 
 
458
    /* Draw the slices */
 
459
 
 
460
    r = base;
 
461
 
 
462
    glBegin(GL_LINES);
 
463
 
 
464
        for (j=0; j<slices; j++)
 
465
        {
 
466
            glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn  );
 
467
            glVertex3d(cost[j]*r,    sint[j]*r,    0.0   );
 
468
            glVertex3d(0.0,          0.0,          height);
 
469
        }
 
470
 
 
471
    glEnd();
 
472
 
 
473
    /* Release sin and cos tables */
 
474
 
 
475
    free(sint);
 
476
    free(cost);
 
477
}
 
478
 
 
479
 
 
480
/*
 
481
 * Draws a solid cylinder
 
482
 */
 
483
void FGAPIENTRY glutSolidCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks)
 
484
{
 
485
    int i,j;
 
486
 
 
487
    /* Step in z and radius as stacks are drawn. */
 
488
 
 
489
    double z0,z1;
 
490
    const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 );
 
491
 
 
492
    /* Pre-computed circle */
 
493
 
 
494
    double *sint,*cost;
 
495
 
 
496
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidCylinder" );
 
497
 
 
498
    fghCircleTable(&sint,&cost,-slices);
 
499
 
 
500
    /* Cover the base and top */
 
501
 
 
502
    glBegin(GL_TRIANGLE_FAN);
 
503
        glNormal3d(0.0, 0.0, -1.0 );
 
504
        glVertex3d(0.0, 0.0,  0.0 );
 
505
        for (j=0; j<=slices; j++)
 
506
          glVertex3d(cost[j]*radius, sint[j]*radius, 0.0);
 
507
    glEnd();
 
508
 
 
509
    glBegin(GL_TRIANGLE_FAN);
 
510
        glNormal3d(0.0, 0.0, 1.0   );
 
511
        glVertex3d(0.0, 0.0, height);
 
512
        for (j=slices; j>=0; j--)
 
513
          glVertex3d(cost[j]*radius, sint[j]*radius, height);
 
514
    glEnd();
 
515
 
 
516
    /* Do the stacks */
 
517
 
 
518
    z0 = 0.0;
 
519
    z1 = zStep;
 
520
 
 
521
    for (i=1; i<=stacks; i++)
 
522
    {
 
523
        if (i==stacks)
 
524
            z1 = height;
 
525
 
 
526
        glBegin(GL_QUAD_STRIP);
 
527
            for (j=0; j<=slices; j++ )
 
528
            {
 
529
                glNormal3d(cost[j],        sint[j],        0.0 );
 
530
                glVertex3d(cost[j]*radius, sint[j]*radius, z0  );
 
531
                glVertex3d(cost[j]*radius, sint[j]*radius, z1  );
 
532
            }
 
533
        glEnd();
 
534
 
 
535
        z0 = z1; z1 += zStep;
 
536
    }
 
537
 
 
538
    /* Release sin and cos tables */
 
539
 
 
540
    free(sint);
 
541
    free(cost);
 
542
}
 
543
 
 
544
/*
 
545
 * Draws a wire cylinder
 
546
 */
 
547
void FGAPIENTRY glutWireCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks)
 
548
{
 
549
    int i,j;
 
550
 
 
551
    /* Step in z and radius as stacks are drawn. */
 
552
 
 
553
          double z = 0.0;
 
554
    const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 );
 
555
 
 
556
    /* Pre-computed circle */
 
557
 
 
558
    double *sint,*cost;
 
559
 
 
560
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireCylinder" );
 
561
 
 
562
    fghCircleTable(&sint,&cost,-slices);
 
563
 
 
564
    /* Draw the stacks... */
 
565
 
 
566
    for (i=0; i<=stacks; i++)
 
567
    {
 
568
        if (i==stacks)
 
569
            z = height;
 
570
 
 
571
        glBegin(GL_LINE_LOOP);
 
572
 
 
573
            for( j=0; j<slices; j++ )
 
574
            {
 
575
                glNormal3d(cost[j],        sint[j],        0.0);
 
576
                glVertex3d(cost[j]*radius, sint[j]*radius, z  );
 
577
            }
 
578
 
 
579
        glEnd();
 
580
 
 
581
        z += zStep;
 
582
    }
 
583
 
 
584
    /* Draw the slices */
 
585
 
 
586
    glBegin(GL_LINES);
 
587
 
 
588
        for (j=0; j<slices; j++)
 
589
        {
 
590
            glNormal3d(cost[j],        sint[j],        0.0   );
 
591
            glVertex3d(cost[j]*radius, sint[j]*radius, 0.0   );
 
592
            glVertex3d(cost[j]*radius, sint[j]*radius, height);
 
593
        }
 
594
 
 
595
    glEnd();
 
596
 
 
597
    /* Release sin and cos tables */
 
598
 
 
599
    free(sint);
 
600
    free(cost);
 
601
}
 
602
 
 
603
/*
 
604
 * Draws a wire torus
 
605
 */
 
606
void FGAPIENTRY glutWireTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings )
 
607
{
 
608
  double  iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi;
 
609
  double *vertex, *normal;
 
610
  int    i, j;
 
611
  double spsi, cpsi, sphi, cphi ;
 
612
 
 
613
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTorus" );
 
614
 
 
615
  if ( nSides < 1 ) nSides = 1;
 
616
  if ( nRings < 1 ) nRings = 1;
 
617
 
 
618
  /* Allocate the vertices array */
 
619
  vertex = (double *)calloc( sizeof(double), 3 * nSides * nRings );
 
620
  normal = (double *)calloc( sizeof(double), 3 * nSides * nRings );
 
621
 
 
622
  glPushMatrix();
 
623
 
 
624
  dpsi =  2.0 * M_PI / (double)nRings ;
 
625
  dphi = -2.0 * M_PI / (double)nSides ;
 
626
  psi  = 0.0;
 
627
 
 
628
  for( j=0; j<nRings; j++ )
 
629
  {
 
630
    cpsi = cos ( psi ) ;
 
631
    spsi = sin ( psi ) ;
 
632
    phi = 0.0;
 
633
 
 
634
    for( i=0; i<nSides; i++ )
 
635
    {
 
636
      int offset = 3 * ( j * nSides + i ) ;
 
637
      cphi = cos ( phi ) ;
 
638
      sphi = sin ( phi ) ;
 
639
      *(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ;
 
640
      *(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ;
 
641
      *(vertex + offset + 2) =                    sphi * iradius  ;
 
642
      *(normal + offset + 0) = cpsi * cphi ;
 
643
      *(normal + offset + 1) = spsi * cphi ;
 
644
      *(normal + offset + 2) =        sphi ;
 
645
      phi += dphi;
 
646
    }
 
647
 
 
648
    psi += dpsi;
 
649
  }
 
650
 
 
651
  for( i=0; i<nSides; i++ )
 
652
  {
 
653
    glBegin( GL_LINE_LOOP );
 
654
 
 
655
    for( j=0; j<nRings; j++ )
 
656
    {
 
657
      int offset = 3 * ( j * nSides + i ) ;
 
658
      glNormal3dv( normal + offset );
 
659
      glVertex3dv( vertex + offset );
 
660
    }
 
661
 
 
662
    glEnd();
 
663
  }
 
664
 
 
665
  for( j=0; j<nRings; j++ )
 
666
  {
 
667
    glBegin(GL_LINE_LOOP);
 
668
 
 
669
    for( i=0; i<nSides; i++ )
 
670
    {
 
671
      int offset = 3 * ( j * nSides + i ) ;
 
672
      glNormal3dv( normal + offset );
 
673
      glVertex3dv( vertex + offset );
 
674
    }
 
675
 
 
676
    glEnd();
 
677
  }
 
678
 
 
679
  free ( vertex ) ;
 
680
  free ( normal ) ;
 
681
  glPopMatrix();
 
682
}
 
683
 
 
684
/*
 
685
 * Draws a solid torus
 
686
 */
 
687
void FGAPIENTRY glutSolidTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings )
 
688
{
 
689
  double  iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi;
 
690
  double *vertex, *normal;
 
691
  int    i, j;
 
692
  double spsi, cpsi, sphi, cphi ;
 
693
 
 
694
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTorus" );
 
695
 
 
696
  if ( nSides < 1 ) nSides = 1;
 
697
  if ( nRings < 1 ) nRings = 1;
 
698
 
 
699
  /* Increment the number of sides and rings to allow for one more point than surface */
 
700
  nSides ++ ;
 
701
  nRings ++ ;
 
702
 
 
703
  /* Allocate the vertices array */
 
704
  vertex = (double *)calloc( sizeof(double), 3 * nSides * nRings );
 
705
  normal = (double *)calloc( sizeof(double), 3 * nSides * nRings );
 
706
 
 
707
  glPushMatrix();
 
708
 
 
709
  dpsi =  2.0 * M_PI / (double)(nRings - 1) ;
 
710
  dphi = -2.0 * M_PI / (double)(nSides - 1) ;
 
711
  psi  = 0.0;
 
712
 
 
713
  for( j=0; j<nRings; j++ )
 
714
  {
 
715
    cpsi = cos ( psi ) ;
 
716
    spsi = sin ( psi ) ;
 
717
    phi = 0.0;
 
718
 
 
719
    for( i=0; i<nSides; i++ )
 
720
    {
 
721
      int offset = 3 * ( j * nSides + i ) ;
 
722
      cphi = cos ( phi ) ;
 
723
      sphi = sin ( phi ) ;
 
724
      *(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ;
 
725
      *(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ;
 
726
      *(vertex + offset + 2) =                    sphi * iradius  ;
 
727
      *(normal + offset + 0) = cpsi * cphi ;
 
728
      *(normal + offset + 1) = spsi * cphi ;
 
729
      *(normal + offset + 2) =        sphi ;
 
730
      phi += dphi;
 
731
    }
 
732
 
 
733
    psi += dpsi;
 
734
  }
 
735
 
 
736
    glBegin( GL_QUADS );
 
737
  for( i=0; i<nSides-1; i++ )
 
738
  {
 
739
    for( j=0; j<nRings-1; j++ )
 
740
    {
 
741
      int offset = 3 * ( j * nSides + i ) ;
 
742
      glNormal3dv( normal + offset );
 
743
      glVertex3dv( vertex + offset );
 
744
      glNormal3dv( normal + offset + 3 );
 
745
      glVertex3dv( vertex + offset + 3 );
 
746
      glNormal3dv( normal + offset + 3 * nSides + 3 );
 
747
      glVertex3dv( vertex + offset + 3 * nSides + 3 );
 
748
      glNormal3dv( normal + offset + 3 * nSides );
 
749
      glVertex3dv( vertex + offset + 3 * nSides );
 
750
    }
 
751
  }
 
752
 
 
753
  glEnd();
 
754
 
 
755
  free ( vertex ) ;
 
756
  free ( normal ) ;
 
757
  glPopMatrix();
 
758
}
 
759
 
 
760
/*
 
761
 *
 
762
 */
 
763
void FGAPIENTRY glutWireDodecahedron( void )
 
764
{
 
765
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireDodecahedron" );
 
766
 
 
767
  /* Magic Numbers:  It is possible to create a dodecahedron by attaching two pentagons to each face of
 
768
   * of a cube.  The coordinates of the points are:
 
769
   *   (+-x,0, z); (+-1, 1, 1); (0, z, x )
 
770
   * where x = (-1 + sqrt(5))/2, z = (1 + sqrt(5))/2  or
 
771
   *       x = 0.61803398875 and z = 1.61803398875.
 
772
   */
 
773
  glBegin ( GL_LINE_LOOP ) ;
 
774
  glNormal3d (  0.0,  0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
 
775
  glEnd () ;
 
776
  glBegin ( GL_LINE_LOOP ) ;
 
777
  glNormal3d (  0.0,  0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
 
778
  glEnd () ;
 
779
  glBegin ( GL_LINE_LOOP ) ;
 
780
  glNormal3d (  0.0, -0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
 
781
  glEnd () ;
 
782
  glBegin ( GL_LINE_LOOP ) ;
 
783
  glNormal3d (  0.0, -0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
 
784
  glEnd () ;
 
785
 
 
786
  glBegin ( GL_LINE_LOOP ) ;
 
787
  glNormal3d (  0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
 
788
  glEnd () ;
 
789
  glBegin ( GL_LINE_LOOP ) ;
 
790
  glNormal3d ( -0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
 
791
  glEnd () ;
 
792
  glBegin ( GL_LINE_LOOP ) ;
 
793
  glNormal3d (  0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
 
794
  glEnd () ;
 
795
  glBegin ( GL_LINE_LOOP ) ;
 
796
  glNormal3d ( -0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
 
797
  glEnd () ;
 
798
 
 
799
  glBegin ( GL_LINE_LOOP ) ;
 
800
  glNormal3d (  0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
 
801
  glEnd () ;
 
802
  glBegin ( GL_LINE_LOOP ) ;
 
803
  glNormal3d (  0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
 
804
  glEnd () ;
 
805
  glBegin ( GL_LINE_LOOP ) ;
 
806
  glNormal3d ( -0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
 
807
  glEnd () ;
 
808
  glBegin ( GL_LINE_LOOP ) ;
 
809
  glNormal3d ( -0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
 
810
  glEnd () ;
 
811
}
 
812
 
 
813
/*
 
814
 *
 
815
 */
 
816
void FGAPIENTRY glutSolidDodecahedron( void )
 
817
{
 
818
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidDodecahedron" );
 
819
 
 
820
  /* Magic Numbers:  It is possible to create a dodecahedron by attaching two pentagons to each face of
 
821
   * of a cube.  The coordinates of the points are:
 
822
   *   (+-x,0, z); (+-1, 1, 1); (0, z, x )
 
823
   * where x = (-1 + sqrt(5))/2, z = (1 + sqrt(5))/2 or
 
824
   *       x = 0.61803398875 and z = 1.61803398875.
 
825
   */
 
826
  glBegin ( GL_POLYGON ) ;
 
827
  glNormal3d (  0.0,  0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
 
828
  glEnd () ;
 
829
  glBegin ( GL_POLYGON ) ;
 
830
  glNormal3d (  0.0,  0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
 
831
  glEnd () ;
 
832
  glBegin ( GL_POLYGON ) ;
 
833
  glNormal3d (  0.0, -0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
 
834
  glEnd () ;
 
835
  glBegin ( GL_POLYGON ) ;
 
836
  glNormal3d (  0.0, -0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
 
837
  glEnd () ;
 
838
 
 
839
  glBegin ( GL_POLYGON ) ;
 
840
  glNormal3d (  0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
 
841
  glEnd () ;
 
842
  glBegin ( GL_POLYGON ) ;
 
843
  glNormal3d ( -0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
 
844
  glEnd () ;
 
845
  glBegin ( GL_POLYGON ) ;
 
846
  glNormal3d (  0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
 
847
  glEnd () ;
 
848
  glBegin ( GL_POLYGON ) ;
 
849
  glNormal3d ( -0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
 
850
  glEnd () ;
 
851
 
 
852
  glBegin ( GL_POLYGON ) ;
 
853
  glNormal3d (  0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
 
854
  glEnd () ;
 
855
  glBegin ( GL_POLYGON ) ;
 
856
  glNormal3d (  0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
 
857
  glEnd () ;
 
858
  glBegin ( GL_POLYGON ) ;
 
859
  glNormal3d ( -0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
 
860
  glEnd () ;
 
861
  glBegin ( GL_POLYGON ) ;
 
862
  glNormal3d ( -0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
 
863
  glEnd () ;
 
864
}
 
865
 
 
866
/*
 
867
 *
 
868
 */
 
869
void FGAPIENTRY glutWireOctahedron( void )
 
870
{
 
871
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireOctahedron" );
 
872
 
 
873
#define RADIUS    1.0f
 
874
  glBegin( GL_LINE_LOOP );
 
875
    glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
 
876
    glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 );
 
877
    glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 );
 
878
    glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
 
879
    glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 );
 
880
    glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
 
881
    glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
 
882
    glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 );
 
883
  glEnd();
 
884
#undef RADIUS
 
885
}
 
886
 
 
887
/*
 
888
 *
 
889
 */
 
890
void FGAPIENTRY glutSolidOctahedron( void )
 
891
{
 
892
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidOctahedron" );
 
893
 
 
894
#define RADIUS    1.0f
 
895
  glBegin( GL_TRIANGLES );
 
896
    glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
 
897
    glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 );
 
898
    glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 );
 
899
    glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
 
900
    glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 );
 
901
    glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
 
902
    glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
 
903
    glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 );
 
904
  glEnd();
 
905
#undef RADIUS
 
906
}
 
907
 
 
908
/* Magic Numbers:  r0 = ( 1, 0, 0 )
 
909
 *                 r1 = ( -1/3, 2 sqrt(2) / 3, 0 )
 
910
 *                 r2 = ( -1/3, -sqrt(2) / 3, sqrt(6) / 3 )
 
911
 *                 r3 = ( -1/3, -sqrt(2) / 3, -sqrt(6) / 3 )
 
912
 * |r0| = |r1| = |r2| = |r3| = 1
 
913
 * Distance between any two points is 2 sqrt(6) / 3
 
914
 *
 
915
 * Normals:  The unit normals are simply the negative of the coordinates of the point not on the surface.
 
916
 */
 
917
 
 
918
#define NUM_TETR_FACES     4
 
919
 
 
920
static GLdouble tet_r[4][3] = { {             1.0,             0.0,             0.0 },
 
921
                                { -0.333333333333,  0.942809041582,             0.0 },
 
922
                                { -0.333333333333, -0.471404520791,  0.816496580928 },
 
923
                                { -0.333333333333, -0.471404520791, -0.816496580928 } } ;
 
924
 
 
925
static GLint tet_i[4][3] =  /* Vertex indices */
 
926
{
 
927
  { 1, 3, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 0, 1, 2 }
 
928
} ;
 
929
 
 
930
/*
 
931
 *
 
932
 */
 
933
void FGAPIENTRY glutWireTetrahedron( void )
 
934
{
 
935
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTetrahedron" );
 
936
 
 
937
  glBegin( GL_LINE_LOOP ) ;
 
938
    glNormal3d ( -tet_r[0][0], -tet_r[0][1], -tet_r[0][2] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[2] ) ;
 
939
    glNormal3d ( -tet_r[1][0], -tet_r[1][1], -tet_r[1][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[2] ) ; glVertex3dv ( tet_r[3] ) ;
 
940
    glNormal3d ( -tet_r[2][0], -tet_r[2][1], -tet_r[2][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[1] ) ;
 
941
    glNormal3d ( -tet_r[3][0], -tet_r[3][1], -tet_r[3][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[2] ) ;
 
942
  glEnd() ;
 
943
}
 
944
 
 
945
/*
 
946
 *
 
947
 */
 
948
void FGAPIENTRY glutSolidTetrahedron( void )
 
949
{
 
950
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTetrahedron" );
 
951
 
 
952
  glBegin( GL_TRIANGLES ) ;
 
953
    glNormal3d ( -tet_r[0][0], -tet_r[0][1], -tet_r[0][2] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[2] ) ;
 
954
    glNormal3d ( -tet_r[1][0], -tet_r[1][1], -tet_r[1][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[2] ) ; glVertex3dv ( tet_r[3] ) ;
 
955
    glNormal3d ( -tet_r[2][0], -tet_r[2][1], -tet_r[2][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[1] ) ;
 
956
    glNormal3d ( -tet_r[3][0], -tet_r[3][1], -tet_r[3][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[2] ) ;
 
957
  glEnd() ;
 
958
}
 
959
 
 
960
/*
 
961
 *
 
962
 */
 
963
static double icos_r[12][3] = {
 
964
    {  1.0,             0.0,             0.0            },
 
965
    {  0.447213595500,  0.894427191000,  0.0            },
 
966
    {  0.447213595500,  0.276393202252,  0.850650808354 },
 
967
    {  0.447213595500, -0.723606797748,  0.525731112119 },
 
968
    {  0.447213595500, -0.723606797748, -0.525731112119 },
 
969
    {  0.447213595500,  0.276393202252, -0.850650808354 },
 
970
    { -0.447213595500, -0.894427191000,  0.0 },
 
971
    { -0.447213595500, -0.276393202252,  0.850650808354 },
 
972
    { -0.447213595500,  0.723606797748,  0.525731112119 },
 
973
    { -0.447213595500,  0.723606797748, -0.525731112119 },
 
974
    { -0.447213595500, -0.276393202252, -0.850650808354 },
 
975
    { -1.0,             0.0,             0.0            }
 
976
};
 
977
 
 
978
static int icos_v [20][3] = {
 
979
    {  0,  1,  2 },
 
980
    {  0,  2,  3 },
 
981
    {  0,  3,  4 },
 
982
    {  0,  4,  5 },
 
983
    {  0,  5,  1 },
 
984
    {  1,  8,  2 },
 
985
    {  2,  7,  3 },
 
986
    {  3,  6,  4 },
 
987
    {  4, 10,  5 },
 
988
    {  5,  9,  1 },
 
989
    {  1,  9,  8 },
 
990
    {  2,  8,  7 },
 
991
    {  3,  7,  6 },
 
992
    {  4,  6, 10 },
 
993
    {  5, 10,  9 },
 
994
    { 11,  9, 10 },
 
995
    { 11,  8,  9 },
 
996
    { 11,  7,  8 },
 
997
    { 11,  6,  7 },
 
998
    { 11, 10,  6 }
 
999
};
 
1000
 
 
1001
void FGAPIENTRY glutWireIcosahedron( void )
 
1002
{
 
1003
  int i ;
 
1004
 
 
1005
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireIcosahedron" );
 
1006
 
 
1007
  for ( i = 0; i < 20; i++ )
 
1008
  {
 
1009
    double normal[3] ;
 
1010
    normal[0] = ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) - ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) ;
 
1011
    normal[1] = ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) - ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) ;
 
1012
    normal[2] = ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) - ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) ;
 
1013
    glBegin ( GL_LINE_LOOP ) ;
 
1014
      glNormal3dv ( normal ) ;
 
1015
      glVertex3dv ( icos_r[icos_v[i][0]] ) ;
 
1016
      glVertex3dv ( icos_r[icos_v[i][1]] ) ;
 
1017
      glVertex3dv ( icos_r[icos_v[i][2]] ) ;
 
1018
    glEnd () ;
 
1019
  }
 
1020
}
 
1021
 
 
1022
/*
 
1023
 *
 
1024
 */
 
1025
void FGAPIENTRY glutSolidIcosahedron( void )
 
1026
{
 
1027
  int i ;
 
1028
 
 
1029
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidIcosahedron" );
 
1030
 
 
1031
  glBegin ( GL_TRIANGLES ) ;
 
1032
  for ( i = 0; i < 20; i++ )
 
1033
  {
 
1034
    double normal[3] ;
 
1035
    normal[0] = ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) - ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) ;
 
1036
    normal[1] = ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) - ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) ;
 
1037
    normal[2] = ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) - ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) ;
 
1038
      glNormal3dv ( normal ) ;
 
1039
      glVertex3dv ( icos_r[icos_v[i][0]] ) ;
 
1040
      glVertex3dv ( icos_r[icos_v[i][1]] ) ;
 
1041
      glVertex3dv ( icos_r[icos_v[i][2]] ) ;
 
1042
  }
 
1043
 
 
1044
  glEnd () ;
 
1045
}
 
1046
 
 
1047
/*
 
1048
 *
 
1049
 */
 
1050
static double rdod_r[14][3] = {
 
1051
    {  0.0,             0.0,             1.0 },
 
1052
    {  0.707106781187,  0.000000000000,  0.5 },
 
1053
    {  0.000000000000,  0.707106781187,  0.5 },
 
1054
    { -0.707106781187,  0.000000000000,  0.5 },
 
1055
    {  0.000000000000, -0.707106781187,  0.5 },
 
1056
    {  0.707106781187,  0.707106781187,  0.0 },
 
1057
    { -0.707106781187,  0.707106781187,  0.0 },
 
1058
    { -0.707106781187, -0.707106781187,  0.0 },
 
1059
    {  0.707106781187, -0.707106781187,  0.0 },
 
1060
    {  0.707106781187,  0.000000000000, -0.5 },
 
1061
    {  0.000000000000,  0.707106781187, -0.5 },
 
1062
    { -0.707106781187,  0.000000000000, -0.5 },
 
1063
    {  0.000000000000, -0.707106781187, -0.5 },
 
1064
    {  0.0,             0.0,            -1.0 }
 
1065
} ;
 
1066
 
 
1067
static int rdod_v [12][4] = {
 
1068
    { 0,  1,  5,  2 },
 
1069
    { 0,  2,  6,  3 },
 
1070
    { 0,  3,  7,  4 },
 
1071
    { 0,  4,  8,  1 },
 
1072
    { 5, 10,  6,  2 },
 
1073
    { 6, 11,  7,  3 },
 
1074
    { 7, 12,  8,  4 },
 
1075
    { 8,  9,  5,  1 },
 
1076
    { 5,  9, 13, 10 },
 
1077
    { 6, 10, 13, 11 },
 
1078
    { 7, 11, 13, 12 },
 
1079
    { 8, 12, 13,  9 }
 
1080
};
 
1081
 
 
1082
static double rdod_n[12][3] = {
 
1083
    {  0.353553390594,  0.353553390594,  0.5 },
 
1084
    { -0.353553390594,  0.353553390594,  0.5 },
 
1085
    { -0.353553390594, -0.353553390594,  0.5 },
 
1086
    {  0.353553390594, -0.353553390594,  0.5 },
 
1087
    {  0.000000000000,  1.000000000000,  0.0 },
 
1088
    { -1.000000000000,  0.000000000000,  0.0 },
 
1089
    {  0.000000000000, -1.000000000000,  0.0 },
 
1090
    {  1.000000000000,  0.000000000000,  0.0 },
 
1091
    {  0.353553390594,  0.353553390594, -0.5 },
 
1092
    { -0.353553390594,  0.353553390594, -0.5 },
 
1093
    { -0.353553390594, -0.353553390594, -0.5 },
 
1094
    {  0.353553390594, -0.353553390594, -0.5 }
 
1095
};
 
1096
 
 
1097
void FGAPIENTRY glutWireRhombicDodecahedron( void )
 
1098
{
 
1099
  int i ;
 
1100
 
 
1101
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireRhombicDodecahedron" );
 
1102
 
 
1103
  for ( i = 0; i < 12; i++ )
 
1104
  {
 
1105
    glBegin ( GL_LINE_LOOP ) ;
 
1106
      glNormal3dv ( rdod_n[i] ) ;
 
1107
      glVertex3dv ( rdod_r[rdod_v[i][0]] ) ;
 
1108
      glVertex3dv ( rdod_r[rdod_v[i][1]] ) ;
 
1109
      glVertex3dv ( rdod_r[rdod_v[i][2]] ) ;
 
1110
      glVertex3dv ( rdod_r[rdod_v[i][3]] ) ;
 
1111
    glEnd () ;
 
1112
  }
 
1113
}
 
1114
 
 
1115
/*
 
1116
 *
 
1117
 */
 
1118
void FGAPIENTRY glutSolidRhombicDodecahedron( void )
 
1119
{
 
1120
  int i ;
 
1121
 
 
1122
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidRhombicDodecahedron" );
 
1123
 
 
1124
  glBegin ( GL_QUADS ) ;
 
1125
  for ( i = 0; i < 12; i++ )
 
1126
  {
 
1127
      glNormal3dv ( rdod_n[i] ) ;
 
1128
      glVertex3dv ( rdod_r[rdod_v[i][0]] ) ;
 
1129
      glVertex3dv ( rdod_r[rdod_v[i][1]] ) ;
 
1130
      glVertex3dv ( rdod_r[rdod_v[i][2]] ) ;
 
1131
      glVertex3dv ( rdod_r[rdod_v[i][3]] ) ;
 
1132
  }
 
1133
 
 
1134
  glEnd () ;
 
1135
}
 
1136
 
 
1137
void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale )
 
1138
{
 
1139
  int i, j ;
 
1140
 
 
1141
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireSierpinskiSponge" );
 
1142
 
 
1143
  if ( num_levels == 0 )
 
1144
  {
 
1145
 
 
1146
    for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
 
1147
    {
 
1148
      glBegin ( GL_LINE_LOOP ) ;
 
1149
      glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ;
 
1150
      for ( j = 0; j < 3; j++ )
 
1151
      {
 
1152
        double x = offset[0] + scale * tet_r[tet_i[i][j]][0] ;
 
1153
        double y = offset[1] + scale * tet_r[tet_i[i][j]][1] ;
 
1154
        double z = offset[2] + scale * tet_r[tet_i[i][j]][2] ;
 
1155
        glVertex3d ( x, y, z ) ;
 
1156
      }
 
1157
 
 
1158
      glEnd () ;
 
1159
    }
 
1160
  }
 
1161
  else if ( num_levels > 0 )
 
1162
  {
 
1163
    GLdouble local_offset[3] ;  /* Use a local variable to avoid buildup of roundoff errors */
 
1164
    num_levels -- ;
 
1165
    scale /= 2.0 ;
 
1166
    for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
 
1167
    {
 
1168
      local_offset[0] = offset[0] + scale * tet_r[i][0] ;
 
1169
      local_offset[1] = offset[1] + scale * tet_r[i][1] ;
 
1170
      local_offset[2] = offset[2] + scale * tet_r[i][2] ;
 
1171
      glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
 
1172
    }
 
1173
  }
 
1174
}
 
1175
 
 
1176
void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale )
 
1177
{
 
1178
  int i, j ;
 
1179
 
 
1180
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidSierpinskiSponge" );
 
1181
 
 
1182
  if ( num_levels == 0 )
 
1183
  {
 
1184
    glBegin ( GL_TRIANGLES ) ;
 
1185
 
 
1186
    for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
 
1187
    {
 
1188
      glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ;
 
1189
      for ( j = 0; j < 3; j++ )
 
1190
      {
 
1191
        double x = offset[0] + scale * tet_r[tet_i[i][j]][0] ;
 
1192
        double y = offset[1] + scale * tet_r[tet_i[i][j]][1] ;
 
1193
        double z = offset[2] + scale * tet_r[tet_i[i][j]][2] ;
 
1194
        glVertex3d ( x, y, z ) ;
 
1195
      }
 
1196
    }
 
1197
 
 
1198
    glEnd () ;
 
1199
  }
 
1200
  else if ( num_levels > 0 )
 
1201
  {
 
1202
    GLdouble local_offset[3] ;  /* Use a local variable to avoid buildup of roundoff errors */
 
1203
    num_levels -- ;
 
1204
    scale /= 2.0 ;
 
1205
    for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
 
1206
    {
 
1207
      local_offset[0] = offset[0] + scale * tet_r[i][0] ;
 
1208
      local_offset[1] = offset[1] + scale * tet_r[i][1] ;
 
1209
      local_offset[2] = offset[2] + scale * tet_r[i][2] ;
 
1210
      glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
 
1211
    }
 
1212
  }
 
1213
}
 
1214
 
 
1215
/*** END OF FILE ***/