void ohmd_calc_default_proj_matrices(ohmd_device_properties* props) { mat4x4f proj_base; // base projection matrix // Calculate where the lens is on each screen, // and with the given value offset the projection matrix. float screen_center = props->hsize / 4.0f; float lens_shift = screen_center - props->lens_sep / 2.0f; float proj_offset = 4.0f * lens_shift / props->hsize; // Setup the base projection matrix. Each eye mostly have the // same projection matrix with the exception of the offset. omat4x4f_init_perspective(&proj_base, props->fov, props->ratio, props->znear, props->zfar); // Setup the two adjusted projection matricies. Each is setup to deal // with the fact that the lens is not in the center of the screen. // These matrices only change of the hardware changes, so static. mat4x4f translate; omat4x4f_init_translate(&translate, proj_offset, 0, 0); omat4x4f_mult(&translate, &proj_base, &props->proj_left); omat4x4f_init_translate(&translate, -proj_offset, 0, 0); omat4x4f_mult(&translate, &proj_base, &props->proj_right); }
static void calc_derived_values(rift_priv *priv) { priv->base.properties.hsize = priv->display_info.h_screen_size; priv->base.properties.vsize = priv->display_info.v_screen_size; priv->base.properties.hres = priv->display_info.h_resolution; priv->base.properties.vres = priv->display_info.v_resolution; priv->base.properties.lens_sep = priv->display_info.lens_separation; priv->base.properties.lens_vpos = priv->display_info.v_center; priv->base.properties.fov = DEG_TO_RAD(125.5144f); // TODO calculate. // Calculate the screen ratio of each subscreen. float full_ratio = (float)priv->display_info.h_resolution / (float)priv->display_info.v_resolution; float ratio = full_ratio / 2.0f; priv->base.properties.ratio = ratio; // Calculate where the lens is on each screen, // and with the given value offset the projection matrix. float screen_center = priv->display_info.h_screen_size / 4.0f; float lens_shift = screen_center - priv->display_info.lens_separation / 2.0f; float proj_offset = 4.0f * lens_shift / priv->display_info.h_screen_size; priv->calc_values.proj_offset = proj_offset; // Setup the base projection matrix. Each eye mostly have the // same projection matrix with the exception of the offset. omat4x4f_init_perspective(&priv->calc_values.proj_base, priv->base.properties.fov, priv->base.properties.ratio, priv->base.properties.znear, priv->base.properties.zfar); // Setup the two adjusted projection matricies. Each is setup to deal // with the fact that the lens is not in the center of the screen. // These matrices only change of the hardware changes, so static. mat4x4f translate; omat4x4f_init_translate(&translate, proj_offset, 0, 0); omat4x4f_mult(&translate, &priv->calc_values.proj_base, &priv->base.properties.proj_left); omat4x4f_init_translate(&translate, -proj_offset, 0, 0); omat4x4f_mult(&translate, &priv->calc_values.proj_base, &priv->base.properties.proj_right); }
int OHMD_APIENTRY ohmd_device_getf(ohmd_device* device, ohmd_float_value type, float* out) { switch(type){ case OHMD_LEFT_EYE_GL_MODELVIEW_MATRIX: { vec3f point = {{0, 0, 0}}; quatf rot; device->getf(device, OHMD_ROTATION_QUAT, (float*)&rot); quatf tmp = device->rotation_correction; oquatf_mult_me(&tmp, &rot); rot = tmp; mat4x4f orient, world_shift, result; omat4x4f_init_look_at(&orient, &rot, &point); omat4x4f_init_translate(&world_shift, +(device->properties.ipd / 2.0f), 0, 0); omat4x4f_mult(&world_shift, &orient, &result); omat4x4f_transpose(&result, (mat4x4f*)out); return OHMD_S_OK; } case OHMD_RIGHT_EYE_GL_MODELVIEW_MATRIX: { vec3f point = {{0, 0, 0}}; quatf rot; device->getf(device, OHMD_ROTATION_QUAT, (float*)&rot); oquatf_mult_me(&rot, &device->rotation_correction); mat4x4f orient, world_shift, result; omat4x4f_init_look_at(&orient, &rot, &point); omat4x4f_init_translate(&world_shift, -(device->properties.ipd / 2.0f), 0, 0); omat4x4f_mult(&world_shift, &orient, &result); omat4x4f_transpose(&result, (mat4x4f*)out); return OHMD_S_OK; } case OHMD_LEFT_EYE_GL_PROJECTION_MATRIX: omat4x4f_transpose(&device->properties.proj_left, (mat4x4f*)out); return OHMD_S_OK; case OHMD_RIGHT_EYE_GL_PROJECTION_MATRIX: omat4x4f_transpose(&device->properties.proj_right, (mat4x4f*)out); return OHMD_S_OK; case OHMD_SCREEN_HORIZONTAL_SIZE: *out = device->properties.hsize; return OHMD_S_OK; case OHMD_SCREEN_VERTICAL_SIZE: *out = device->properties.vsize; return OHMD_S_OK; case OHMD_LENS_HORIZONTAL_SEPARATION: *out = device->properties.lens_sep; return OHMD_S_OK; case OHMD_LENS_VERTICAL_POSITION: *out = device->properties.lens_vpos; return OHMD_S_OK; case OHMD_RIGHT_EYE_FOV: case OHMD_LEFT_EYE_FOV: *out = device->properties.fov; return OHMD_S_OK; case OHMD_RIGHT_EYE_ASPECT_RATIO: case OHMD_LEFT_EYE_ASPECT_RATIO: *out = device->properties.ratio; return OHMD_S_OK; case OHMD_EYE_IPD: *out = device->properties.ipd; return OHMD_S_OK; case OHMD_PROJECTION_ZFAR: *out = device->properties.zfar; return OHMD_S_OK; case OHMD_PROJECTION_ZNEAR: *out = device->properties.znear; return OHMD_S_OK; case OHMD_ROTATION_QUAT: { int ret = device->getf(device, OHMD_ROTATION_QUAT, out); if(ret != 0) return ret; oquatf_mult_me((quatf*)out, &device->rotation_correction); quatf tmp = device->rotation_correction; oquatf_mult_me(&tmp, (quatf*)out); *(quatf*)out = tmp; return OHMD_S_OK; } case OHMD_POSITION_VECTOR: { int ret = device->getf(device, OHMD_POSITION_VECTOR, out); if(ret != 0) return ret; for(int i = 0; i < 3; i++) out[i] += device->position_correction.arr[i]; return OHMD_S_OK; } default: return device->getf(device, type, out); } }
int OHMD_APIENTRY ohmd_device_getf(ohmd_device* device, ohmd_float_value type, float* out) { switch(type){ case OHMD_LEFT_EYE_GL_MODELVIEW_MATRIX: { vec3f point = {{0, 0, 0}}; quatf rot; device->getf(device, OHMD_ROTATION_QUAT, (float*)&rot); mat4x4f orient, world_shift, result; omat4x4f_init_look_at(&orient, &rot, &point); omat4x4f_init_translate(&world_shift, +(device->properties.ipd / 2.0f), 0, 0); omat4x4f_mult(&world_shift, &orient, &result); omat4x4f_transpose(&result, (mat4x4f*)out); return 0; } case OHMD_RIGHT_EYE_GL_MODELVIEW_MATRIX: { vec3f point = {{0, 0, 0}}; quatf rot; device->getf(device, OHMD_ROTATION_QUAT, (float*)&rot); mat4x4f orient, world_shift, result; omat4x4f_init_look_at(&orient, &rot, &point); omat4x4f_init_translate(&world_shift, -(device->properties.ipd / 2.0f), 0, 0); omat4x4f_mult(&world_shift, &orient, &result); omat4x4f_transpose(&result, (mat4x4f*)out); return 0; } case OHMD_LEFT_EYE_GL_PROJECTION_MATRIX: omat4x4f_transpose(&device->properties.proj_left, (mat4x4f*)out); return 0; case OHMD_RIGHT_EYE_GL_PROJECTION_MATRIX: omat4x4f_transpose(&device->properties.proj_right, (mat4x4f*)out); return 0; case OHMD_SCREEN_HORIZONTAL_SIZE: *out = device->properties.hsize; return 0; case OHMD_SCREEN_VERTICAL_SIZE: *out = device->properties.vsize; return 0; case OHMD_LENS_HORIZONTAL_SEPARATION: *out = device->properties.lens_sep; return 0; case OHMD_LENS_VERTICAL_POSITION: *out = device->properties.lens_vpos; return 0; case OHMD_RIGHT_EYE_FOV: case OHMD_LEFT_EYE_FOV: *out = device->properties.fov; return 0; case OHMD_RIGHT_EYE_ASPECT_RATIO: case OHMD_LEFT_EYE_ASPECT_RATIO: *out = device->properties.ratio; return 0; case OHMD_EYE_IPD: *out = device->properties.ipd; return 0; case OHMD_PROJECTION_ZFAR: *out = device->properties.zfar; return 0; case OHMD_PROJECTION_ZNEAR: *out = device->properties.znear; return 0; default: return device->getf(device, type, out); } }