HMDUtils.FusionService.Quat Adapt(HMDUtils.OVRPluginServices.Quatf In)
 {
     HMDUtils.FusionService.Quat Output = new HMDUtils.FusionService.Quat(In.x, In.y, In.z, In.w);
     return(Output);
 }
Beispiel #2
0
    void LateUpdate()
    {
        try
        {
            double Time             = HMDUtils.FusionService.GetTime();
            uint   ViconFrameNumber = Client.GetFrameNumber();

            //position
            Output_GetSubjectRootSegmentName  RootName    = Client.GetSubjectRootSegmentName(HmdName);
            Output_GetSegmentLocalTranslation Translation = Client.GetSegmentTranslation(HmdName, RootName.SegmentName);

            // Raw Vicon position, scale is in mm. The data here is in the datastream default; x-forward, y-left, z-up for the global coordinate system
            HMDUtils.FusionService.Vec ViconPosition = new HMDUtils.FusionService.Vec(Translation.Translation[0], Translation.Translation[1], Translation.Translation[2]);

            //orientation. The local coordinate system of the HMD object is x-right, y-up, z-back
            Output_GetSegmentLocalRotationQuaternion Rot = Client.GetSegmentRotation(HmdName, RootName.SegmentName);

            // Raw Vicon orientation
            HMDUtils.FusionService.Quat ViconOrientation = new HMDUtils.FusionService.Quat(Rot.Rotation[0], Rot.Rotation[1], Rot.Rotation[2], Rot.Rotation[3]);

            // If we don't get a result, or the pose returned from the datastream is occluded, then we will use the last known good position that we received.
            bool bViconPoseValid = true;

            if (Rot.Result != ViconDataStreamSDK.CSharp.Result.Success || Rot.Occluded || Translation.Occluded)
            {
                // We use this flag to determine whether to initialize the fusion algorithm; we don't want to initialize it on occluded frames
                bViconPoseValid = false;

                if (m_LastGoodPose != null)
                {
                    ViconPosition    = m_LastGoodPose.Position;
                    ViconOrientation = m_LastGoodPose.Rotation;
                }
                else
                {
                    // If all else fails, we will return the origin :(
                    ViconOrientation = new HMDUtils.FusionService.Quat(0, 0, 0, 1);
                }
            }
            else
            {
                if (m_LastGoodPose == null)
                {
                    m_LastGoodPose = new HMDUtils.FusionService.Pose(ViconPosition, ViconOrientation);
                }
                else
                {
                    m_LastGoodPose.Position = ViconPosition;
                    m_LastGoodPose.Rotation = ViconOrientation;
                }
            }

            //Oculus space. We need to translate to the oculus coordinate system here so that the fusion algorithm can work with all data in the same coordinate system.
            // The Vicon data comes in as z-up, x-forward rhs. We convert to y-up, z-back rhs. The local coordinate system of the tracked Oculus object in the Vicon data is already y-up, z-back.
            // The conversion also scales from mm to m.

            //           Vicon Oculus  Unity
            // forward    x     -z     z
            // up         z      y     y
            // right     -y      x     x

            //HMDUtils.FusionService.Quat ViconOrientationInOculus = new HMDUtils.FusionService.Quat(-ViconOrientation.Y, ViconOrientation.Z, -ViconOrientation.X, ViconOrientation.W);
            //HMDUtils.FusionService.Vec ViconPositionInOculus = new HMDUtils.FusionService.Vec(-ViconPosition.Y * 0.001, ViconPosition.Z * 0.001, -ViconPosition.X * 0.001);
            //HMDUtils.FusionService.Pose ViconInOculus = new HMDUtils.FusionService.Pose( ViconPositionInOculus, ViconOrientationInOculus );

            HMDUtils.FusionService.Pose ViconInOculus = HMDUtils.FusionService.GetMappedVicon(ViconOrientation, ViconPosition);

            // The pose from the oculus; this is already in oculus coordinate system - y-up, z-back, rhs
            HMDUtils.OVRPluginServices.PoseStatef HMDState = HMDUtils.OVRPluginServices.ovrp_GetNodePoseState(HMDUtils.OVRPluginServices.Step.Render, HMDUtils.OVRPluginServices.Node.EyeCenter);

            HMDUtils.OVRPluginServices.Quatf    HmdOrt  = HMDState.Pose.Orientation;
            HMDUtils.OVRPluginServices.Vector3f HmdOrtV = HMDState.AngularVelocity;
            HMDUtils.OVRPluginServices.Vector3f HmdOrtA = HMDState.AngularAcceleration;

            HMDUtils.OVRPluginServices.Vector3f HmdPos  = HMDState.Pose.Position;
            HMDUtils.OVRPluginServices.Vector3f HmdPosV = HMDState.Velocity;
            HMDUtils.OVRPluginServices.Vector3f HmdPosA = HMDState.Acceleration;

            if (m_Service != null)
            {
                HMDUtils.FusionService.Quat Output;
                if (m_Service.GetUpdatedOrientation(Time,
                                                    Adapt(HmdOrt),
                                                    Adapt(HmdOrtV),
                                                    Adapt(HmdOrtA),
                                                    ViconInOculus.Rotation,
                                                    ViconInOculus.Position,
                                                    bViconPoseValid,
                                                    (float)1,
                                                    (float)0.0137,
                                                    (float)0.00175,
                                                    out Output))
                {
                    if (Log)
                    {
                        m_Log.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},{17},{18},{19},{20},{21},{22},{23},{24},{25},{26},{27},{28},{29},{30},{31},{32},{33},{34},{35}",
                                        Time, HMDState.Time,
                                        HmdOrt.x, HmdOrt.y, HmdOrt.z, HmdOrt.w,
                                        HmdOrtV.x, HmdOrtV.y, HmdOrtV.z,
                                        HmdOrtA.x, HmdOrtA.y, HmdOrtA.z,
                                        HmdPos.x, HmdPos.y, HmdPos.z,
                                        HmdPosV.x, HmdPosV.y, HmdPosV.z,
                                        HmdPosA.x, HmdPosA.y, HmdPosA.z,
                                        ViconFrameNumber,
                                        ViconInOculus.Rotation.X, ViconInOculus.Rotation.Y, ViconInOculus.Rotation.Z, ViconInOculus.Rotation.W,
                                        ViconInOculus.Position.X, ViconInOculus.Position.Y, ViconInOculus.Position.Z,
                                        ViconOrientation.X, ViconOrientation.Y, ViconOrientation.Z, ViconOrientation.W,
                                        ViconPosition.X, ViconPosition.Y, ViconPosition.Z);
                    }

                    // We are in Oculus co-ordinate space: y-up, z-backward rhs. We need to convert to Unity, which is y-up, z-forward lhs - eg a reflection in the xy plane
                    Quaternion OutputOrt = new Quaternion((float)-Output.X, (float)-Output.Y, (float)Output.Z, (float)Output.W);
                    Quaternion OculusOrt = new Quaternion((float)-HmdOrt.x, (float)-HmdOrt.y, (float)HmdOrt.z, (float)HmdOrt.w);
                    transform.localPosition = new Vector3((float)ViconInOculus.Position.X, (float)ViconInOculus.Position.Y, (float)-ViconInOculus.Position.Z);

                    transform.localRotation = OutputOrt * Quaternion.Inverse(OculusOrt);
                }
            }
        }
        catch (DllNotFoundException ex)
        {
            Debug.LogError(string.Format("XR must be enabled for this project to use the HMD fusion script: Error {0}", ex.Message));
        }
    }