#include "viewer.h" #include "vector.h" #define FOLLOW_WT 0.2 // for smooth transition bw frames, the smaller the close to prev frame // if mouse stroke to left: zoomOut; to right: zoomIn void zoom(int mouseDragXdist, double &fieldOfView) { double amt = mouseDragXdist / 100.0f; // some random positive amt fieldOfView += amt; if (fieldOfView > 180) fieldOfView = 180; if (fieldOfView < 0) fieldOfView = 0; mdebug(DEBUG_STAGE,"field of view = %2.2lf\n", fieldOfView); } void camera_omin(int frame_cnt, double *trans, double look[3], double eye[3]) { v3_assign(eye, 150, 110, 150); v3_assign(look, 0, 15, 0); return; } /* changes look and eye given time, follow_theta, follow_phi, follow_lag, and pos and rot at the time */ double prev_eye[]= {0, 0, 0}; // eye pos in prev frame void Gl_Win::camera_follow(int time, double look[3], double eye[3]) { int frame_size_inDouble = rot_cnt * 3; double *pos = trans + time * 3; double *rot = euler + time * frame_size_inDouble; double rot_y_this_frame = rot[2]; // fig's facing direction double theta; double phi; double new_eye[3]; double eye_diff[3]; look[X] = pos[X]; look[Y] = pos[Y]; look[Z] = pos[Z]; if (rot_y_this_frame < 0) theta = (rot_y_this_frame + follow_theta) * DegreeToRadian; else theta = (180 - rot_y_this_frame - follow_theta) * DegreeToRadian; phi = follow_phi * DegreeToRadian; new_eye[X] = look[X] - follow_lag * sin(theta) * cos(phi); new_eye[Y] = look[Y] + follow_lag * sin(phi); new_eye[Z] = look[Z] + follow_lag * cos(theta) * cos(phi); // for smooth camera mvt from frame to frame v3_sub(new_eye, prev_eye, eye_diff); // get diff bw this and last frame v3_scale(eye_diff, FOLLOW_WT, eye_diff); // take weighted diff v3_add(eye_diff, prev_eye, eye); // get new eye v3_assign(prev_eye, eye); mdebug(DEBUG_STAGE,"t=%d, rot = %2.2lf, the=%2.2lf, phi=%2.2lf\n", time, rot[2], follow_theta, follow_phi); } void adjust_follow_theta(int mouseDragXdist, double &follow_theta) { double amt = mouseDragXdist / 100.0f; follow_theta += amt; if (follow_theta > 360) follow_theta = 360; if (follow_theta < 0) follow_theta = 0; mdebug(DEBUG_STAGE,"theta = %2.2lf, amt=%2.2lf\n", follow_theta, amt); } void adjust_follow_phi(int mouseDragYdist, double &follow_phi) { double amt = -mouseDragYdist / 100.0f; // neg 'cause scrn pos flips w/ gl. follow_phi += amt ; if (follow_phi > 90) follow_phi = 90; if (follow_phi < 0) follow_phi = 0; mdebug(DEBUG_STAGE,"phi = %2.2lf, amt=%2.2lf\n", follow_phi, amt); } void adjust_follow_lag(int mouseDragXdist, double &follow_lag) { double amt = mouseDragXdist / 100.0f; follow_lag += amt; mdebug(DEBUG_STAGE,"lag = %2.2lf, amt=%2.2lf\n", follow_lag, amt); } ////////light and shadow ///////////// /* a shadow matrix multiplied onto the stack according to light pos point drop shade matrix pm=[ly -lx 0 0 0 0 0 0 0 -lz ly 0 0 -1 0 ly] */ void Gl_Win::shadowMatrix(GLfloat light_pos[3]) { double pm[16] = {light_pos[1], 0, 0, 0, -light_pos[0], 0 , -light_pos[2], -1, 0, 0, light_pos[1], 0, 0, 0, 0, light_pos[1] }; glMultMatrixd(pm); } // bulb slightly below light source, so get lit void Gl_Win::draw_light_bulb(bool light, GLfloat light_pos[3]) { if (light) { mat_diffuse_ambient[R] = 1; mat_diffuse_ambient[G] = 0.2f; mat_diffuse_ambient[B] = 0; glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_diffuse_ambient); } else glColor3d(1, 0.2, 0); glPushMatrix(); glLoadIdentity(); glTranslatef(light_pos[X], light_pos[Y] - 10, light_pos[Z]); glRotatef(90, 1, 0, 0); gluCylinder(qobj, 0.5, 5, 6, 5, 1); glPopMatrix(); } void set_light( const float light_pos[3] ) { // this is a spot light GLfloat light1_ambient[] = {.3f, 0.2f, 0.2f, 1.0}; GLfloat light_1s[] = {1, 1, 1, 1}; GLfloat spot_direction[3]; spot_direction[X] = - light_pos[X]; spot_direction[Y] = - light_pos[Y]; spot_direction[Z] = - light_pos[Z]; glEnable( GL_DEPTH_TEST ); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular ); glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS , 100.0); glShadeModel(GL_SMOOTH); glLightfv( GL_LIGHT0, GL_POSITION, light_pos ); // two lights same spot glLightfv( GL_LIGHT1, GL_POSITION, light_pos ); glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, light_1s); glLightfv(GL_LIGHT1, GL_SPECULAR, light_1s); glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.5); glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.5); glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.2f); glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 45.0); glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION, spot_direction); glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.0); } // lighting button cb void lightCB(Fl_Widget* wid, Fl_Widget *container) { Fl_Light_Button *but = (Fl_Light_Button *)wid; Gl_Win *win = (Gl_Win *)container; if (but->value() == 1) win->light = true; else win->light = false; win->damage(1); } // floor button cb void floorCB(Fl_Widget* wid, Fl_Widget *container) { Fl_Light_Button *but = (Fl_Light_Button *)wid; Gl_Win *win = (Gl_Win *)container; if (but->value() == 1) win->b_floor = true; else win->b_floor = false; win->damage(1); }