X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fmolecule.c;h=75010b8ee0b8c17cd798be8a3b10b12fe13ab1f1;hp=c6c59b868ed0e9e8de26793e7a4e72fb2db6ea7d;hb=13dbc569cdc6e29019722c0ef9b932a925efbcad;hpb=3f9592851ce4ed76a9979bfdd6ec7dc5c457e183 diff --git a/hacks/glx/molecule.c b/hacks/glx/molecule.c index c6c59b86..75010b8e 100644 --- a/hacks/glx/molecule.c +++ b/hacks/glx/molecule.c @@ -73,6 +73,8 @@ #define HACK_INIT init_molecule #define HACK_DRAW draw_molecule #define HACK_RESHAPE reshape_molecule +#define HACK_HANDLE_EVENT molecule_handle_event +#define EVENT_MASK PointerMotionMask #define molecule_opts xlockmore_opts #define DEF_TIMEOUT "20" @@ -109,11 +111,15 @@ #include "colors.h" #include "sphere.h" #include "tube.h" +#include "rotator.h" +#include "gltrackball.h" #ifdef USE_GL /* whole file */ #include #include +#include +#include #include #define SPHERE_SLICES 16 /* how densely to render spheres */ @@ -186,13 +192,9 @@ typedef struct { typedef struct { GLXContext *glx_context; - - GLfloat rotx, roty, rotz; /* current object rotation */ - GLfloat dx, dy, dz; /* current rotational velocity */ - GLfloat ddx, ddy, ddz; /* current rotational acceleration */ - GLfloat d_max; /* max velocity */ - - Bool spin_x, spin_y, spin_z; + rotator *rot; + trackball_state *trackball; + Bool button_down_p; GLfloat molecule_size; /* max dimension of molecule bounding box */ @@ -230,7 +232,7 @@ static XrmOptionDescRec opts[] = { { "-molecule", ".molecule", XrmoptionSepArg, 0 }, { "-timeout",".timeout",XrmoptionSepArg, 0 }, { "-spin", ".spin", XrmoptionSepArg, 0 }, - { "+spin", ".spin", XrmoptionNoArg, "False" }, + { "+spin", ".spin", XrmoptionNoArg, "" }, { "-wander", ".wander", XrmoptionNoArg, "True" }, { "+wander", ".wander", XrmoptionNoArg, "False" }, { "-labels", ".labels", XrmoptionNoArg, "True" }, @@ -977,7 +979,7 @@ parse_pdb_data (molecule *m, const char *data, const char *filename, int line) else if (!strncmp (s, "CONECT ", 7)) { int atoms[11]; - int i = sscanf (s + 8, " %d %d %d %d %d %d %d %d %d %d %d ", + int i = sscanf (s + 8, " %d %d %d %d %d %d %d %d %d %d %d %d ", &atoms[0], &atoms[1], &atoms[2], &atoms[3], &atoms[4], &atoms[5], &atoms[6], &atoms[7], &atoms[8], &atoms[9], &atoms[10], &atoms[11]); @@ -1224,15 +1226,13 @@ reshape_molecule (ModeInfo *mi, int width, int height) glMatrixMode(GL_PROJECTION); glLoadIdentity(); - - gluPerspective( 30.0, 1/h, 20.0, 40.0 ); - gluLookAt( 0.0, 0.0, 15.0, - 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0); + gluPerspective (30.0, 1/h, 20.0, 40.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glTranslatef(0.0, 0.0, -15.0); + gluLookAt( 0.0, 0.0, 30.0, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); } @@ -1256,77 +1256,6 @@ gl_init (ModeInfo *mi) } -/* lifted from lament.c */ -#define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n)))) -#define RANDSIGN() ((random() & 1) ? 1 : -1) - -static void -rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v) -{ - double ppos = *pos; - - /* tick position */ - if (ppos < 0) - ppos = -(ppos + *v); - else - ppos += *v; - - if (ppos > 1.0) - ppos -= 1.0; - else if (ppos < 0) - ppos += 1.0; - - if (ppos < 0) abort(); - if (ppos > 1.0) abort(); - *pos = (*pos > 0 ? ppos : -ppos); - - /* accelerate */ - *v += *dv; - - /* clamp velocity */ - if (*v > max_v || *v < -max_v) - { - *dv = -*dv; - } - /* If it stops, start it going in the other direction. */ - else if (*v < 0) - { - if (random() % 4) - { - *v = 0; - - /* keep going in the same direction */ - if (random() % 2) - *dv = 0; - else if (*dv < 0) - *dv = -*dv; - } - else - { - /* reverse gears */ - *v = -*v; - *dv = -*dv; - *pos = -*pos; - } - } - - /* Alter direction of rotational acceleration randomly. */ - if (! (random() % 120)) - *dv = -*dv; - - /* Change acceleration very occasionally. */ - if (! (random() % 200)) - { - if (*dv == 0) - *dv = 0.00001; - else if (random() & 1) - *dv *= 1.2; - else - *dv *= 0.8; - } -} - - static void startup_blurb (ModeInfo *mi) { @@ -1340,6 +1269,39 @@ startup_blurb (ModeInfo *mi) glXSwapBuffers(MI_DISPLAY(mi), MI_WINDOW(mi)); } +Bool +molecule_handle_event (ModeInfo *mi, XEvent *event) +{ + molecule_configuration *mc = &mcs[MI_SCREEN(mi)]; + + if (event->xany.type == ButtonPress && + event->xbutton.button & Button1) + { + mc->button_down_p = True; + gltrackball_start (mc->trackball, + event->xbutton.x, event->xbutton.y, + MI_WIDTH (mi), MI_HEIGHT (mi)); + return True; + } + else if (event->xany.type == ButtonRelease && + event->xbutton.button & Button1) + { + mc->button_down_p = False; + return True; + } + else if (event->xany.type == MotionNotify && + mc->button_down_p) + { + gltrackball_track (mc->trackball, + event->xmotion.x, event->xmotion.y, + MI_WIDTH (mi), MI_HEIGHT (mi)); + return True; + } + + return False; +} + + void init_molecule (ModeInfo *mi) { @@ -1367,28 +1329,17 @@ init_molecule (ModeInfo *mi) wire = MI_IS_WIREFRAME(mi); - mc->rotx = frand(1.0) * RANDSIGN(); - mc->roty = frand(1.0) * RANDSIGN(); - mc->rotz = frand(1.0) * RANDSIGN(); - - /* bell curve from 0-6 degrees, avg 3 */ - mc->dx = (frand(1) + frand(1) + frand(1)) / (360/2); - mc->dy = (frand(1) + frand(1) + frand(1)) / (360/2); - mc->dz = (frand(1) + frand(1) + frand(1)) / (360/2); - - mc->d_max = mc->dx * 2; - - mc->ddx = 0.00006 + frand(0.00003); - mc->ddy = 0.00006 + frand(0.00003); - mc->ddz = 0.00006 + frand(0.00003); - { + Bool spinx=False, spiny=False, spinz=False; + double spin_speed = 2.0; + double wander_speed = 0.03; + char *s = do_spin; while (*s) { - if (*s == 'x' || *s == 'X') mc->spin_x = 1; - else if (*s == 'y' || *s == 'Y') mc->spin_y = 1; - else if (*s == 'z' || *s == 'Z') mc->spin_z = 1; + if (*s == 'x' || *s == 'X') spinx = True; + else if (*s == 'y' || *s == 'Y') spiny = True; + else if (*s == 'z' || *s == 'Z') spinz = True; else { fprintf (stderr, @@ -1398,6 +1349,14 @@ init_molecule (ModeInfo *mi) } s++; } + + mc->rot = make_rotator (spinx ? spin_speed : 0, + spiny ? spin_speed : 0, + spinz ? spin_speed : 0, + 1.0, + do_wander ? wander_speed : 0, + True); + mc->trackball = gltrackball_init (); } mc->molecule_dlist = glGenLists(1); @@ -1428,7 +1387,8 @@ draw_molecule (ModeInfo *mi) if (!mc->glx_context) return; - if (last + timeout <= now) /* randomize molecules every -timeout seconds */ + if (last + timeout <= now && /* randomize molecules every -timeout seconds */ + !mc->button_down_p) { if (mc->nmolecules == 1) { @@ -1474,39 +1434,18 @@ draw_molecule (ModeInfo *mi) glScalef(1.1, 1.1, 1.1); { - GLfloat x, y, z; - - if (do_wander) - { - static int frame = 0; - -# define SINOID(SCALE,SIZE) \ - ((((1 + sin((frame * (SCALE)) / 2 * M_PI)) / 2.0) * (SIZE)) - (SIZE)/2) - - x = SINOID(0.031, 9.0); - y = SINOID(0.023, 9.0); - z = SINOID(0.017, 9.0); - frame++; - glTranslatef(x, y, z); - } - - if (mc->spin_x || mc->spin_y || mc->spin_z) - { - x = mc->rotx; - y = mc->roty; - z = mc->rotz; - if (x < 0) x = 1 - (x + 1); - if (y < 0) y = 1 - (y + 1); - if (z < 0) z = 1 - (z + 1); - - if (mc->spin_x) glRotatef(x * 360, 1.0, 0.0, 0.0); - if (mc->spin_y) glRotatef(y * 360, 0.0, 1.0, 0.0); - if (mc->spin_z) glRotatef(z * 360, 0.0, 0.0, 1.0); - - rotate(&mc->rotx, &mc->dx, &mc->ddx, mc->d_max); - rotate(&mc->roty, &mc->dy, &mc->ddy, mc->d_max); - rotate(&mc->rotz, &mc->dz, &mc->ddz, mc->d_max); - } + double x, y, z; + get_position (mc->rot, &x, &y, &z, !mc->button_down_p); + glTranslatef((x - 0.5) * 9, + (y - 0.5) * 9, + (z - 0.5) * 9); + + gltrackball_rotate (mc->trackball); + + get_rotation (mc->rot, &x, &y, &z, !mc->button_down_p); + glRotatef (x * 360, 1.0, 0.0, 0.0); + glRotatef (y * 360, 0.0, 1.0, 0.0); + glRotatef (z * 360, 0.0, 0.0, 1.0); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);