bool HMDState::setFloatArray(const char* propertyName, float values[], unsigned arraySize)
{
    if (!arraySize)
    {
        return false;
    }
    
    if (OVR_strcmp(propertyName, "DistortionClearColor") == 0)
    {
        CopyFloatArrayWithLimit(RenderState.ClearColor, 4, values, arraySize);
        return true;
    }

	if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetNumberValues, propertyName))
	{
		double* da = new double[arraySize];
		for (int i = 0; i < (int)arraySize; ++i)
		{
			da[i] = values[i];
		}

		bool result = NetClient::GetInstance()->SetNumberValues(GetNetId(), propertyName, da, arraySize);

		delete[] da;

		return result;
	}

	return false;
}
float HMDState::getFloatValue(const char* propertyName, float defaultVal)
{
    if (OVR_strcmp(propertyName, "LensSeparation") == 0)
    {
        return OurHMDInfo.LensSeparationInMeters;
    }
    else if (OVR_strcmp(propertyName, "VsyncToNextVsync") == 0) 
    {
        return OurHMDInfo.Shutter.VsyncToNextVsync;
    }
    else if (OVR_strcmp(propertyName, "PixelPersistence") == 0) 
    {
        return OurHMDInfo.Shutter.PixelPersistence;
    }
    else if (NetSessionCommon::IsServiceProperty(NetSessionCommon::EGetNumberValue, propertyName))
    {
       return (float)NetClient::GetInstance()->GetNumberValue(GetNetId(), propertyName, defaultVal);
    }
    else if (pProfile)
    {
        return pProfile->GetFloatValue(propertyName, defaultVal);
    }

    return defaultVal;
}
bool HMDState::setString(const char* propertyName, const char* value)
{
	if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetStringValue, propertyName))
	{
		return NetClient::GetInstance()->SetStringValue(GetNetId(), propertyName, value);
	}

	return false;
}
Esempio n. 4
0
void HMDState::UpdateRenderProfile(Profile* profile)
{
    // Apply the given profile to generate a render context
    RenderState.OurProfileRenderInfo = GenerateProfileRenderInfoFromProfile(RenderState.OurHMDInfo, profile);
    RenderState.RenderInfo = GenerateHmdRenderInfoFromHmdInfo(RenderState.OurHMDInfo, RenderState.OurProfileRenderInfo);

    RenderState.Distortion[0] = CalculateDistortionRenderDesc(StereoEye_Left, RenderState.RenderInfo, 0);
    RenderState.Distortion[1] = CalculateDistortionRenderDesc(StereoEye_Right, RenderState.RenderInfo, 0);

    if (pClient)
    {
        // Center pupil depth
        float centerPupilDepth = GetCenterPupilDepthFromRenderInfo(&RenderState.RenderInfo);
        pClient->SetNumberValue(GetNetId(), "CenterPupilDepth", centerPupilDepth);

        // Neck model
        Vector3f neckModel = GetNeckModelFromProfile(profile);
        double neckModelArray[3] = {
            neckModel.x,
            neckModel.y,
            neckModel.z
        };
        pClient->SetNumberValues(GetNetId(), "NeckModelVector3f", neckModelArray, 3);

        // Camera position

        // OVR_KEY_CAMERA_POSITION is actually the *inverse* of a camera position.
        Posed centeredFromWorld;

        double values[7];
        if (profile->GetDoubleValues(OVR_KEY_CAMERA_POSITION, values, 7) == 7)
        {
            centeredFromWorld = Posed::FromArray(values);
        }
        else
        {
            centeredFromWorld = TheTrackingStateReader.GetDefaultCenteredFromWorld();
        }

        // ComputeCenteredFromWorld wants a worldFromCpf pose, so invert it.
        // FIXME: The stored centeredFromWorld doesn't have a neck model offset applied, but probably should.
        TheTrackingStateReader.ComputeCenteredFromWorld(centeredFromWorld.Inverted(), Vector3d(0, 0, 0));
    }
}
int HMDState::getIntValue(const char* propertyName, int defaultVal)
{
    if (NetSessionCommon::IsServiceProperty(NetSessionCommon::EGetIntValue, propertyName))
    {
        return NetClient::GetInstance()->GetIntValue(GetNetId(), propertyName, defaultVal);
    }
    else if (pProfile)
    {
        return pProfile->GetIntValue(propertyName, defaultVal);
    }
    return defaultVal;
}
void HMDState::UpdateRenderProfile(Profile* profile)
{
    // Apply the given profile to generate a render context
    RenderState.RenderInfo = GenerateHmdRenderInfoFromHmdInfo(RenderState.OurHMDInfo, profile);
    RenderState.Distortion[0] = CalculateDistortionRenderDesc(StereoEye_Left, RenderState.RenderInfo, 0);
    RenderState.Distortion[1] = CalculateDistortionRenderDesc(StereoEye_Right, RenderState.RenderInfo, 0);

    if (pClient)
    {
        // Center pupil depth
        float centerPupilDepth = GetCenterPupilDepthFromRenderInfo(&RenderState.RenderInfo);
        pClient->SetNumberValue(GetNetId(), "CenterPupilDepth", centerPupilDepth);

        // Neck model
        Vector3f neckModel = GetNeckModelFromProfile(profile);
        double neckModelArray[3] = {
            neckModel.x,
            neckModel.y,
            neckModel.z
        };
        pClient->SetNumberValues(GetNetId(), "NeckModelVector3f", neckModelArray, 3);

        double camerastate[7];
        if (profile->GetDoubleValues(OVR_KEY_CAMERA_POSITION, camerastate, 7) == 0)
        {
            //there is no value, so we load the default
            for (int i = 0; i < 7; i++) camerastate[i] = 0;
            camerastate[3] = 1;//no offset. by default, give the quaternion w component value 1
        }
        else

        TheSensorStateReader.setCenteredFromWorld(OVR::Posed::FromArray(camerastate));
    }


}
const char* HMDState::getString(const char* propertyName, const char* defaultVal)
{
    if (NetSessionCommon::IsServiceProperty(NetSessionCommon::EGetStringValue, propertyName))
    {
        return NetClient::GetInstance()->GetStringValue(GetNetId(), propertyName, defaultVal);
    }

	if (pProfile)
	{
		LastGetStringValue[0] = 0;
		if (pProfile->GetValue(propertyName, LastGetStringValue, sizeof(LastGetStringValue)))
		{
			return LastGetStringValue;
		}
	}

	return defaultVal;
}
unsigned HMDState::getFloatArray(const char* propertyName, float values[], unsigned arraySize)
{
	if (arraySize)
	{
		if (OVR_strcmp(propertyName, "ScreenSize") == 0)
		{
			float data[2] = { OurHMDInfo.ScreenSizeInMeters.w, OurHMDInfo.ScreenSizeInMeters.h };

            return CopyFloatArrayWithLimit(values, arraySize, data, 2);
		}
        else if (OVR_strcmp(propertyName, "DistortionClearColor") == 0)
        {
            return CopyFloatArrayWithLimit(values, arraySize, RenderState.ClearColor, 4);
        }
        else if (OVR_strcmp(propertyName, "DK2Latency") == 0)
        {
            if (OurHMDInfo.HmdType != HmdType_DK2)
            {
                return 0;
            }

            union {
                struct X {
                    float latencyRender, latencyTimewarp, latencyPostPresent;
                } x;
                float data[3];
            } m;

            static_assert(sizeof(m.x)==sizeof(m.data), "sizeof(struct X) failure");

            TimeManager.GetLatencyTimings(m.x.latencyRender, m.x.latencyTimewarp, m.x.latencyPostPresent);

            return CopyFloatArrayWithLimit(values, arraySize, m.data, 3);
        }
        else if (NetSessionCommon::IsServiceProperty(NetSessionCommon::EGetNumberValues, propertyName))
        {
            // Convert floats to doubles
            double* da = new double[arraySize];
            for (int i = 0; i < (int)arraySize; ++i)
            {
                da[i] = values[i];
            }

            int count = NetClient::GetInstance()->GetNumberValues(GetNetId(), propertyName, da, (int)arraySize);

            for (int i = 0; i < count; ++i)
            {
                values[i] = (float)da[i];
            }

            delete[] da;

            return count;
        }
		else if (pProfile)
		{        
			// TBD: Not quite right. Should update profile interface, so that
			//      we can return 0 in all conditions if property doesn't exist.
		
            return pProfile->GetFloatValues(propertyName, values, arraySize);
		}
	}

	return 0;
}
Esempio n. 9
0
bool HMDState::ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2],
                                  const ovrFovPort eyeFovIn[2],
                                  const ovrRenderAPIConfig* apiConfig,                                  
                                  unsigned distortionCaps)
{
    ThreadChecker::Scope checkScope(&RenderAPIThreadChecker, "ovrHmd_ConfigureRendering");

    // null -> shut down.
    if (!apiConfig)
    {
#if !defined(HEADLESS_APP)
        if (pHSWDisplay)
        {
            pHSWDisplay->Shutdown();
            pHSWDisplay.Clear();
        }
#endif /* !defined(HEADLESS_APP) */

        if (pRenderer)
            pRenderer.Clear();        
        RenderingConfigured = false; 
        return true;
    }

    if (pRenderer &&
        (apiConfig->Header.API != pRenderer->GetRenderAPI()))
    {
        // Shutdown old renderer.
#if !defined(HEADLESS_APP)
        if (pHSWDisplay)
        {
            pHSWDisplay->Shutdown();
            pHSWDisplay.Clear();
        }
#endif /* !defined(HEADLESS_APP) */

        if (pRenderer)
            pRenderer.Clear();
    }

    distortionCaps = distortionCaps & pHmdDesc->DistortionCaps;

    // Step 1: do basic setup configuration
    RenderState.EnabledHmdCaps = EnabledHmdCaps;     // This is a copy... Any cleaner way?
    RenderState.DistortionCaps = distortionCaps;
    RenderState.EyeRenderDesc[0] = RenderState.CalcRenderDesc(ovrEye_Left,  eyeFovIn[0]);
    RenderState.EyeRenderDesc[1] = RenderState.CalcRenderDesc(ovrEye_Right, eyeFovIn[1]);
    eyeRenderDescOut[0] = RenderState.EyeRenderDesc[0];
    eyeRenderDescOut[1] = RenderState.EyeRenderDesc[1];

    // Set RenderingConfigured early to avoid ASSERTs in renderer initialization.
    RenderingConfigured = true;

    if (!pRenderer)
    {
#if !defined(HEADLESS_APP)
        pRenderer = *DistortionRenderer::APICreateRegistry
                        [apiConfig->Header.API]();
#endif /* !defined(HEADLESS_APP) */
    }

    if (!pRenderer 
#if !defined(HEADLESS_APP)
        || !pRenderer->Initialize(apiConfig, &TheTrackingStateReader,
                                  &TimewarpTimer, &RenderState)
#endif /* !defined(HEADLESS_APP) */
       )
    {
        RenderingConfigured = false;
        return false;
    }

#if !defined(HEADLESS_APP)
    // Setup the Health and Safety Warning display system.
    if(pHSWDisplay && (pHSWDisplay->GetRenderAPIType() != apiConfig->Header.API)) // If we need to reconstruct the HSWDisplay for a different graphics API type, delete the existing display.
    {
        pHSWDisplay->Shutdown();
        pHSWDisplay.Clear();
    }

    if(!pHSWDisplay) // Use * below because that for of operator= causes it to inherit the refcount the factory gave the object.
    {
        pHSWDisplay = *OVR::CAPI::HSWDisplay::Factory(apiConfig->Header.API, pHmdDesc, RenderState);
    }

    if (pHSWDisplay)
    {
        pHSWDisplay->Initialize(apiConfig); // This is potentially re-initializing it with a new config.
    }

#ifdef OVR_OS_WIN32
    if (!pWindow)
    {
        // We can automatically populate the window to attach to by
        // pulling that information off the swap chain that the
        // application provides.  If the application later calls the
        // ovrHmd_AttachToWindow() function these will get harmlessly
        // overwritten.  The check above verifies that the window is
        // not set yet, and it insures that this default doesn't
        // overwrite the application setting.

        if (apiConfig->Header.API == ovrRenderAPI_D3D11)
        {
            ovrD3D11Config* d3d11Config = (ovrD3D11Config*)apiConfig;
            if (d3d11Config->D3D11.pSwapChain)
            {
                DXGI_SWAP_CHAIN_DESC desc = {};
                HRESULT hr = d3d11Config->D3D11.pSwapChain->GetDesc(&desc);
                if (SUCCEEDED(hr))
                {
                    pWindow = (void*)desc.OutputWindow;
                }
            }
        }
        else if (apiConfig->Header.API == ovrRenderAPI_OpenGL)
        {
            ovrGLConfig* glConfig = (ovrGLConfig*)apiConfig;
            pWindow = (void*)glConfig->OGL.Window;
        }
OVR_DISABLE_MSVC_WARNING(4996) // Disable deprecation warning
        else if (apiConfig->Header.API == ovrRenderAPI_D3D9)
        {
            ovrD3D9Config* dx9Config = (ovrD3D9Config*)apiConfig;
            if (dx9Config->D3D9.pDevice)
            {
                D3DDEVICE_CREATION_PARAMETERS  params = {};
                HRESULT hr = dx9Config->D3D9.pDevice->GetCreationParameters(&params);
                if (SUCCEEDED(hr))
                {
                    pWindow = (void*)params.hFocusWindow;
                }
            }
        }
OVR_RESTORE_MSVC_WARNING()

        // If a window handle was implied by render configuration,
        if (pWindow)
        {
            // This is the same logic as ovrHmd_AttachToWindow() on Windows:
            if (pClient)
                pClient->Hmd_AttachToWindow(GetNetId(), pWindow);
            Win32::DisplayShim::GetInstance().hWindow = (HWND)pWindow;
            // On the server side it is updating the association of connection
            // to window handle.  This is perfectly safe to update later to
            // a new window handle (verified).  Also verified that if this
            // handle is garbage that it doesn't crash anything.
        }
    }
#endif
#endif /* !defined(HEADLESS_APP) */

    return true;
}
Esempio n. 10
0
unsigned HMDState::getFloatArray(const char* propertyName, float values[], unsigned arraySize)
{
    if (arraySize)
    {
        if (OVR_strcmp(propertyName, "ScreenSize") == 0)
        {
            float data[2] = { OurHMDInfo.ScreenSizeInMeters.w, OurHMDInfo.ScreenSizeInMeters.h };

            return CopyFloatArrayWithLimit(values, arraySize, data, 2);
        }
        else if (OVR_strcmp(propertyName, "DistortionClearColor") == 0)
        {
            return CopyFloatArrayWithLimit(values, arraySize, RenderState.ClearColor, 4);
        }
        else if (OVR_strcmp(propertyName, "DK2Latency") == 0)
        {
            if (OurHMDInfo.HmdType < HmdType_DK2)
            {
                return 0;
            }

            OutputLatencyTimings timings;
            ScreenLatencyTracker.GetLatencyTimings(timings);

            if (arraySize > 0)
            {
                switch (arraySize)
                {
                default: values[4] = (float)timings.ErrorTimewarp;      // Fall-thru
                case 4:  values[3] = (float)timings.ErrorRender;        // Fall-thru
                case 3:  values[2] = (float)timings.LatencyPostPresent; // Fall-thru
                case 2:  values[1] = (float)timings.LatencyTimewarp;    // Fall-thru
                case 1:  values[0] = (float)timings.LatencyRender;
                }
            }

            return arraySize > 5 ? 5 : arraySize;
        }
        else if (OVR_strcmp(propertyName, "NeckModelVector3f") == 0)
        {
            // Query the service to grab the HNM.
            double hnm[3] = {};
            int count = NetClient::GetInstance()->GetNumberValues(GetNetId(), propertyName, hnm, (int)arraySize);

            // If the service is unavailable or returns zero data,
            if (count < 3 ||
                (hnm[0] == 0.0 && hnm[1] == 0.0 && hnm[2] == 0.0))
            {
                // These are the default values used if the server does not return any data, due to not
                // being reachable or other errors.
                OVR_ASSERT(pProfile.GetPtr());
                if (pProfile.GetPtr())
                {
                    Vector3f neckModel = GetNeckModelFromProfile(pProfile);
                    hnm[0] = neckModel.x;
                    hnm[1] = neckModel.y;
                    hnm[2] = neckModel.z;
                }
            }

            for (unsigned i = 0; i < 3 && i < arraySize; ++i)
            {
                values[i] = (float)hnm[i];
            }

            return arraySize > 3 ? 3 : arraySize;
        }
        else if (NetSessionCommon::IsServiceProperty(NetSessionCommon::EGetNumberValues, propertyName))
        {
            // Convert floats to doubles
            double* da = new double[arraySize];
            for (int i = 0; i < (int)arraySize; ++i)
            {
                da[i] = values[i];
            }

            int count = NetClient::GetInstance()->GetNumberValues(GetNetId(), propertyName, da, (int)arraySize);

            for (int i = 0; i < count; ++i)
            {
                values[i] = (float)da[i];
            }

            delete[] da;

            return count;
        }
        else if (pProfile)
        {        
            // TBD: Not quite right. Should update profile interface, so that
            //      we can return 0 in all conditions if property doesn't exist.
        
            return pProfile->GetFloatValues(propertyName, values, arraySize);
        }
    }

    return 0;
}