/******************************************************************************\ Space out the vertices at even distance from the sphere. \******************************************************************************/ static void sphericize(void) { c_vec3_t origin, co; float scale; int i; origin = C_vec3(0.f, 0.f, 0.f); for (i = 0; i < r_tiles_max * 3; i++) { co = r_globe_verts[i].v.co; scale = r_globe_radius / C_vec3_len(co); r_globe_verts[i].v.co = C_vec3_scalef(co, scale); } }
/******************************************************************************\ Sets the height of one tile. \******************************************************************************/ static void set_tile_height(int tile, float height) { c_vec3_t co; float dist; int i, j, verts[6], verts_len; for (i = 0; i < 3; i++) { verts_len = vertex_indices(3 * tile + i, verts); height = height / verts_len; for (j = 0; j < verts_len; j++) { co = r_globe_verts[verts[j]].v.co; dist = C_vec3_len(co); co = C_vec3_scalef(co, (dist + height) / dist); r_globe_verts[verts[j]].v.co = co; } } }
/******************************************************************************\ Calculates a new camera rotation matrix and reloads the modelview matrix. \******************************************************************************/ void R_update_camera(void) { c_vec3_t x_axis, y_axis, z_axis, diff; R_push_mode(R_MODE_3D); glMatrixMode(GL_MODELVIEW); /* Update zoom */ r_cam_zoom += cam_zoom_diff; if (r_cam_zoom > r_zoom_max) r_cam_zoom = r_zoom_max; if (r_cam_zoom < R_ZOOM_MIN) r_cam_zoom = R_ZOOM_MIN; cam_zoom_diff = 0.f; /* Momentum mode changes the meaning of the camera difference vector to velocity rather than change-per-frame */ diff = cam_rot_diff; if (cam_momentum) { float prop; diff = C_vec3_scalef(diff, c_frame_sec); prop = 1.f - c_frame_sec * CAM_FRICTION; if (prop <= 0.f) { cam_rot_diff = C_vec3(0.f, 0.f, 0.f); cam_momentum = FALSE; } else { cam_rot_diff = C_vec3_scalef(cam_rot_diff, prop); if (C_vec3_len(cam_rot_diff) < STOP_MARGIN) { cam_rot_diff = C_vec3(0.f, 0.f, 0.f); cam_momentum = FALSE; } } } else cam_rot_diff = C_vec3(0.f, 0.f, 0.f); /* Apply the rotation differences from last frame to the rotation matrix to get view-oriented scrolling */ glLoadMatrixf(cam_rotation); x_axis = C_vec3(cam_rotation[0], cam_rotation[4], cam_rotation[8]); y_axis = C_vec3(cam_rotation[1], cam_rotation[5], cam_rotation[9]); z_axis = C_vec3(cam_rotation[2], cam_rotation[6], cam_rotation[10]); glRotatef(C_rad_to_deg(diff.x), x_axis.x, x_axis.y, x_axis.z); glRotatef(C_rad_to_deg(diff.y), y_axis.x, y_axis.y, y_axis.z); glRotatef(C_rad_to_deg(diff.z), z_axis.x, z_axis.y, z_axis.z); /* If we are in gradual rotation mode, update it */ if (cam_gradual) { float angle; angle = gradual_angle * GRADUAL_RATE * c_frame_sec; if (angle > gradual_angle) angle = gradual_angle; glRotatef(C_rad_to_deg(angle), gradual_axis.x, gradual_axis.y, gradual_axis.z); gradual_angle -= angle; if (gradual_angle < STOP_MARGIN) cam_gradual = FALSE; } /* Recreate the full camera matrix with the new rotation */ glGetFloatv(GL_MODELVIEW_MATRIX, cam_rotation); check_rotation(); glLoadIdentity(); glTranslatef(0, 0, -r_globe_radius - r_cam_zoom); glMultMatrixf(cam_rotation); glGetFloatv(GL_MODELVIEW_MATRIX, r_cam_matrix); /* Extract the camera location from the matrix for use by other parts of the program. We cannot replace these new vectors with the axes above because they are changed by the rotations. */ r_cam_forward = C_vec3(-cam_rotation[2], -cam_rotation[6], -cam_rotation[10]); r_cam_normal = C_vec3(cam_rotation[1], cam_rotation[5], cam_rotation[9]); r_cam_origin = C_vec3_scalef(r_cam_forward, -r_globe_radius - r_cam_zoom); R_pop_mode(); }