Beispiel #1
0
        /// <summary>
        /// The system calls this each frame to update haptics playback.
        /// </summary>
        public void Process()
        {
            var hapticsState = OVRPlugin.GetControllerHapticsState(m_controller);

            float elapsedTime = Time.realtimeSinceStartup - m_prevSamplesQueuedTime;

            if (m_prevSamplesQueued > 0)
            {
                int expectedSamples = m_prevSamplesQueued - (int)(elapsedTime * OVRHaptics.Config.SampleRateHz + 0.5f);
                if (expectedSamples < 0)
                {
                    expectedSamples = 0;
                }

                if ((hapticsState.SamplesQueued - expectedSamples) == 0)
                {
                    m_numPredictionHits++;
                }
                else
                {
                    m_numPredictionMisses++;
                }

                //Debug.Log(hapticsState.SamplesAvailable + "a " + hapticsState.SamplesQueued + "q " + expectedSamples + "e "
                //+ "Prediction Accuracy: " + m_numPredictionHits / (float)(m_numPredictionMisses + m_numPredictionHits));

                if ((expectedSamples > 0) && (hapticsState.SamplesQueued == 0))
                {
                    m_numUnderruns++;
                    //Debug.LogError("Samples Underrun (" + m_controller + " #" + m_numUnderruns + ") -"
                    //        + " Expected: " + expectedSamples
                    //        + " Actual: " + hapticsState.SamplesQueued);
                }

                m_prevSamplesQueued     = hapticsState.SamplesQueued;
                m_prevSamplesQueuedTime = Time.realtimeSinceStartup;
            }

            int desiredSamplesCount = OVRHaptics.Config.OptimalBufferSamplesCount;

            if (m_lowLatencyMode)
            {
                float sampleRateMs           = 1000.0f / (float)OVRHaptics.Config.SampleRateHz;
                float elapsedMs              = elapsedTime * 1000.0f;
                int   samplesNeededPerFrame  = (int)Mathf.Ceil(elapsedMs / sampleRateMs);
                int   lowLatencySamplesCount = OVRHaptics.Config.MinimumSafeSamplesQueued + samplesNeededPerFrame;

                if (lowLatencySamplesCount < desiredSamplesCount)
                {
                    desiredSamplesCount = lowLatencySamplesCount;
                }
            }

            if (hapticsState.SamplesQueued > desiredSamplesCount)
            {
                return;
            }

            if (desiredSamplesCount > OVRHaptics.Config.MaximumBufferSamplesCount)
            {
                desiredSamplesCount = OVRHaptics.Config.MaximumBufferSamplesCount;
            }
            if (desiredSamplesCount > hapticsState.SamplesAvailable)
            {
                desiredSamplesCount = hapticsState.SamplesAvailable;
            }

            int acquiredSamplesCount = 0;
            int clipIndex            = 0;

            while (acquiredSamplesCount < desiredSamplesCount && clipIndex < m_pendingClips.Count)
            {
                int numSamplesToCopy       = desiredSamplesCount - acquiredSamplesCount;
                int remainingSamplesInClip = m_pendingClips[clipIndex].Clip.Count - m_pendingClips[clipIndex].ReadCount;
                if (numSamplesToCopy > remainingSamplesInClip)
                {
                    numSamplesToCopy = remainingSamplesInClip;
                }

                if (numSamplesToCopy > 0)
                {
                    int numBytes  = numSamplesToCopy * OVRHaptics.Config.SampleSizeInBytes;
                    int dstOffset = acquiredSamplesCount * OVRHaptics.Config.SampleSizeInBytes;
                    int srcOffset = m_pendingClips[clipIndex].ReadCount * OVRHaptics.Config.SampleSizeInBytes;
                    Marshal.Copy(m_pendingClips[clipIndex].Clip.Samples, srcOffset, m_nativeBuffer.GetPointer(dstOffset), numBytes);

                    m_pendingClips[clipIndex].ReadCount += numSamplesToCopy;
                    acquiredSamplesCount += numSamplesToCopy;
                }

                clipIndex++;
            }

            for (int i = m_pendingClips.Count - 1; i >= 0 && m_pendingClips.Count > 0; i--)
            {
                if (m_pendingClips[i].ReadCount >= m_pendingClips[i].Clip.Count)
                {
                    m_pendingClips.RemoveAt(i);
                }
            }

            int desiredPadding = desiredSamplesCount - (hapticsState.SamplesQueued + acquiredSamplesCount);

            if (desiredPadding < (OVRHaptics.Config.MinimumBufferSamplesCount - acquiredSamplesCount))
            {
                desiredPadding = (OVRHaptics.Config.MinimumBufferSamplesCount - acquiredSamplesCount);
            }
            if (desiredPadding > hapticsState.SamplesAvailable)
            {
                desiredPadding = hapticsState.SamplesAvailable;
            }

            if (desiredPadding > 0)
            {
                int numBytes  = desiredPadding * OVRHaptics.Config.SampleSizeInBytes;
                int dstOffset = acquiredSamplesCount * OVRHaptics.Config.SampleSizeInBytes;
                int srcOffset = 0;
                Marshal.Copy(m_paddingClip.Samples, srcOffset, m_nativeBuffer.GetPointer(dstOffset), numBytes);

                acquiredSamplesCount += desiredPadding;
            }

            if (acquiredSamplesCount > 0)
            {
                OVRPlugin.HapticsBuffer hapticsBuffer;
                hapticsBuffer.Samples      = m_nativeBuffer.GetPointer();
                hapticsBuffer.SamplesCount = acquiredSamplesCount;

                OVRPlugin.SetControllerHaptics(m_controller, hapticsBuffer);

                hapticsState            = OVRPlugin.GetControllerHapticsState(m_controller);
                m_prevSamplesQueued     = hapticsState.SamplesQueued;
                m_prevSamplesQueuedTime = Time.realtimeSinceStartup;
            }
        }