8aa07ab0a03752b70d437f6c64d40f60d3f37d4b
[xscreensaver] / hacks / glx / extrusion-taper.c
1 /* 
2  * taper.c
3  * 
4  * FUNCTION:
5  * Draws a tapered screw shape.
6  *
7  * HISTORY:
8  * -- created by Linas Vepstas October 1991
9  * -- heavily modified to draw more texas shapes, Feb 1993, Linas
10  * -- converted to use GLUT -- December 1995, Linas
11  *
12  */
13
14 /* required include files */
15 #ifdef HAVE_CONFIG_H
16 #include <config.h>
17 #endif
18
19 #include <math.h>
20 #include <stdlib.h>
21 #include <GL/gl.h>
22 /*#include <GL/glut.h>*/
23 #ifdef HAVE_GLE3
24 #include <GL/gle.h>
25 #else
26 #include <GL/tube.h>
27 #endif
28
29 #ifndef NULL
30 #define NULL ((void *) 0x0)
31 #endif /* NULL */
32
33 /* Some <math.h> files do not define M_PI... */
34 #ifndef M_PI
35 #define M_PI 3.14159265358979323846
36 #endif
37
38 /* =========================================================== */
39
40 #define SCALE 3.33333
41 #define CONTOUR(x,y) {                                  \
42    double ax, ay, alen;                                 \
43    contour[i][0] = SCALE * (x);                         \
44    contour[i][1] = SCALE * (y);                         \
45    if (i!=0) {                                          \
46       ax = contour[i][0] - contour[i-1][0];             \
47       ay = contour[i][1] - contour[i-1][1];             \
48       alen = 1.0 / sqrt (ax*ax + ay*ay);                \
49       ax *= alen;   ay *= alen;                         \
50       norms [i-1][0] = ay;                              \
51       norms [i-1][1] = -ax;                             \
52    }                                                    \
53    i++;                                                 \
54 }
55
56 #define NUM_PTS (25)
57
58 static double contour [NUM_PTS][2];
59 static double norms [NUM_PTS][2];
60
61 static void init_contour (void)
62 {
63    int i;
64
65    /* outline of extrusion */
66    i=0;
67    CONTOUR (1.0, 1.0);
68    CONTOUR (1.0, 2.9);
69    CONTOUR (0.9, 3.0);
70    CONTOUR (-0.9, 3.0);
71    CONTOUR (-1.0, 2.9);
72
73    CONTOUR (-1.0, 1.0);
74    CONTOUR (-2.9, 1.0);
75    CONTOUR (-3.0, 0.9);
76    CONTOUR (-3.0, -0.9);
77    CONTOUR (-2.9, -1.0);
78
79    CONTOUR (-1.0, -1.0);
80    CONTOUR (-1.0, -2.9);
81    CONTOUR (-0.9, -3.0);
82    CONTOUR (0.9, -3.0);
83    CONTOUR (1.0, -2.9);
84
85    CONTOUR (1.0, -1.0);
86    CONTOUR (2.9, -1.0);
87    CONTOUR (3.0, -0.9);
88    CONTOUR (3.0, 0.9);
89    CONTOUR (2.9, 1.0);
90
91    CONTOUR (1.0, 1.0);   /* repeat so that last normal is computed */
92 }
93    
94 /* =========================================================== */
95
96 #define PSIZE 40
97 static double path[PSIZE][3];
98 static double twist[PSIZE];
99 static double taper[PSIZE];
100
101 static void init_taper (void) {
102    int j;
103    double z, deltaz;
104    double ang, dang;
105
106    z = -10.0;
107    deltaz = 0.5;
108
109    ang = 0.0;
110    dang = 20.0;
111    for (j=0; j<40; j++) {
112       path[j][0] = 0x0;
113       path[j][1] = 0x0;
114       path[j][2] = z;
115
116       twist[j] = ang;
117       ang += dang;
118
119       taper[j] = 0.1 * sqrt (9.51*9.51 - z*z);
120
121       z += deltaz;
122    }
123
124    taper[0] = taper[1];
125    taper[39] = taper[38];
126
127 }
128
129 /* =========================================================== */
130
131 extern float lastx;
132 extern float lasty;
133 extern float rot_x;
134 extern float rot_y;
135 extern float rot_z;
136
137 void InitStuff_taper (void)
138 {
139    int style;
140
141    /* configure the pipeline */
142    style = TUBE_JN_CAP;
143    style |= TUBE_CONTOUR_CLOSED;
144    style |= TUBE_NORM_FACET;
145    style |= TUBE_JN_ANGLE;
146    gleSetJoinStyle (style);
147
148    init_contour();
149    init_taper();
150 }
151
152 /* =========================================================== */
153
154 static void gleTaper (int ncp, 
155                gleDouble contour[][2], 
156                gleDouble cont_normal[][2], 
157                gleDouble up[3],
158                int npoints,
159                gleDouble point_array[][3],
160                float color_array[][3],
161                gleDouble taper[],
162                gleDouble twist[])
163 {
164    int j;
165    gleAffine *xforms;
166    double co, si, angle;
167
168    /* malloc the extrusion array and the twist array */
169    xforms = (gleAffine *) malloc (npoints * sizeof(gleAffine));
170
171    for (j=0; j<npoints; j++) {
172       angle = (M_PI/180.0) * twist[j];
173       si = sin (angle);
174       co = cos (angle);
175       xforms[j][0][0] = taper[j] * co;
176       xforms[j][0][1] = - taper[j] * si;
177       xforms[j][0][2] = 0.0;
178       xforms[j][1][0] = taper[j] * si;
179       xforms[j][1][1] = taper[j] * co;
180       xforms[j][1][2] = 0.0;
181    }
182
183    gleSuperExtrusion (ncp,               /* number of contour points */
184                 contour,    /* 2D contour */
185                 cont_normal, /* 2D contour normals */
186                 up,           /* up vector for contour */
187                 npoints,           /* numpoints in poly-line */
188                 point_array,        /* polyline */
189                 color_array,        /* color of polyline */
190                 xforms);
191
192    free (xforms);
193 }
194
195 /* =========================================================== */
196
197 void DrawStuff_taper (void) {
198    int j;
199    double ang, dang;
200    double z, deltaz;
201    double ponent;
202    z=-1.0;
203    deltaz = 1.999/38;
204    ang = 0.0;
205    dang = lasty/40.0;
206    ponent = fabs (lastx/540.0);
207    for (j=1; j<39; j++) {
208       twist[j] = ang;
209       ang += dang;
210
211       taper[j] = pow ((1.0 - pow (fabs(z), 1.0/ponent)), ponent);
212       z += deltaz;
213    }
214
215    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
216    glColor3f (0.5, 0.6, 0.6);
217
218    /* set up some matrices so that the object spins with the mouse */
219    glPushMatrix ();
220    glTranslatef (0.0, 0.0, -80.0);
221    glRotatef(rot_x, 1, 0, 0);
222    glRotatef(rot_y, 0, 1, 0);
223    glRotatef(rot_z, 0, 0, 1);
224
225 /*     glRotatef (130.0, 0.0, 1.0, 0.0); */
226 /*     glRotatef (65.0, 1.0, 0.0, 0.0); */
227
228    /* draw the brand and the handle */
229    gleTaper (20, contour, norms,  NULL, 40, path, NULL, taper, twist);
230
231    glPopMatrix ();
232 }
233
234 /* ===================== END OF FILE ================== */