/// From the OVR SDK. void OculusAppSkeleton::AssembleViewMatrix() { // Rotate and position m_oculusView Camera, using YawPitchRoll in BodyFrame coordinates. // OVR::Matrix4f rollPitchYaw = GetRollPitchYaw(); OVR::Vector3f up = rollPitchYaw.Transform(UpVector); OVR::Vector3f forward = rollPitchYaw.Transform(ForwardVector); // Minimal head modelling. float headBaseToEyeHeight = 0.15f; // Vertical height of eye from base of head float headBaseToEyeProtrusion = 0.09f; // Distance forward of eye from base of head OVR::Vector3f eyeCenterInHeadFrame(0.0f, headBaseToEyeHeight, -headBaseToEyeProtrusion); OVR::Vector3f shiftedEyePos = EyePos + rollPitchYaw.Transform(eyeCenterInHeadFrame); shiftedEyePos.y -= eyeCenterInHeadFrame.y; // Bring the head back down to original height m_oculusView = OVR::Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + forward, up); // This is what transformation would be without head modeling. // m_oculusView = Matrix4f::LookAtRH(EyePos, EyePos + forward, up); /// Set up a third person(or otherwise) view for control window { OVR::Vector3f txFollowDisp = rollPitchYaw.Transform(FollowCamDisplacement); FollowCamPos = EyePos + txFollowDisp; m_controlView = OVR::Matrix4f::LookAtRH(FollowCamPos, EyePos, up); } }
Vector3f OvrSceneView::HeadModelOffset( float EyeRoll, float EyePitch, float EyeYaw, float HeadModelDepth, float HeadModelHeight ) { // head-on-a-stick model const Matrix4f rollPitchYaw = Matrix4f::RotationY( EyeYaw ) * Matrix4f::RotationX( EyePitch ) * Matrix4f::RotationZ( EyeRoll ); Vector3f eyeCenterInHeadFrame( 0.0f, HeadModelHeight, -HeadModelDepth ); Vector3f lastHeadModelOffset = rollPitchYaw.Transform( eyeCenterInHeadFrame ); lastHeadModelOffset.y -= eyeCenterInHeadFrame.y; // Bring the head back down to original height return lastHeadModelOffset; }
Vector3f OvrSceneView::HeadModelOffset( float EyeRoll, float EyePitch, float EyeYaw, float HeadModelLength, float HeadModelAngle ) { const float radAngle = HeadModelAngle / 180.0f * M_PI; const float headBaseToEyeHeight = cosf( radAngle ) * HeadModelLength; // Vertical height of eye from base of head const float headBaseToEyeProtrusion = sinf( radAngle ) * HeadModelLength; // Distance forward of eye from base of head // head-on-a-stick model const Matrix4f rollPitchYaw = Matrix4f::RotationY( EyeYaw ) * Matrix4f::RotationX( EyePitch ) * Matrix4f::RotationZ( EyeRoll ); Vector3f eyeCenterInHeadFrame( 0.0f, headBaseToEyeHeight, -headBaseToEyeProtrusion ); Vector3f lastHeadModelOffset = rollPitchYaw.Transform( eyeCenterInHeadFrame ); lastHeadModelOffset.y -= eyeCenterInHeadFrame.y; // Bring the head back down to original height return lastHeadModelOffset; }
Matrix LibOVR_Adaptor::getViewMatrixAfterMovement() { //float headBaseToEyeHeight = 0.15f; // Vertical height of eye from base of head //float headBaseToEyeProtrusion = 0.09f; // Distance forward of eye from base of head //OVR::Matrix4f rollPitchYaw = OVR::Matrix4f::RotationY(EyeYaw) * OVR::Matrix4f::RotationX(EyePitch) * OVR::Matrix4f::RotationZ(EyeRoll); //OVR::Vector3f up = rollPitchYaw.Transform( OVR::Vector3f(0, Up[y], Up[z])); //OVR::Vector3f forward = rollPitchYaw.Transform( OVR::Vector3f(Dir[x], Dir[y], Dir[z])); OVR::Vector3f eyeCenterInHeadFrame(0.0f, 0.15f, -0.09f); OVR::Vector3f shiftedEyePos = this->EyePos + eyeCenterInHeadFrame; EyePos.y -= eyeCenterInHeadFrame.y; // Bring the head back down to original height //OVR::Matrix4f View = OVR::Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + forward, up); Matrix RotX( ROT_X, this->EyePitch * -1); Matrix RotY( ROT_Y, (this->EyeYaw + 180) * -1 ); Matrix RotZ( ROT_Z, this->EyeRoll * -1 ); Matrix Trans( TRANS, this->EyePos.x, this->EyePos.y, this->EyePos.z); return (RotY * RotX * RotZ);// * Trans); }
void OculusRoomTinyApp::OnIdle() { double curtime = GetAppTime(); float dt = float(curtime - LastUpdate); LastUpdate = curtime; // Handle Sensor motion. // We extract Yaw, Pitch, Roll instead of directly using the orientation // to allow "additional" yaw manipulation with mouse/controller. if (pSensor) { Quatf hmdOrient = SFusion.GetOrientation(); float yaw = 0.0f; hmdOrient.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &EyePitch, &EyeRoll); EyeYaw += (yaw - LastSensorYaw); LastSensorYaw = yaw; } // Gamepad rotation. EyeYaw -= GamepadRotate.x * dt; if (!pSensor) { // Allow gamepad to look up/down, but only if there is no Rift sensor. EyePitch -= GamepadRotate.y * dt; const float maxPitch = ((3.1415f/2)*0.98f); if (EyePitch > maxPitch) EyePitch = maxPitch; if (EyePitch < -maxPitch) EyePitch = -maxPitch; } // Handle keyboard movement. // This translates EyePos based on Yaw vector direction and keys pressed. // Note that Pitch and Roll do not affect movement (they only affect view). if (MoveForward || MoveBack || MoveLeft || MoveRight) { Vector3f localMoveVector(0,0,0); Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw); if (MoveForward) localMoveVector = ForwardVector; else if (MoveBack) localMoveVector = -ForwardVector; if (MoveRight) localMoveVector += RightVector; else if (MoveLeft) localMoveVector -= RightVector; // Normalize vector so we don't move faster diagonally. localMoveVector.Normalize(); Vector3f orientationVector = yawRotate.Transform(localMoveVector); orientationVector *= MoveSpeed * dt * (ShiftDown ? 3.0f : 1.0f); EyePos += orientationVector; } else if (GamepadMove.LengthSq() > 0) { Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw); Vector3f orientationVector = yawRotate.Transform(GamepadMove); orientationVector *= MoveSpeed * dt; EyePos += orientationVector; } // Rotate and position View Camera, using YawPitchRoll in BodyFrame coordinates. // Matrix4f rollPitchYaw = Matrix4f::RotationY(EyeYaw) * Matrix4f::RotationX(EyePitch) * Matrix4f::RotationZ(EyeRoll); Vector3f up = rollPitchYaw.Transform(UpVector); Vector3f forward = rollPitchYaw.Transform(ForwardVector); // Minimal head modelling. float headBaseToEyeHeight = 0.15f; // Vertical height of eye from base of head float headBaseToEyeProtrusion = 0.09f; // Distance forward of eye from base of head Vector3f eyeCenterInHeadFrame(0.0f, headBaseToEyeHeight, -headBaseToEyeProtrusion); Vector3f shiftedEyePos = EyePos + rollPitchYaw.Transform(eyeCenterInHeadFrame); shiftedEyePos.y -= eyeCenterInHeadFrame.y; // Bring the head back down to original height View = Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + forward, up); // This is what transformation would be without head modeling. // View = Matrix4f::LookAtRH(EyePos, EyePos + forward, up); switch(SConfig.GetStereoMode()) { case Stereo_None: Render(SConfig.GetEyeRenderParams(StereoEye_Center)); break; case Stereo_LeftRight_Multipass: Render(SConfig.GetEyeRenderParams(StereoEye_Left)); Render(SConfig.GetEyeRenderParams(StereoEye_Right)); break; } pRender->Present(); // Force GPU to flush the scene, resulting in the lowest possible latency. pRender->ForceFlushGPU(); }