/******************************************************************************\ Computes tile vectors for the parameter array. \******************************************************************************/ static void compute_tile_vectors(int i) { c_vec3_t ab, ac; /* Set tile normal vector */ ab = C_vec3_sub(r_globe_verts[3 * i].v.co, r_globe_verts[3 * i + 1].v.co); ac = C_vec3_sub(r_globe_verts[3 * i].v.co, r_globe_verts[3 * i + 2].v.co); r_tiles[i].normal = C_vec3_norm(C_vec3_cross(ab, ac)); r_globe_verts[3 * i].v.no = r_tiles[i].normal; r_globe_verts[3 * i + 1].v.no = r_tiles[i].normal; r_globe_verts[3 * i + 2].v.no = r_tiles[i].normal; /* Centroid */ r_tiles[i].origin = C_vec3_add(r_globe_verts[3 * i].v.co, r_globe_verts[3 * i + 1].v.co); r_tiles[i].origin = C_vec3_add(r_tiles[i].origin, r_globe_verts[3 * i + 2].v.co); r_tiles[i].origin = C_vec3_divf(r_tiles[i].origin, 3.f); /* Forward vector */ r_tiles[i].forward = C_vec3_sub(r_globe_verts[3 * i].v.co, r_tiles[i].origin); r_tiles[i].forward = C_vec3_norm(r_tiles[i].forward); }
/******************************************************************************\ Use the previous camera move to calculate camera velocity and let the globe spin by itself until it is grabbed again. \******************************************************************************/ void R_release_cam(void) { cam_gradual = FALSE; cam_momentum = TRUE; if (c_frame - last_cam_move > 1) return; cam_rot_diff = C_vec3_divf(cam_rot_diff, c_frame_sec); }
/******************************************************************************\ Subdivide each globe tile into four tiles. Partioned tile vertices are numbered in the following manner: 3 / \ 4---5 6 2---1 9 / \ \ / / \ 7---8 0 10-11 A vertex's neighbor is the vertex of the tile that shares the next counter- clockwise edge of the tile from that vertex. \******************************************************************************/ static void subdivide4(void) { c_vec3_t mid_0_1, mid_0_2, mid_1_2; r_globe_vertex_t *verts; int i, i_flip, j, n[3], n_flip[3]; for (i = r_tiles_max - 1; i >= 0; i--) { verts = r_globe_verts + 12 * i; /* Determine which faces are flipped (over 0 vertex) */ i_flip = i < flip_limit; for (j = 0; j < 3; j++) { n[j] = r_globe_verts[3 * i + j].next / 3; n_flip[j] = (n[j] < flip_limit) != i_flip; } /* Compute mid-point coordinates */ mid_0_1 = C_vec3_add(r_globe_verts[3 * i].v.co, r_globe_verts[3 * i + 1].v.co); mid_0_1 = C_vec3_divf(mid_0_1, 2.f); mid_0_2 = C_vec3_add(r_globe_verts[3 * i].v.co, r_globe_verts[3 * i + 2].v.co); mid_0_2 = C_vec3_divf(mid_0_2, 2.f); mid_1_2 = C_vec3_add(r_globe_verts[3 * i + 1].v.co, r_globe_verts[3 * i + 2].v.co); mid_1_2 = C_vec3_divf(mid_1_2, 2.f); /* Bottom-right triangle */ verts[9].v.co = mid_0_2; verts[9].next = 12 * i + 1; verts[10].v.co = mid_1_2; verts[10].next = 12 * n[1] + 8; verts[11].v.co = r_globe_verts[3 * i + 2].v.co; verts[11].next = 12 * n[2] + (n_flip[2] ? 7 : 3); /* Bottom-left triangle */ verts[6].v.co = mid_0_1; verts[6].next = 12 * n[0] + (n_flip[0] ? 9 : 4); verts[7].v.co = r_globe_verts[3 * i + 1].v.co; verts[7].next = 12 * n[1] + 11; verts[8].v.co = mid_1_2; verts[8].next = 12 * i; /* Top triangle */ verts[3].v.co = r_globe_verts[3 * i].v.co; verts[3].next = 12 * n[0] + (n_flip[0] ? 3 : 7); verts[4].v.co = mid_0_1; verts[4].next = 12 * i + 2; verts[5].v.co = mid_0_2; verts[5].next = 12 * n[2] + (n_flip[2] ? 4 : 9); /* Center triangle */ verts[0].v.co = mid_1_2; verts[0].next = 12 * i + 10; verts[1].v.co = mid_0_2; verts[1].next = 12 * i + 5; verts[2].v.co = mid_0_1; verts[2].next = 12 * i + 6; } flip_limit *= 4; r_tiles_max *= 4; r_globe_radius *= 2; sphericize(); }