+
+ /* calculate the mouselook view matrix */
+ mouse_view_matrix = Mat4::identity;
+ if(!have_headtracking) {
+ mouse_view_matrix.pre_rotate_x(deg_to_rad(cam_phi));
+ }
+ mouse_view_matrix.pre_rotate_y(deg_to_rad(cam_theta));
+ mouse_view_matrix.pre_translate(0, -cam_height, 0);
+
+ long interval = time_msec - last_pointer_time;
+ if(interval < LASER_TIMEOUT) {
+ Vec3 target;
+
+ if(have_headtracking) {
+ target.x = sin(deg_to_rad(mtheta)) * cos(deg_to_rad(mphi)) * 200.0;
+ target.y = sin(deg_to_rad(mphi)) * 200.0;
+ target.z = -cos(deg_to_rad(mtheta)) * cos(deg_to_rad(mphi)) * 200.0;
+
+ mray.origin = inverse(view_matrix) * Vec3(0.2, -0.4, 0.0);
+ } else {
+ /* pick on a distant sphere to find where the mouse is pointing to
+ * and use that as the other end of the mouse ray
+ */
+ float px = 2.0 * (float)mouse_x / win_width - 1.0;
+ float py = 1.0 - (2.0 * (float)mouse_y / win_height);
+
+ Mat4 mvp_inv = inverse(mouse_view_matrix * proj_matrix);
+ Vec4 vfar = mvp_inv * Vec4(px, py, 1, 1);
+
+ target = vfar.xyz() / vfar.w;
+
+ mray.origin = Vec3(0, cam_height, 0);
+ }
+
+ mray.dir = target - mray.origin;
+
+ laser_alpha = 1.0 - std::max(4.0f * interval / LASER_TIMEOUT - 3.0f, 0.0f);
+ } else {
+ laser_alpha = 0.0f;
+ }