#include #include #include #include #include #include #include #include #include #include #include #include #include "globals.h" #include "states.h" #include "util.h" #include "lights.h" #include "init.h" #include "geom.h" #include "render.h" static const float pi2 = 2.0 * M_PI; /* gets the user events like mouse events and keyboard events and sets up the event state that is passed in */ void handle_events(EventState *events, RenderState *state) { Device dev, mdev[2]; short val; int i; mdev[X] = MOUSEX; mdev[Y] = MOUSEY; dev = qread(&val); switch(dev) { case REDRAW: getorigin(&state->orgview[X], &state->orgview[Y]); getsize(&state->sizeview[X], &state->sizeview[Y]); rectzoom((float)(state->sizeview[X])/(float)(state->bg_size[X]), (float)(state->sizeview[Y])/(float)(state->bg_size[Y])); reshapeviewport(); events->redraw = 1; break; case ESCKEY: /* exit program */ gexit(); exit(0); break; case INPUTCHANGE: events->cursor_on_main = !(events->cursor_on_main); /* make the display list if we're on the main rendering window, because in the main window, the display list will remain constant */ if (events->cursor_on_main) { /* printf("making new display list\n"); state->num_polygons = make_display_list(CurrObj, geometry_display_list); state->timeout = 0; */ } else { /* state->timeout = 50;*/ } break; case HKEY: if (val) state->bg_on = !state->bg_on; break; case LEFTSHIFTKEY: if (val) { events->shift_key = 1; } else { events->shift_key = 0; } break; case RIGHTSHIFTKEY: if (val) { events->shift_key = 1; } else { events->shift_key = 0; } break; case LEFTMOUSE: if (val) { getdev(2, mdev, events->mouse_pos); events->leftmouse_down = 1; events->mouse_pos[X] -= state->orgview[X]; events->mouse_pos[Y] -= state->orgview[Y]; events->redraw = 1; } else { events->mouse_speed = sqrt((float) ((events->lastmouse_pos[X] - events->mouse_pos[X])* (events->lastmouse_pos[X] - events->mouse_pos[X])+ (events->lastmouse_pos[Y] - events->mouse_pos[Y])* (events->lastmouse_pos[Y] - events->mouse_pos[Y]))); events->leftmouse_down = 0; } break; case MIDDLEMOUSE: if (val) { events->middlemouse_down = 1; getdev(2, mdev, events->mouse_pos); events->mouse_pos[X] -= state->orgview[X]; events->mouse_pos[Y] -= state->orgview[Y]; events->redraw = 1; } else { events->middlemouse_down = 0; } break; case RIGHTMOUSE: if (val) { events->rightmouse_down = 1; getdev(2, mdev, events->mouse_pos); events->mouse_pos[X] -= state->orgview[X]; events->mouse_pos[Y] -= state->orgview[Y]; events->redraw = 1; } else { events->rightmouse_down = 0; } break; case UPARROWKEY: if (val) events->arrowup = 1; else events->arrowup = 0; break; case DOWNARROWKEY: if (val) events->arrowdown = 1; else events->arrowdown = 0; break; case LEFTARROWKEY: if (val) events->arrowleft = 1; else events->arrowleft = 0; break; case RIGHTARROWKEY: if (val) events->arrowright = 1; else events->arrowright = 0; break; case PAD8: if (val) events->pad8 = 1; else events->pad8 = 0; break; case PAD2: if (val) events->pad2 = 1; else events->pad2 = 0; break; case PAD4: if (val) events->pad4 = 1; else events->pad4 = 0; break; case PAD6: if (val) events->pad6 = 1; else events->pad6 = 0; break; case EKEY: if (val) { state->eyemode = !state->eyemode; } break; case QKEY: if (val) { if (state->twoside == 0.0) state->twoside = 1.0; else state->twoside = 0.0; init_lights(); } break; case MKEY: if (val) { state->texmap = !state->texmap; } break; case LKEY: if (val) { if (state->lights_on) { state->lights_on = 0; lmbind(LMODEL, 0); for (i=0; i<(state->num_lights); i++) { lmbind(LIGHT0+i, 0); } } else { state->lights_on = 1; lmbind(LMODEL, 1); init_lights(); } } break; case FKEY: if (val) { if (state->fog_on) { state->fog_on = 0; fogvertex(FG_OFF, NULL); } else { state->fog_on = 1; state->depth_cue_on = 0; define_fog(0.0, 0.0, 25.0, 0.4, 0.4, 0.4); fogvertex(FG_ON, NULL); } } break; case DKEY: if (val) { if (state->depth_cue_on) { state->depth_cue_on = 0; fogvertex(FG_OFF, NULL); /*depthcue(FALSE);*/ } else { state->depth_cue_on = 1; state->fog_on = 0; define_fog(0.0, 0.0, 25.0, 0.01, 0.01, 0.01); fogvertex(FG_ON, NULL); /*depthcue(TRUE);*/ } } break; case GKEY: if (val) { if (state->smooth_on) { state->smooth_on = 0; subpixel(FALSE); pntsmooth(SMP_OFF); linesmooth(SML_OFF); polysmooth(PYSM_OFF); } else { state->smooth_on = 1; subpixel(TRUE); pntsmooth(SMP_ON); linesmooth(SML_ON); polysmooth(PYSM_ON); } } break; case SKEY: if (val) { state->shading = !state->shading; shademodel(state->shading); if (isobj(CurrObj)) { editobj(CurrObj); closeobj(); } render(); } break; case MINUSKEY: if (val) { state->sensitivity -= 0.01; if (state->sensitivity < 0.0) state->sensitivity = 0.0; } break; case EQUALKEY: if (val) { state->sensitivity += 0.01; if (state->sensitivity > 2.0) state->sensitivity = 2.0; } break; case AKEY: if (val) { state->aspect_on = !state->aspect_on; events->redraw = 1; } break; case BKEY: if (val) { state->backface_on = !state->backface_on; backface(state->backface_on); if (isobj(CurrObj)) { editobj(CurrObj); closeobj(); } events->redraw = 1; } break; case CKEY: if (val) { state->concave_on = !state->concave_on; concave(state->concave_on); if (isobj(CurrObj)) { editobj(CurrObj); closeobj(); } events->redraw = 1; } break; case ZKEY: if (val) { state->zbuffer_on = !state->zbuffer_on; zbuffer(state->zbuffer_on); if (isobj(CurrObj)) { editobj(CurrObj); closeobj(); } events->redraw = 1; } break; case WKEY: if (val) { if (state->wire_frame) { state->wire_frame = 0; polymode(PYM_FILL); } else { state->wire_frame = 1; polymode(PYM_LINE); } render(); } break; case TKEY: if (val) { if (state->alpha_on) { state->alpha_on = 0; blendfunction(BF_ONE, BF_ZERO); } else { state->alpha_on = 1; blendfunction(BF_SA, BF_MSA); } render(); } break; case PKEY: if (val) { state->persp = !state->persp; render(); } break; case TWOKEY: if (val) { state->stereo_on = !state->stereo_on; if (state->stereo_on) prefsize(state->sizeview[X]<<1, state->sizeview[Y]); else prefsize(state->sizeview[X]>>1, state->sizeview[Y]); winconstraints(); /* to set the new window size */ winconstraints(); /* to allow manual resizing later */ win_stat(state->winview, state->orgview, state->sizeview); events->redraw = 1; } break; } } /* changes the state of the renderer, which includes transformations of objects and view, and changing of various rendering modes (wireframe, fog, stereo, zbuffer, alpha, etc.) */ void handle_event_changes(EventState *events, RenderState *state) { float dmouse[2], old_theta; float vcx, vcy, vcz; Device mdev[2]; mdev[X] = MOUSEX; mdev[Y] = MOUSEY; /* always redraw, to get the frames/sec */ events->redraw = 1; if (events->redraw) { events->redraw = 0; render(); updatematrix(*state); if (((events->mouse_speed == 0.0 || events->leftmouse_down) && !state->eyemode) || !state->auto_rotate) { state->axis = NO_AXIS; state->xrot = state->yrot = state->zrot = 0; } } if (events->leftmouse_down) { getdev(2, mdev, events->mouse_pos2); events->mouse_pos2[X] -= state->orgview[X]; events->mouse_pos2[Y] -= state->orgview[Y]; dmouse[X] = (float)(events->mouse_pos2[X] - events->mouse_pos[X]); dmouse[Y] = (float)(events->mouse_pos2[Y] - events->mouse_pos[Y]); dmouse[X] *= state->sensitivity; dmouse[Y] *= state->sensitivity; if (events->shift_key) { if (state->eyemode) { state->twist = fmodf(state->twist+dmouse[X], 360.0); } else { if (events->mouse_pos[X] >= state->sizeview[X]*0.5) { if (events->mouse_pos[Y] >= state->sizeview[Y]*0.5) { /* quadrant 1 */ state->zrot -= dmouse[X]; state->zrot += dmouse[Y]; } else { /* quadrant 4 */ state->zrot += dmouse[X]; state->zrot += dmouse[Y]; } } else { if (events->mouse_pos[Y] >= state->sizeview[Y]*0.5) { /* quadrant 2 */ state->zrot -= dmouse[X]; state->zrot -= dmouse[Y]; } else { /* quadrant 3 */ state->zrot += dmouse[X]; state->zrot -= dmouse[Y]; } } state->axis = Z_AXIS; } } else { if (state->eyemode) { old_theta = state->theta; state->phi = fmodf(state->phi-0.005*dmouse[X], 2.0*M_PI); state->theta = fmodf(state->theta+0.005*dmouse[Y], 2.0*M_PI); state->twist = adjust_twist_angle(old_theta, state->theta, state->twist); state->vrp[X]=(state->cop[X] + (state->cv_rad* cos(state->theta)* cos(state->phi))); state->vrp[Y]=state->cop[Y]+state->cv_rad*sin(state->theta); state->vrp[Z]=(state->cop[Z] - (state->cv_rad* cos(state->theta)* sin(state->phi))); } else { state->xrot -= dmouse[Y]; state->yrot += dmouse[X]; state->axis = XY_AXIS; } } events->lastmouse_pos[X] = events->mouse_pos[X]; events->lastmouse_pos[Y] = events->mouse_pos[Y]; events->mouse_pos[X] = events->mouse_pos2[X]; events->mouse_pos[Y] = events->mouse_pos2[Y]; events->redraw = 1; } if (events->middlemouse_down) { getdev(2, mdev, events->mouse_pos2); events->mouse_pos2[X] -= state->orgview[X]; events->mouse_pos2[Y] -= state->orgview[Y]; dmouse[X] = (float)(events->mouse_pos2[X] - events->mouse_pos[X])*0.025; dmouse[Y] = (float)(events->mouse_pos2[Y] - events->mouse_pos[Y])*0.025; dmouse[X] *= state->sensitivity; dmouse[Y] *= state->sensitivity; if (events->shift_key) { if (state->eyemode) { vcx = 0.25*(state->vrp[X] - state->cop[X])*dmouse[Y]; vcy = 0.25*(state->vrp[Y] - state->cop[Y])*dmouse[Y]; vcz = 0.25*(state->vrp[Z] - state->cop[Z])*dmouse[Y]; state->cop[X] += vcx; state->cop[Y] += vcy; state->cop[Z] += vcz; state->vrp[X] += vcx; state->vrp[Y] += vcy; state->vrp[Z] += vcz; } else { state->dz += dmouse[Y]; } } else { if (state->eyemode) { state->cop[X] += 0.5*dmouse[X]; state->vrp[X] += 0.5*dmouse[X]; state->cop[Y] += 0.5*dmouse[Y]; state->vrp[Y] += 0.5*dmouse[Y]; } else { state->dx += dmouse[X]; state->dy += dmouse[Y]; } } events->mouse_pos[X] = events->mouse_pos2[X]; events->mouse_pos[Y] = events->mouse_pos2[Y]; events->redraw = 1; } if (events->rightmouse_down) { getdev(2, mdev, events->mouse_pos2); events->mouse_pos2[X] -= state->orgview[X]; events->mouse_pos2[Y] -= state->orgview[Y]; dmouse[X] = (float)(events->mouse_pos2[X] - events->mouse_pos[X])*0.005; dmouse[Y] = (float)(events->mouse_pos2[Y] - events->mouse_pos[Y])*0.005; dmouse[X] *= state->sensitivity; dmouse[Y] *= state->sensitivity; if (!state->eyemode) { state->scale_factor *= 1.0 + dmouse[Y]; if (state->scale_factor < Epsilon) state->scale_factor = Epsilon; } events->mouse_pos[X] = events->mouse_pos2[X]; events->mouse_pos[Y] = events->mouse_pos2[Y]; events->redraw = 1; } if (events->arrowup) { if (state->eyemode) { old_theta = state->theta; state->theta = fmodf(state->theta-0.05*state->sensitivity, 2.0*M_PI); state->twist = adjust_twist_angle(old_theta, state->theta, state->twist); state->vrp[X]=(state->cop[X] + state->cv_rad*cos(state->theta)*cos(state->phi)); state->vrp[Y]=state->cop[Y] + state->cv_rad*sin(state->theta); state->vrp[Z]=(state->cop[Z] - state->cv_rad*cos(state->theta)*sin(state->phi)); } else { state->scale_factor *= 1.0 + 0.05*state->sensitivity; } events->redraw = 1; } if (events->arrowdown) { if (state->eyemode) { old_theta = state->theta; state->theta = fmodf(state->theta+0.05*state->sensitivity, 2.0*M_PI); state->twist = adjust_twist_angle(old_theta, state->theta, state->twist); state->vrp[X]=(state->cop[X] + state->cv_rad*cos(state->theta)*cos(state->phi)); state->vrp[Y]=state->cop[Y] + state->cv_rad*sin(state->theta); state->vrp[Z]=(state->cop[Z] - state->cv_rad*cos(state->theta)*sin(state->phi)); } else { state->scale_factor *= 1.0 - 0.05*state->sensitivity; if (state->scale_factor < Epsilon) state->scale_factor = Epsilon; } events->redraw = 1; } if (events->arrowleft) { if (state->eyemode) { state->twist = fmodf(state->twist+state->sensitivity, 360.0); } else { state->zrot += 1.0*state->sensitivity; state->axis = Z_AXIS; } events->redraw = 1; } if (events->arrowright) { if (state->eyemode) { state->twist = fmodf(state->twist-state->sensitivity, 360.0); } else { state->zrot -= 1.0*state->sensitivity; state->axis = Z_AXIS; } events->redraw = 1; } if (events->pad8) { if (state->eyemode) { vcx = 0.1*state->sensitivity*(state->vrp[X] - state->cop[X]); vcy = 0.1*state->sensitivity*(state->vrp[Y] - state->cop[Y]); vcz = 0.1*state->sensitivity*(state->vrp[Z] - state->cop[Z]); state->cop[X] += vcx; state->cop[Y] += vcy; state->cop[Z] += vcz; state->vrp[X] += vcx; state->vrp[Y] += vcy; state->vrp[Z] += vcz; } else { state->xrot -= 1.0*state->sensitivity; state->axis = XY_AXIS; } events->redraw = 1; } if (events->pad2) { if (state->eyemode) { vcx = 0.1*state->sensitivity*(state->cop[X] - state->vrp[X]); vcy = 0.1*state->sensitivity*(state->cop[Y] - state->vrp[Y]); vcz = 0.1*state->sensitivity*(state->cop[Z] - state->vrp[Z]); state->cop[X] += vcx; state->cop[Y] += vcy; state->cop[Z] += vcz; state->vrp[X] += vcx; state->vrp[Y] += vcy; state->vrp[Z] += vcz; } else { state->xrot += 1.0*state->sensitivity; state->axis = XY_AXIS; } events->redraw = 1; } if (events->pad4) { if (state->eyemode) { state->phi = fmodf(state->phi+0.05*state->sensitivity, 2.0*M_PI); state->vrp[X]=(state->cop[X] + state->cv_rad*cos(state->theta)*cos(state->phi)); state->vrp[Y]=state->cop[Y] + state->cv_rad*sin(state->theta); state->vrp[Z]=(state->cop[Z] - state->cv_rad*cos(state->theta)*sin(state->phi)); } else { state->yrot -= 1.0*state->sensitivity; state->axis = XY_AXIS; } events->redraw = 1; } if (events->pad6) { if (state->eyemode) { state->phi = fmodf(state->phi-0.05*state->sensitivity, 2.0*M_PI); state->vrp[X]=(state->cop[X] + state->cv_rad*cos(state->theta)*cos(state->phi)); state->vrp[Y]=state->cop[Y] + state->cv_rad*sin(state->theta); state->vrp[Z]=(state->cop[Z] - state->cv_rad*cos(state->theta)*sin(state->phi)); } else { state->yrot += 1.0*state->sensitivity; state->axis = XY_AXIS; } events->redraw = 1; } }