static void game_update_grav(float h[3], const float g[3]) { struct s_file *fp = &file; float x[3]; float y[3] = { 0.f, 1.f, 0.f }; float z[3]; float X[16]; float Z[16]; float M[16]; /* Compute the gravity vector from the given world rotations. */ v_sub(z, view_p, fp->uv->p); v_crs(x, y, z); v_crs(z, x, y); v_nrm(x, x); v_nrm(z, z); // m_rot (Z, z, V_RAD(game_rz)); m_rot (Z, z, V_RAD(game_rz*((20.0f/BOUND)))); // m_rot (X, x, V_RAD(game_rx)); m_rot (X, x, V_RAD(game_rx*((20.0f/BOUND)))); m_mult(M, Z, X); m_vxfm(h, M, g); }
void game_tilt_grav(float h[3], const float g[3], const struct game_tilt *tilt) { float X[16]; float Z[16]; float M[16]; /* Compute the gravity vector from the given world rotations. */ m_rot (Z, tilt->z, V_RAD(tilt->rz)); m_rot (X, tilt->x, V_RAD(tilt->rx)); m_mult(M, Z, X); m_vxfm(h, M, g); }
/* * Integrate the rotation of the given basis E under angular velocity W * through time DT. */ void sol_rotate(float e[3][3], const float w[3], float dt) { if (v_len(w) > 0.0f) { float a[3], M[16], f[3][3]; /* Compute the rotation matrix. */ v_nrm(a, w); m_rot(M, a, v_len(w) * dt); /* Apply it to the basis. */ m_vxfm(f[0], M, e[0]); m_vxfm(f[1], M, e[1]); m_vxfm(f[2], M, e[2]); /* Re-orthonormalize the basis. */ v_crs(e[2], f[0], f[1]); v_crs(e[1], f[2], f[0]); v_crs(e[0], f[1], f[2]); v_nrm(e[0], e[0]); v_nrm(e[1], e[1]); v_nrm(e[2], e[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(); }