~ubuntu-branches/ubuntu/natty/rss-glx/natty

« back to all changes in this revision

Viewing changes to other_src/lorenz.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2009-05-01 05:30:24 UTC
  • mfrom: (1.2.3 upstream)
  • mto: This revision was merged to the branch mainline in revision 26.
  • Revision ID: james.westby@ubuntu.com-20090501053024-eo6umwjsksox3uaf
Tags: upstream-0.8.3
Import upstream version 0.8.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2002, 2009  S�ren Sonnenburg <sonne@debian.org>
 
3
 *
 
4
 * FX done Breakpoint 2002, code recovered, converted and polished into
 
5
 * xscreensaver hack on Apr 12 at Breakpoint 2009.
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 * 
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 * 
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
 */
 
21
 
 
22
/*
 
23
 * Lorenz attractor screensaver 
 
24
 */
 
25
 
 
26
char *hack_name = (char *)"lorenz";
 
27
 
 
28
#include "driver.h"
 
29
#include <GL/gl.h>
 
30
#include <GL/glu.h>
 
31
 
 
32
#include <math.h>
 
33
#include <stdio.h>
 
34
#include <stdlib.h>
 
35
 
 
36
#include <rsMath/rsVec.h>
 
37
#include <rsMath/rsQuat.h>
 
38
 
 
39
 
 
40
#define num_satellites_default 25
 
41
#define num_points_default 100000
 
42
#define line_width_attractor_default 2
 
43
#define line_width_satellites_default 16
 
44
#define camera_speed_default 0.3
 
45
#define linear_cutoff_default 0.2
 
46
#define camera_angle_default 45
 
47
 
 
48
static float elapsedTime;
 
49
 
 
50
static int line_width_satellites=line_width_satellites_default;
 
51
static int line_width_attractor=line_width_attractor_default;
 
52
static float camera_speed=camera_speed_default;
 
53
static float linear_cutoff=linear_cutoff_default;
 
54
 
 
55
static int num_points_max=-1;
 
56
static int num_precomputed_points=num_points_default;
 
57
static int num_points;
 
58
static int num_satellites=num_satellites_default;
 
59
static float lorenz_a=11;
 
60
static float lorenz_b=15;
 
61
static float lorenz_c=3;
 
62
static float lorenz_dt=0.02;
 
63
 
 
64
static float camera_angle=camera_angle_default;
 
65
static float camera_angle_anim[2] = {5, 179};
 
66
static float camera_angle_anim_speed=0.1;
 
67
static float mean[3] = { 0, 0, 0 };
 
68
static float time;
 
69
static float lastn0 = 0;
 
70
static float flipn0 = 1;
 
71
static float deltaflipn0 = 0;
 
72
 
 
73
static int width=800;
 
74
static int height=600;
 
75
 
 
76
static GLfloat col_ambient[] =  { 0.0, 0.1, 0.4, 0 };
 
77
 
 
78
static GLfloat l0_diffuse[] =    { 1.0, 1.0, 0.0, 1.0 };
 
79
static GLfloat l0_specular[] =   { 0.1, 0.1, 0.05, 0.0 };
 
80
static GLfloat l0_att[] =        { 0.5 };
 
81
static GLfloat l0_qatt[] =       { 5.01 };
 
82
static GLfloat l0_cutoff[] =     { 100 };
 
83
 
 
84
static float* lorenz_coords;
 
85
static float* lorenz_path;
 
86
static float* satellite_times;
 
87
static float* satellite_speeds;
 
88
 
 
89
static inline float distance(float P0x, float P0y, float P0z,
 
90
                float P1x, float P1y, float P1z)
 
91
{
 
92
        float x=P0x-P1x;
 
93
        float y=P0y-P1y;
 
94
        float z=P0z-P1z;
 
95
        return sqrt(x*x+y*y+z*z);
 
96
}
 
97
 
 
98
static inline void norm_one(float* x, float* y, float* z)
 
99
{
 
100
        float n=sqrt(((*x)*(*x))+((*y)*(*y))+((*z)*(*z)));
 
101
        (*x)/=n;
 
102
        (*y)/=n;
 
103
        (*z)/=n;
 
104
}
 
105
 
 
106
inline void calc_normal(float P0x, float P0y, float P0z,
 
107
                float P1x, float P1y, float P1z,
 
108
                float P2x, float P2y, float P2z,
 
109
                float* Nx, float* Ny, float* Nz)
 
110
{
 
111
        (*Nx)= (P1y - P0y) * (P2z - P0z) - (P1z - P0z) * (P2y - P0y);
 
112
        (*Ny)= (P1z - P0z) * (P2x - P0x) - (P1x - P0x) * (P2z - P0z);
 
113
        (*Nz)= (P1x - P0x) * (P2y - P0y) - (P1y - P0y) * (P2x - P0x);
 
114
}
 
115
 
 
116
inline float angle(float P0x, float P0y, float P0z,
 
117
                float P1x, float P1y, float P1z,
 
118
                float P2x, float P2y, float P2z)
 
119
{
 
120
        return atan2(distance(P0x,P0y,P0z, P1x, P1y, P1z), distance(P0x,P0y,P0z, P2x, P2y, P2z));
 
121
}
 
122
 
 
123
 
 
124
inline void coords_at_time(float* from, float t, float* x, float* y, float* z)
 
125
{
 
126
        int u=(int) t;
 
127
        float s;
 
128
        s=(t-floor(t));
 
129
        *x=(1-s)*from[3*u]+s*from[3*(u+1)];
 
130
        *y=(1-s)*from[3*u+1]+s*from[3*(u+1)+1];
 
131
        *z=(1-s)*from[3*u+2]+s*from[3*(u+1)+2];
 
132
}
 
133
 
 
134
inline void normal_at_time(float* from, float t, float* x, float* y, float* z)
 
135
{
 
136
        float p1[3];
 
137
        float p2[3];
 
138
        float p3[3];
 
139
        coords_at_time(from, t, &p1[0], &p1[1], &p1[2]);
 
140
        coords_at_time(from, t-1, &p2[0], &p2[1], &p2[2]);
 
141
        coords_at_time(from, t+1, &p3[0], &p3[1], &p3[2]);
 
142
        calc_normal(p1[0], p1[1], p1[2],
 
143
                        p2[0], p2[1], p2[2],
 
144
                        p3[0], p3[1], p3[2],
 
145
                        x,y,z);
 
146
}
 
147
 
 
148
inline float distance_to_line(float P0x, float P0y, float P0z,
 
149
                float P1x, float P1y, float P1z,
 
150
                float P2x, float P2y, float P2z)
 
151
{
 
152
 
 
153
        return distance(P0x,P0y,P0z, P1x,P1y,P1z)*sin(angle(P0x,P0y,P0z, P1x,P1y,P1z, P2x,P2y,P2z));
 
154
}
 
155
 
 
156
void reduce_points(int cutoff)
 
157
{
 
158
        int j=0;
 
159
        int start=0;
 
160
        int end=0;
 
161
        float dist=1;
 
162
        int current_offs=0;
 
163
 
 
164
        num_points=num_precomputed_points;
 
165
 
 
166
        while (current_offs<num_points-1 && start<num_points-1 && end<num_points-1)
 
167
        {
 
168
                dist=0;
 
169
                for (end=start; end<num_points && dist<linear_cutoff; end++)
 
170
                {
 
171
                        for (j=start; j<=end && dist<linear_cutoff; j++)
 
172
                        {
 
173
                                dist=distance_to_line(lorenz_coords[3*start],
 
174
                                                lorenz_coords[3*start+1],lorenz_coords[3*start+2],
 
175
                                                lorenz_coords[3*j],lorenz_coords[3*j+1],lorenz_coords[3*j+2],
 
176
                                                lorenz_coords[3*end],lorenz_coords[3*end+1],lorenz_coords[3*end+2]);
 
177
                        }
 
178
                }
 
179
 
 
180
                end--;
 
181
                current_offs++;
 
182
                lorenz_path[3*current_offs]=lorenz_coords[3*end];
 
183
                lorenz_path[3*current_offs+1]=lorenz_coords[3*end+1];
 
184
                lorenz_path[3*current_offs+2]=lorenz_coords[3*end+2];
 
185
                start=end;
 
186
        }
 
187
#ifdef DEBUG
 
188
        printf("reduced from %d to %d\n", num_points, current_offs);
 
189
#endif
 
190
        num_points=current_offs;
 
191
 
 
192
        if (num_points_max>0 && num_points>num_points_max)
 
193
                num_points=num_points_max;
 
194
}
 
195
 
 
196
void init_line_strip(void) 
 
197
{
 
198
        int i;
 
199
        float n[3];
 
200
 
 
201
        glClearColor(0.0, 0.0, 0.0, 0.0);
 
202
        glShadeModel(GL_FLAT);
 
203
        glEnable(GL_LIGHTING);
 
204
        glBlendFunc(GL_SRC_ALPHA,GL_ONE);
 
205
        glEnable(GL_BLEND);
 
206
        glEnable(GL_LIGHT0);
 
207
 
 
208
        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col_ambient);
 
209
        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
 
210
 
 
211
        glNewList(1, GL_COMPILE);
 
212
        glLineWidth(line_width_attractor);
 
213
        glBegin(GL_LINE_STRIP);
 
214
        for (i=100; i<num_points-20; i++)
 
215
        {
 
216
                glVertex3fv(&lorenz_path[i*3]);
 
217
 
 
218
                calc_normal(lorenz_path[3*i], lorenz_path[3*i+1], lorenz_path[3*i+2], 
 
219
                                lorenz_path[3*(i+3)], lorenz_path[3*(i+3)+1], lorenz_path[3*(i+3)+2],
 
220
                                lorenz_path[3*(i+5)], lorenz_path[3*(i+5)+2], lorenz_path[3*(i+5)+2],
 
221
                                &n[0],&n[1],&n[2]);
 
222
 
 
223
                norm_one(&n[0], &n[1], &n[2]);
 
224
 
 
225
                glNormal3fv(n);
 
226
        }
 
227
        glEnd();
 
228
        glEndList();
 
229
}
 
230
 
 
231
 
 
232
void display(void)
 
233
{
 
234
        int satellites=0;
 
235
        float n[3];
 
236
        float p1[3];
 
237
        float p2[3];
 
238
        float p3[3];
 
239
        float l=0;
 
240
 
 
241
        //set cam
 
242
        glMatrixMode (GL_MODELVIEW);
 
243
        glLoadIdentity ();          
 
244
 
 
245
        coords_at_time(lorenz_coords, time,   &p1[0], &p1[1], &p1[2]);
 
246
        coords_at_time(lorenz_coords, time+10,&p2[0], &p2[1], &p2[2]);
 
247
        coords_at_time(lorenz_coords, time+15,&p3[0], &p3[1], &p3[2]);
 
248
 
 
249
        calc_normal(p1[0], p1[1], p1[2],
 
250
                        p2[0], p2[1], p2[2],
 
251
                        p3[0], p3[1], p3[2],
 
252
                        &n[0], &n[1], &n[2]);
 
253
 
 
254
        norm_one(&n[0], &n[1], &n[2]);
 
255
 
 
256
        // n[0]'s sign changes when transitioning between the lobes...
 
257
        if ((lastn0 >= 0) != (n[0] >= 0)) {
 
258
                // if we've completed a transition, one in four chance whether to transition again.
 
259
                if ((deltaflipn0 >= 1.0) && (rand() < RAND_MAX / 4)) {
 
260
                        flipn0 = flipn0 * -1;
 
261
                        deltaflipn0 = 0;
 
262
                }
 
263
        }
 
264
 
 
265
        lastn0 = n[0];
 
266
 
 
267
        deltaflipn0 += elapsedTime;
 
268
 
 
269
        // during transition, slerp between flipped states
 
270
        if (deltaflipn0 < 1.0) {
 
271
                float la[3];
 
272
 
 
273
                la[0] = p2[0] - p1[0];
 
274
                la[1] = p2[1] - p1[1];
 
275
                la[2] = p2[2] - p1[2];
 
276
 
 
277
                norm_one(&la[0], &la[1], &la[2]);
 
278
 
 
279
                rsQuat normal, flipped;
 
280
                normal.make(0.0, la[0], la[1], la[2]);
 
281
                flipped.make(M_PI, la[0], la[1], la[2]);
 
282
                rsQuat f;
 
283
 
 
284
                if (flipn0 == -1)
 
285
                        f.slerp(normal, flipped, deltaflipn0);
 
286
                else
 
287
                        f.slerp(flipped, normal, deltaflipn0);
 
288
 
 
289
                rsVec rn = f.apply(rsVec(n[0], n[1], n[2]));
 
290
                n[0] = rn[0];
 
291
                n[1] = rn[1];
 
292
                n[2] = rn[2];
 
293
        } else {
 
294
                n[0] = n[0] * flipn0;
 
295
                n[1] = n[1] * flipn0;
 
296
                n[2] = n[2] * flipn0;
 
297
        }
 
298
 
 
299
 
 
300
        gluLookAt(p1[0]+0.9*n[0], p1[1]+0.9*n[1], p1[2]+0.9*n[2],
 
301
                        p2[0], p2[1], p2[2],
 
302
                        n[0],n[1],n[2]);
 
303
 
 
304
        coords_at_time(lorenz_coords, time+10,&p2[0], &p2[1], &p2[2]);
 
305
        coords_at_time(lorenz_coords, time+2, &p3[0], &p3[1], &p3[2]);
 
306
 
 
307
        //set light     
 
308
        GLfloat light_position0[] = { p2[0]+n[0], p2[1]+n[1], p2[2]+n[2], 1.0 };
 
309
        GLfloat light_dir0[] = { n[0], n[1], n[2], 1.0 };
 
310
 
 
311
        glPushMatrix();
 
312
 
 
313
        glLightfv(GL_LIGHT0, GL_DIFFUSE, l0_diffuse);
 
314
        glLightfv(GL_LIGHT0, GL_SPECULAR, l0_specular);
 
315
        glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
 
316
        glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir0);
 
317
        glLightfv(GL_LIGHT0, GL_CONSTANT_ATTENUATION, l0_att);
 
318
        glLightfv(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, l0_qatt);
 
319
        glLightfv(GL_LIGHT0, GL_SPOT_CUTOFF, l0_cutoff);
 
320
        glPopMatrix();
 
321
 
 
322
        glClear (GL_COLOR_BUFFER_BIT);
 
323
        glCallList(1);
 
324
 
 
325
        glDisable(GL_LIGHTING);
 
326
        for (satellites=0; satellites<num_satellites; satellites++)
 
327
        {
 
328
                glPushMatrix();
 
329
                float x,y,z;
 
330
                coords_at_time(lorenz_coords, satellite_times[satellites], &x,&y,&z);
 
331
 
 
332
                glLineWidth(line_width_satellites);
 
333
                glBegin(GL_LINE_STRIP);
 
334
                float s=37*elapsedTime*satellite_speeds[satellites]*num_points/num_precomputed_points;
 
335
 
 
336
                float maxl= ( 10*(fabs(s)) < 3 ) ? 3 : 10*(fabs(s));
 
337
                float stepl=(fabs(s)/maxl);
 
338
                for (l=0; l<maxl; l+=stepl)
 
339
                {
 
340
                        coords_at_time(lorenz_coords, satellite_times[satellites]+l, &x,&y,&z);
 
341
                        glVertex3d(x,y,z);
 
342
                        glNormal3d(light_dir0[0], light_dir0[1], light_dir0[2]);
 
343
                        if (s<0)
 
344
                                glColor4f(0.4,0.3,1.0/(l+1),0.9/(l+1));
 
345
                        else 
 
346
                                glColor4f(0.4,0.3,1.0/(maxl-l+1),0.9/(maxl-l+1));
 
347
 
 
348
                }
 
349
                glEnd();
 
350
                glPopMatrix();
 
351
 
 
352
                satellite_times[satellites]+=s;
 
353
                if (satellite_times[satellites]>num_points-20)
 
354
                        satellite_times[satellites]-=num_points-20;
 
355
                if (satellite_times[satellites]<0)
 
356
                        satellite_times[satellites]+=num_points-20;
 
357
        }
 
358
        glEnable(GL_BLEND);
 
359
        glEnable(GL_LIGHTING);
 
360
 
 
361
        glFlush ();
 
362
}
 
363
 
 
364
void set_camera()
 
365
{
 
366
        glMatrixMode(GL_PROJECTION);
 
367
        glLoadIdentity();
 
368
        gluPerspective(camera_angle, ((GLfloat) width)/height,0.0,1000);
 
369
}
 
370
 
 
371
void reshape (int w, int h)
 
372
{
 
373
        width=w;
 
374
        height=h;
 
375
#ifdef DEBUG
 
376
        printf("width=%d, height=%d\n", width, height);
 
377
#endif
 
378
 
 
379
        set_camera();
 
380
        glMatrixMode (GL_MODELVIEW);
 
381
        glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
 
382
}
 
383
 
 
384
void init_satellites()
 
385
{
 
386
        int i;
 
387
 
 
388
        if (num_satellites>0)
 
389
        {
 
390
                satellite_times = (float *)malloc(sizeof(float)*num_satellites);
 
391
                satellite_speeds = (float *)malloc(sizeof(float)*num_satellites);
 
392
 
 
393
                for (i=0; i<num_satellites; i++)
 
394
                {
 
395
                        satellite_times[i]=((float) rand())*num_points/RAND_MAX;
 
396
                        satellite_speeds[i]=10*camera_speed*(((float) rand())/RAND_MAX - 0.5);
 
397
                }
 
398
        }
 
399
}
 
400
 
 
401
void precompute_lorenz_array()
 
402
{
 
403
        int i;
 
404
        float max[3] = { 1,1,1 };
 
405
 
 
406
        lorenz_coords=(float*) malloc(3*num_precomputed_points*sizeof(float));
 
407
        lorenz_path=(float*) malloc(3*num_precomputed_points*sizeof(float));
 
408
 
 
409
        lorenz_coords[0]=20;
 
410
        lorenz_coords[1]=5;
 
411
        lorenz_coords[2]=-5;
 
412
 
 
413
        for (i=0; i<num_precomputed_points-1; i++)
 
414
        {
 
415
                lorenz_coords[(i+1)*3] = lorenz_coords[i*3] + lorenz_a * 
 
416
                        ( lorenz_coords[i*3+1] - lorenz_coords[i*3] ) * lorenz_dt;
 
417
 
 
418
                lorenz_coords[(i+1)*3+1] = lorenz_coords[i*3+1] +
 
419
                        ( lorenz_b * lorenz_coords[i*3] - lorenz_coords[i*3+1] -
 
420
                          lorenz_coords[i*3] * lorenz_coords[i*3+2] ) * lorenz_dt;
 
421
 
 
422
                lorenz_coords[(i+1)*3+2] = lorenz_coords[i*3+2] +
 
423
                        ( lorenz_coords[i*3] * lorenz_coords[i*3+1] -
 
424
                          lorenz_c * lorenz_coords[i*3+2] ) * lorenz_dt;
 
425
        }
 
426
 
 
427
        for (i=0; i<num_precomputed_points; i++)
 
428
        {
 
429
                mean[0]+=lorenz_coords[i*3];
 
430
                mean[1]+=lorenz_coords[i*3+1];
 
431
                mean[2]+=lorenz_coords[i*3+2];
 
432
        }
 
433
 
 
434
        mean[0]/=num_precomputed_points;
 
435
        mean[1]/=num_precomputed_points;
 
436
        mean[2]/=num_precomputed_points;
 
437
 
 
438
        for (i=0; i<num_precomputed_points; i++)
 
439
        {
 
440
                lorenz_coords[i*3]-=mean[0];
 
441
                lorenz_coords[i*3+1]-=mean[1];
 
442
                lorenz_coords[i*3+2]-=mean[2];
 
443
        }
 
444
 
 
445
        for (i=0; i<num_precomputed_points; i++)
 
446
        {
 
447
                if (lorenz_coords[i*3]>max[0])
 
448
                        max[0]=lorenz_coords[i*3];
 
449
                if (lorenz_coords[i*3+1]>max[1])
 
450
                        max[1]=lorenz_coords[i*3+1];
 
451
                if (lorenz_coords[i*3+2]>max[2])
 
452
                        max[2]=lorenz_coords[i*3+2];
 
453
        }
 
454
 
 
455
        float m= max[0];
 
456
        if (m<max[1])
 
457
                m=max[1];
 
458
        if (m<max[2])
 
459
                m=max[2];
 
460
 
 
461
        m=2;
 
462
        for (i=0; i<num_precomputed_points; i++)
 
463
        {
 
464
                lorenz_coords[i*3]/=m;
 
465
                lorenz_coords[i*3+1]/=m;
 
466
                lorenz_coords[i*3+2]/=m;
 
467
        }
 
468
}
 
469
 
 
470
void cleanup_arrays()
 
471
{
 
472
        if (lorenz_coords)
 
473
                free(lorenz_coords);
 
474
        if (lorenz_path)
 
475
                free(lorenz_path);
 
476
 
 
477
        if (satellite_times)
 
478
                free(satellite_times);
 
479
        if (satellite_speeds)
 
480
                free(satellite_speeds);
 
481
}
 
482
 
 
483
void callback(void)
 
484
{
 
485
        set_camera();
 
486
        display();
 
487
 
 
488
        time+=37*elapsedTime*camera_speed*num_points/num_precomputed_points;
 
489
 
 
490
        camera_angle+=37*elapsedTime*camera_angle_anim_speed;
 
491
        if (camera_angle<camera_angle_anim[0] || camera_angle>camera_angle_anim[1])
 
492
        {
 
493
                camera_angle_anim_speed*=-1;
 
494
                camera_angle+=camera_angle_anim_speed;
 
495
        }
 
496
}
 
497
 
 
498
void hack_draw (xstuff_t * XStuff, double currentTime, float frameTime)
 
499
{
 
500
        static float times[10] = { 0.03f, 0.03f, 0.03f, 0.03f, 0.03f,
 
501
                0.03f, 0.03f, 0.03f, 0.03f, 0.03f
 
502
        };
 
503
        static int timeindex = 0;
 
504
#ifdef BENCHMARK
 
505
        static int a = 1;
 
506
#endif
 
507
 
 
508
        if (frameTime > 0)
 
509
                times[timeindex] = frameTime;
 
510
        else
 
511
                times[timeindex] = elapsedTime;
 
512
 
 
513
#ifdef BENCHMARK
 
514
        elapsedTime = 0.027;
 
515
#else
 
516
        elapsedTime = 0.1f * (times[0] + times[1] + times[2] + times[3] + times[4] + times[5] + times[6] + times[7] + times[8] + times[9]);
 
517
 
 
518
        timeindex++;
 
519
        if (timeindex >= 10)
 
520
                timeindex = 0;
 
521
#endif
 
522
 
 
523
        callback();
 
524
 
 
525
#ifdef BENCHMARK
 
526
        if (a++ == 1000)
 
527
                exit(0);
 
528
#endif
 
529
}
 
530
 
 
531
void hack_reshape (xstuff_t * XStuff)
 
532
{
 
533
#ifdef DEBUG
 
534
        printf("hack_reshape\n");
 
535
#endif
 
536
        int w=XStuff->windowWidth;
 
537
        int h=XStuff->windowHeight;
 
538
        reshape(w,h);
 
539
}
 
540
 
 
541
void hack_init (xstuff_t * XStuff)
 
542
{
 
543
#ifdef DEBUG
 
544
        printf("hack_init\n");
 
545
#endif
 
546
        time=num_points/3;
 
547
        precompute_lorenz_array();
 
548
        reduce_points(num_points_max);
 
549
        init_satellites();
 
550
        init_line_strip();
 
551
        hack_reshape (XStuff);
 
552
}
 
553
 
 
554
void hack_cleanup (xstuff_t * XStuff)
 
555
{
 
556
#ifdef DEBUG
 
557
        printf("hack_cleanup\n");
 
558
#endif
 
559
        cleanup_arrays();
 
560
}
 
561
 
 
562
void hack_handle_opts (int argc, char **argv)
 
563
{
 
564
#ifdef DEBUG
 
565
        printf("handle_hack_opts\n");
 
566
#endif
 
567
        while (1) {
 
568
                int c;
 
569
 
 
570
#ifdef HAVE_GETOPT_H
 
571
                static struct option long_options[] = {
 
572
                        {"help", 0, 0, 'h'},
 
573
                        DRIVER_OPTIONS_LONG
 
574
                        {"num-points", 1, 0, 'n'},
 
575
                        {"num-satellites", 1, 0, 's'},
 
576
                        {"camera-speed", 1, 0, 'c'},
 
577
                        {"camera-angle", 1, 0, 'a'},
 
578
                        {"line-width", 1, 0, 'l'},
 
579
                        {"line-width-sat", 1, 0, 'w'},
 
580
                        {"line-cutoff", 1, 0, 'o'},
 
581
                };
 
582
 
 
583
                c = getopt_long (argc, argv, DRIVER_OPTIONS_SHORT "hn:s:c:a:l:w:o:", long_options, NULL);
 
584
#else
 
585
                c = getopt (argc, argv, DRIVER_OPTIONS_SHORT "hn:s:c:a:l:w:o:");
 
586
#endif
 
587
                if (c == -1)
 
588
                        break;
 
589
 
 
590
                switch (c) {
 
591
                DRIVER_OPTIONS_CASES case 'h':
 
592
                        printf ("%s:"
 
593
#ifndef HAVE_GETOPT_H
 
594
                                " Not built with GNU getopt.h, long options *NOT* enabled."
 
595
#endif
 
596
                                "\n" DRIVER_OPTIONS_HELP
 
597
                                "\t--num-points/-n <arg>\n"
 
598
                                "\t--num-satellites/-s\n"
 
599
                                "\t--camera-speed/-c\n"
 
600
                                "\t--camera-angle/-a\n"
 
601
                                "\t--line-width/l\n"
 
602
                                "\t--line-width-sat/w\n"
 
603
                                "\t--line-cutoff/o\n", argv[0]);
 
604
                        exit (1);
 
605
                case 'n':
 
606
                        num_precomputed_points = strtol_minmaxdef (optarg, 10, 100, 1000000, 1, num_points_default, "--num-points: ");
 
607
                        break;
 
608
                case 's':
 
609
                        num_satellites = strtol_minmaxdef (optarg, 10, 0, 50, 1, num_satellites_default, "--num-satellites: ");
 
610
                        break;
 
611
                case 'c':
 
612
                        camera_speed = 0.01 * strtol_minmaxdef (optarg, 10, 0, 100, 1, camera_speed_default/0.01, "--camera-speed: ");
 
613
                        break;
 
614
                case 'a':
 
615
                        camera_angle = strtol_minmaxdef (optarg, 10, 5, 179, 1, camera_angle_default, "--camera-angle: ");
 
616
                        camera_angle_anim_speed=0;
 
617
                        break;
 
618
                case 'l':
 
619
                        line_width_attractor = strtol_minmaxdef (optarg, 10, 1, 100, 1, line_width_attractor_default, "--line-width: ");
 
620
                        break;
 
621
                case 'w':
 
622
                        line_width_satellites = strtol_minmaxdef (optarg, 10, 1, 100, 1, line_width_satellites_default, "--line-width-sat: ");
 
623
                        break;
 
624
                case 'o':
 
625
                        linear_cutoff = 0.01 * strtol_minmaxdef (optarg, 10, 0, 10000, 1, linear_cutoff_default/0.01, "--line-cutoff: ");
 
626
                        break;
 
627
                }
 
628
        }
 
629
}