Ejemplo n.º 1
0
        /// <summary>
        /// If new data is available, updates <see cref="LatestPose"/>.
        /// </summary>
        /// <remarks>
        /// If the client "connection" was interrupted, this call will automatically attempt to reconnect. If
        /// something goes wrong during that process, it's possible that the call could throw an exception.
        /// </remarks>
        /// <returns>True if new data was available, false otherwise.</returns>
        public bool UpdatePose()
        {
            if (m_bPendingReconnect)
            {
                // Note: This call could throw.
                if (InternalConnect())
                {
                    // Successfully reconnected; clear the flag and continue normally.
                    m_bPendingReconnect = false;
                }
                else
                {
                    // Failed to reconnect; don't go any further, but try to reconnect again next time.
                    return(false);
                }
            }

            NPResult getDataResult = m_clientLib.NP_GetData(ref m_trackirData, 0, 0);

            if (getDataResult == NPResult.OK)
            {
                if (m_trackirData.FrameSignature != m_latestFrameSignature)
                {
                    // We got fresh data, so update the latest cached/transformed pose.
                    const float kEncodedRangeMinMax             = 16383.0f;
                    const float kDecodedTranslationMinMaxMeters = 0.5f;           // +/- 50 cm
                    const float kDecodedRotationMinMaxRadians   = (float)Math.PI; // +/- 180 deg

                    // Negate right-hand rule rotations to be consistent with left-handed coordinate basis.
                    // See remarks in the comments for the TrackIRData struct for more information.
                    float rollRad  = (-m_trackirData.Roll / kEncodedRangeMinMax) * kDecodedRotationMinMaxRadians;
                    float pitchRad = (-m_trackirData.Pitch / kEncodedRangeMinMax) * kDecodedRotationMinMaxRadians;
                    float yawRad   = (-m_trackirData.Yaw / kEncodedRangeMinMax) * kDecodedRotationMinMaxRadians;
                    float xMeters  = (m_trackirData.X / kEncodedRangeMinMax) * kDecodedTranslationMinMaxMeters;
                    float yMeters  = (m_trackirData.Y / kEncodedRangeMinMax) * kDecodedTranslationMinMaxMeters;
                    float zMeters  = (m_trackirData.Z / kEncodedRangeMinMax) * kDecodedTranslationMinMaxMeters;

                    m_latestPose.Orientation    = Pose.Quaternion.FromTaitBryanIntrinsicZYX(rollRad, yawRad, pitchRad);
                    m_latestPose.PositionMeters = new Pose.Vector3(xMeters, yMeters, zMeters);

                    m_latestFrameSignature = m_trackirData.FrameSignature;

                    // Successfully retrieved a new pose.
                    return(true);
                }
                else
                {
                    // No error, but no new data available.
                    return(false);
                }
            }
            else
            {
                // Got an unexpected return code from the NP_GetData call.
                m_latestFrameSignature = -1;
                m_bPendingReconnect    = true;
                return(false);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Stops data transmission and unregisters the application's window handle.
        /// </summary>
        public void Disconnect()
        {
            if (m_bDataTransmitting)
            {
                NPResult stopDataResult = m_clientLib.NP_StopDataTransmission();
                if (stopDataResult != NPResult.OK)
                {
                    Console.WriteLine("WARNING: NP_StopDataTransmission returned " + stopDataResult.ToString() + ".");
                }

                m_bDataTransmitting = false;
            }

            if (m_bRegisteredWindowHandle)
            {
                NPResult unregisterResult = m_clientLib.NP_UnregisterWindowHandle();
                if (unregisterResult != NPResult.OK)
                {
                    Console.WriteLine("WARNING: NP_UnregisterWindowHandle returned " + unregisterResult.ToString() + ".");
                }

                m_bRegisteredWindowHandle = false;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Uses the cached appId and hwnd to initialize the TrackIR API.
        /// </summary>
        /// <returns>
        /// True if initialization completed successfully, false if the API returned the code
        /// <see cref="NPResult.ERR_DEVICE_NOT_PRESENT"/>. Any other failure condition throws an exception.
        /// </returns>
        private bool InternalConnect()
        {
            // Clear this flag. Most exit paths from this function represent errors we can't recover from, and we
            // shouldn't keep trying repeatedly; the only exception is waiting for ERR_DEVICE_NOT_PRESENT to resolve.
            m_bPendingReconnect = false;

            // Retrieve host software version.
            UInt16   version;
            NPResult queryVersionResult = m_clientLib.NP_QueryVersion(out version);

            if (queryVersionResult == NPResult.ERR_DEVICE_NOT_PRESENT)
            {
                // Don't go any further; we'll try to connect again next time UpdatePose is called.
                m_bPendingReconnect = true;
                return(false);
            }
            else if (queryVersionResult != NPResult.OK)
            {
                Console.WriteLine("WARNING: NP_QueryVersion returned " + queryVersionResult.ToString() + ".");
            }

            HostSoftwareVersionMajor = (version >> 8);
            HostSoftwareVersionMinor = (version & 0x00FF);

            // Retrieve signature object and validate that signature strings match expected values.
            TrackIRSignature signature          = new TrackIRSignature();
            NPResult         getSignatureResult = m_clientLib.NP_GetSignature(ref signature);

            if (getSignatureResult != NPResult.OK)
            {
                throw new TrackIRException("NP_GetSignature returned " + getSignatureResult.ToString() + ".");
            }

            const string kExpectedAppSignature = "hardware camera\n software processing data\n track user movement\n\n Copyright EyeControl Technologies";
            const string kExpectedDllSignature = "precise head tracking\n put your head into the game\n now go look around\n\n Copyright EyeControl Technologies";

            if (signature.AppSignature != kExpectedAppSignature || signature.DllSignature != kExpectedDllSignature)
            {
                throw new TrackIRException("Unable to verify TrackIR Enhanced signature values.");
            }

            // Register the application window for liveness checks. This allows the TrackIR software to
            // detect situations where e.g. your application crashes and fails to shut down cleanly.
            NPResult registerHwndResult = m_clientLib.NP_RegisterWindowHandle(m_appHwnd);

            if (registerHwndResult == NPResult.OK)
            {
                m_bRegisteredWindowHandle = true;
            }
            else
            {
                throw new TrackIRException("NP_RegisterWindowHandle returned " + registerHwndResult.ToString() + ".");
            }

            // Register the application by its NaturalPoint-assigned ID.
            NPResult registerIdResult = m_clientLib.NP_RegisterProgramProfileID(m_appId);

            if (registerIdResult != NPResult.OK)
            {
                throw new TrackIRException("NP_RegisterProgramProfileID returned " + registerIdResult.ToString() + ".");
            }

            // Signal that we want to start receiving tracking data.
            NPResult startDataResult = m_clientLib.NP_StartDataTransmission();

            if (startDataResult == NPResult.OK)
            {
                m_bDataTransmitting = true;
            }
            else
            {
                throw new TrackIRException("NP_StartDataTransmission returned " + startDataResult.ToString() + ".");
            }

            return(true);
        }