void game_look(float phi, float theta) { struct game_view *view = &gl.view[CURR]; view->c[0] = view->p[0] + fsinf(V_RAD(theta)) * fcosf(V_RAD(phi)); view->c[1] = view->p[1] + fsinf(V_RAD(phi)); view->c[2] = view->p[2] - fcosf(V_RAD(theta)) * fcosf(V_RAD(phi)); gl.view[PREV] = gl.view[CURR]; }
static void title_timer(int id, float dt) { float g[3] = { 0.f, 0.f, 0.f }; game_step(g, dt); game_set_fly(fcosf(time_state() / 10.f)); gui_timer(id, dt); }
void video_push_persp(float fov, float n, float f) { if (hmd_stat()) hmd_persp(n, f); else { GLfloat m[4][4]; GLfloat r = fov / 2 * V_PI / 180; GLfloat s = fsinf(r); GLfloat c = fcosf(r) / s; GLfloat a = ((GLfloat) video.device_w / (GLfloat) video.device_h); glMatrixMode(GL_PROJECTION); { glLoadIdentity(); m[0][0] = c / a; m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = 0.0f; m[1][0] = 0.0f; m[1][1] = c; m[1][2] = 0.0f; m[1][3] = 0.0f; m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = -(f + n) / (f - n); m[2][3] = -1.0f; m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = -2.0f * n * f / (f - n); m[3][3] = 0.0f; glMultMatrixf(&m[0][0]); } glMatrixMode(GL_MODELVIEW); { glLoadIdentity(); } } }
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 title_timer(int id, float dt) { static const char *demo = NULL; float t; real_time += dt; switch (mode) { case 0: /* Mode 0: Pan across title level. */ if (real_time <= 20.0f) game_set_fly(fcosf(V_PI * real_time / 20.0f)); else { game_fade(+1.0f); real_time = 0.0f; mode = 1; } break; case 1: /* Mode 1: Fade out. Load demo level. */ if (real_time > 1.0f) { if ((demo = demo_pick())) { demo_replay_init(demo, NULL, NULL, NULL, NULL); demo_time = 0.0f; real_time = 0.0f; mode = 2; } else { game_fade(-1.0f); real_time = 0.0f; mode = 0; } } break; case 2: /* Mode 2: Run demo. */ while (demo_time < real_time) if (demo_replay_step(&t)) demo_time += t; else { demo_replay_stop(0); game_fade(+1.0f); real_time = 0.0f; mode = 3; } break; case 3: /* Mode 3: Fade out. Load title level. */ if (real_time > 1.0f) { game_init("map-rlk/title.sol", "map-back/jupiter.sol", "png/space.png", 0, 1); real_time = 0.0f; mode = 0; } break; } gui_timer(id, dt); audio_timer(dt); game_step_fade(dt); }
static void title_timer(int id, float dt) { static const char *demo = NULL; real_time += dt; switch (mode) { case MODE_LEVEL: /* Pan across title level. */ if (real_time <= 20.0f) { game_client_fly(fcosf(V_PI * real_time / 20.0f)); } else { game_fade(+1.0f); real_time = 0.0f; mode = MODE_LEVEL_FADE; } break; case MODE_LEVEL_FADE: /* Fade out. Load demo level. */ if (real_time > 1.0f) { if (!items) items = demo_dir_scan(); if ((demo = pick_demo(items))) { demo_replay_init(demo, NULL, NULL, NULL, NULL, NULL); game_client_fly(0.0f); real_time = 0.0f; mode = MODE_DEMO; } else { game_fade(-1.0f); real_time = 0.0f; mode = MODE_LEVEL; } } break; case MODE_DEMO: /* Run demo. */ if (!demo_replay_step(dt)) { demo_replay_stop(0); game_fade(+1.0f); real_time = 0.0f; mode = MODE_DEMO_FADE; } else game_client_blend(demo_replay_blend()); break; case MODE_DEMO_FADE: /* Fade out. Load title level. */ if (real_time > 1.0f) { init_title_level(); real_time = 0.0f; mode = MODE_LEVEL; } break; } gui_timer(id, dt); game_step_fade(dt); }
void game_look(float phi, float theta) { view_c[0] = view_p[0] + fsinf(V_RAD(theta)) * fcosf(V_RAD(phi)); view_c[1] = view_p[1] + fsinf(V_RAD(phi)); view_c[2] = view_p[2] - fcosf(V_RAD(theta)) * fcosf(V_RAD(phi)); }
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])); }
static void game_update_view(float dt) { float dc = view.dc * (jump_b > 0 ? 2.0f * fabsf(jump_dt - 0.5f) : 1.0f); float da = input_get_r() * dt * 90.0f; float k; float M[16], v[3], Y[3] = { 0.0f, 1.0f, 0.0f }; float view_v[3]; float spd = (float) cam_speed(input_get_c()) / 1000.0f; /* Track manual rotation time. */ if (da == 0.0f) { if (view_time < 0.0f) { /* Transition time is influenced by activity time. */ view_fade = CLAMP(VIEW_FADE_MIN, -view_time, VIEW_FADE_MAX); view_time = 0.0f; } /* Inactivity. */ view_time += dt; } else { if (view_time > 0.0f) { view_fade = 0.0f; view_time = 0.0f; } /* Activity (yes, this is negative). */ view_time -= dt; } /* Center the view about the ball. */ v_cpy(view.c, vary.uv->p); view_v[0] = -vary.uv->v[0]; view_v[1] = 0.0f; view_v[2] = -vary.uv->v[2]; /* Compute view vector. */ if (spd >= 0.0f) { /* Viewpoint chases ball position. */ if (da == 0.0f) { float s; v_sub(view.e[2], view.p, view.c); v_nrm(view.e[2], view.e[2]); /* Gradually restore view vector convergence rate. */ s = fpowf(view_time, 3.0f) / fpowf(view_fade, 3.0f); s = CLAMP(0.0f, s, 1.0f); v_mad(view.e[2], view.e[2], view_v, v_len(view_v) * spd * s * dt); } } else { /* View vector is given by view angle. */ view.e[2][0] = fsinf(V_RAD(view.a)); view.e[2][1] = 0.0; view.e[2][2] = fcosf(V_RAD(view.a)); } /* Apply manual rotation. */ if (da != 0.0f) { m_rot(M, Y, V_RAD(da)); m_vxfm(v, M, view.e[2]); v_cpy(view.e[2], v); } /* Orthonormalize the new view reference frame. */ 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_scl(v, view.e[1], view.dp * view_k); v_mad(v, v, view.e[2], view.dz * view_k); v_add(view.p, v, vary.uv->p); /* Compute the new view center. */ v_cpy(view.c, vary.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])); game_cmd_updview(); }