/* * Compute appropriate tilt axes from the view basis. */ void game_tilt_axes(struct game_tilt *tilt, float view_e[3][3]) { const float Y[3] = { 0.0f, 1.0f, 0.0f }; v_cpy(tilt->x, view_e[0]); v_cpy(tilt->z, view_e[2]); /* Handle possible top-down view. */ if (fabsf(v_dot(view_e[1], Y)) < fabsf(v_dot(view_e[2], Y))) v_inv(tilt->z, view_e[1]); }
void game_update_view(float dt) { const float y[3] = { 0.f, 1.f, 0.f }; float dy; float dz; float k; float e[3]; float d[3]; float s = 2.f * dt; if (!state) return; /* Center the view about the ball. */ v_cpy(view_c, file.vary.uv[ball].p); v_inv(view_v, file.vary.uv[ball].v); switch (config_get_d(CONFIG_CAMERA)) { case 2: /* Camera 2: View vector is given by view angle. */ view_e[2][0] = fsinf(V_RAD(view_a)); view_e[2][1] = 0.f; view_e[2][2] = fcosf(V_RAD(view_a)); s = 1.f; break; default: /* View vector approaches the ball velocity vector. */ v_mad(e, view_v, y, v_dot(view_v, y)); v_inv(e, e); k = v_dot(view_v, view_v); v_sub(view_e[2], view_p, view_c); v_mad(view_e[2], view_e[2], view_v, k * dt * 0.1f); } /* Orthonormalize the basis of the view in its new position. */ v_crs(view_e[0], view_e[1], view_e[2]); v_crs(view_e[2], view_e[0], view_e[1]); v_nrm(view_e[0], view_e[0]); v_nrm(view_e[2], view_e[2]); /* The current view (dy, dz) approaches the ideal (view_dy, view_dz). */ v_sub(d, view_p, view_c); dy = v_dot(view_e[1], d); dz = v_dot(view_e[2], d); dy += (view_dy - dy) * s; dz += (view_dz - dz) * s; /* Compute the new view position. */ view_p[0] = view_p[1] = view_p[2] = 0.f; v_mad(view_p, view_c, view_e[1], dy); v_mad(view_p, view_p, view_e[2], dz); view_a = V_DEG(fatan2f(view_e[2][0], view_e[2][2])); }
static void game_update_view(float dt) { float dc = view_dc * (jump_b ? 2.0f * fabsf(jump_dt - 0.5f) : 1.0f); float dx = view_ry * dt * 5.0f; float k; view_a += view_ry * dt * 90.f; /* Center the view about the ball. */ v_cpy(view_c, file.uv->p); v_inv(view_v, file.uv->v); switch (config_get_d(CONFIG_CAMERA)) { case 1: /* Camera 1: Viewpoint chases the ball position. */ v_sub(view_e[2], view_p, view_c); break; case 2: /* Camera 2: View vector is given by view angle. */ view_e[2][0] = fsinf(V_RAD(view_a)); view_e[2][1] = 0.f; view_e[2][2] = fcosf(V_RAD(view_a)); dx = 0.0f; break; default: /* Default: View vector approaches the ball velocity vector. */ k = v_dot(view_v, view_v); v_sub(view_e[2], view_p, view_c); v_mad(view_e[2], view_e[2], view_v, k * dt / 4); break; } /* Orthonormalize the basis of the view in its new position. */ v_crs(view_e[0], view_e[1], view_e[2]); v_crs(view_e[2], view_e[0], view_e[1]); v_nrm(view_e[0], view_e[0]); v_nrm(view_e[2], view_e[2]); /* Compute the new view position. */ k = 1.0f + v_dot(view_e[2], view_v) / 10.0f; view_k = view_k + (k - view_k) * dt; if (view_k < 0.5) view_k = 0.5; v_cpy(view_p, file.uv->p); v_mad(view_p, view_p, view_e[0], dx * view_k); v_mad(view_p, view_p, view_e[1], view_dp * view_k); v_mad(view_p, view_p, view_e[2], view_dz * view_k); /* Compute the new view center. */ v_cpy(view_c, file.uv->p); v_mad(view_c, view_c, view_e[1], dc); /* Note the current view angle. */ view_a = V_DEG(fatan2f(view_e[2][0], view_e[2][2])); }