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;
}
Esempio n. 2
0
bool HMDProfile::ParseProperty(const char* prop, const char* sval)
{
    if (OVR_strcmp(prop, "LL") == 0)
    {
        LL = atoi(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "LR") == 0)
    {
        LR = atoi(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "RL") == 0)
    {
        RL = atoi(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "RR") == 0)
    {
        RR = atoi(sval);
        return true;
    }
    
    return Profile::ParseProperty(prop, sval);
}
Esempio n. 3
0
// Removes an existing profile.  Returns true if the profile was found and deleted
// and returns false otherwise.
bool ProfileManager::Delete(const Profile* profile)
{
    Lock::Locker lockScope(&ProfileLock);

    if (OVR_strcmp(profile->Name, "default") == 0)
        return false;  // don't delete a default profile

    if (CacheDevice == Profile_Unknown)
        LoadCache(profile->Type);

    // Look for the existence of this profile
    for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
    {
        if (OVR_strcmp(profile->Name, ProfileCache[i]->Name) == 0)
        {  
            if (OVR_strcmp(profile->Name, DefaultProfile) == 0)
                DefaultProfile.Clear();
            
            ProfileCache.RemoveAt(i);
            Changed = true;
            return true;
        }
    }

    return false;
}
Esempio n. 4
0
const JSON * JsonReader::GetChildByName( const char * childName ) const
{
	assert( IsObject() );

	// Check if the the cached child pointer is valid.
	if ( !Parent->Children.IsNull( Child ) )
	{
		if ( OVR_strcmp( Child->Name, childName ) == 0 )
		{
			const JSON * c = Child;
			Child = c->pNext;	// Cache the next child.
			return c;
		}
	}
	// Itereate over all children.
    for ( const JSON * c = Parent->Children.GetFirst(); !Parent->Children.IsNull( c ); c = c->pNext )
	{
		if ( OVR_strcmp( c->Name, childName ) == 0 )
		{
			Child = c->pNext;	// Cache the next child.
			return c;
		}
	}
	return 0;
}
Esempio n. 5
0
bool RiftDK1Profile::ParseProperty(const char* prop, const char* sval)
{
    if (OVR_strcmp(prop, "EyeCup") == 0)
    {
        switch (sval[0])
        {
            case 'C': EyeCups = EyeCup_C; break;
            case 'B': EyeCups = EyeCup_B; break;
            default:  EyeCups = EyeCup_A; break;
        }
        return true;
    }
    else if (OVR_strcmp(prop, "LL") == 0)
    {
        LL = atoi(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "LR") == 0)
    {
        LR = atoi(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "RL") == 0)
    {
        RL = atoi(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "RR") == 0)
    {
        RR = atoi(sval);
        return true;
    }
    
    return Profile::ParseProperty(prop, sval);
}
Esempio n. 6
0
bool ProfileManager::CreateUser(const char* user, const char* name)
{
    Lock::Locker lockScope(&ProfileLock);

    if (ProfileCache == NULL)
    {   // Load the cache
        LoadCache(true);
        if (ProfileCache == NULL)
            return false;
    }

    JSON* users = ProfileCache->GetItemByName("Users");
    if (users == NULL)
    {   // Generate the User section
        users = JSON::CreateArray();
        ProfileCache->AddItem("Users", users);
//TODO: Insert this before the TaggedData
    }

    // Search for the pre-existence of this user
    JSON* user_item = users->GetFirstItem();
    int index = 0;
    while (user_item)
    {
        JSON* userid = user_item->GetItemByName("User");
        int compare = OVR_strcmp(user, userid->Value);
        if (compare == 0)
        {   // The user already exists so simply update the fields
            JSON* name_item = user_item->GetItemByName("Name");
            if (name_item && OVR_strcmp(name, name_item->Value) != 0)
            {
                name_item->Value = name;
                Changed = true;
            }
            return true;
        }
        else if (compare < 0)
        {   // A new user should be placed before this item
            break;
        }
        
        user_item = users->GetNextItem(user_item);
        index++;
    }

    // Create and fill the user struct
    JSON* new_user = JSON::CreateObject();
    new_user->AddStringItem(OVR_KEY_USER, user);
    new_user->AddStringItem(OVR_KEY_NAME, name);
    // user_item->AddStringItem("Password", password);

    if (user_item == NULL)
        users->AddArrayElement(new_user);
    else
        users->InsertArrayElement(index, new_user);

    Changed = true;
    return true;
}
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;
}
bool IsInStringArray(const char* a[], const char* key)
{
    for (int i = 0; a[i]; ++i)
    {
        if (OVR_strcmp(a[i], key) == 0)
            return true;
    }

    return false;
}
Esempio n. 9
0
// Returns the child item with the given name or NULL if not found
JSON * JSON::GetItemByName( const char * name )
{
    for ( JSON * child = Children.GetFirst(); !Children.IsNull( child ); child = child->pNext )
	{
		if ( OVR_strcmp( child->Name, name ) == 0 )
		{
			return child;
		}
	}
	return 0;
}
Esempio n. 10
0
// Saves a new or existing profile.  Returns true on success or false on an
// invalid or failed save.
bool ProfileManager::Save(const Profile* profile)
{
    Lock::Locker lockScope(&ProfileLock);

    if (OVR_strcmp(profile->Name, "default") == 0)
        return false;  // don't save a default profile

    // TODO: I should also verify that this profile type matches the current cache
    if (CacheDevice == Profile_Unknown)
        LoadCache(profile->Type);

    // Look for the pre-existence of this profile
    bool added = false;
    for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
    {
        int compare = OVR_strcmp(profile->Name, ProfileCache[i]->Name);
              
        if (compare == 0)
        {   
            // TODO: I should do a proper field comparison to avoid unnecessary
            // overwrites and file saves

            // Replace the previous instance with the new profile
            ProfileCache[i] = *profile->Clone();
            added   = true;
            Changed = true;
            break;
        }
    }

    if (!added)
    {
        ProfileCache.PushBack(*profile->Clone());
        if (ProfileCache.GetSize() == 1)
            CacheDevice = profile->Type;

        Changed = true;
    }

    return true;
}
Esempio n. 11
0
bool Profile::ParseProperty(const char* prop, const char* sval)
{
    if (OVR_strcmp(prop, "Name") == 0)
    {
        OVR_strcpy(Name, MaxNameLen, sval);
        return true;
    }
    else if (OVR_strcmp(prop, "CloudUser") == 0)
        {
            OVR_strcpy(CloudUser, MaxNameLen, sval);
            return true;
        }
    else if (OVR_strcmp(prop, "Gender") == 0)
    {
        if (OVR_strcmp(sval, "Male") == 0)
            Gender = Gender_Male;
        else if (OVR_strcmp(sval, "Female") == 0)
            Gender = Gender_Female;
        else
            Gender = Gender_Unspecified;

        return true;
    }
    else if (OVR_strcmp(prop, "PlayerHeight") == 0)
    {
        PlayerHeight = (float)atof(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "IPD") == 0)
    {
        IPD = (float)atof(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "NeckEyeHori") == 0)
    {
        NeckEyeHori = (float)atof(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "NeckEyeVert") == 0)
    {
        NeckEyeVert = (float)atof(sval);
        return true;
    }

    return false;
}
Esempio n. 12
0
bool ProfileManager::HasProfile(ProfileType device, const char* name)
{
    Lock::Locker lockScope(&ProfileLock);

    if (CacheDevice == Profile_Unknown)
        LoadCache(device);

    for (unsigned i = 0; i< ProfileCache.GetSize(); i++)
    {
        if (ProfileCache[i] && OVR_strcmp(ProfileCache[i]->Name, name) == 0)
            return true;
    }
    return false;
}
Esempio n. 13
0
bool RiftDKHDProfile::ParseProperty(const char* prop, const char* sval)
{
    if (OVR_strcmp(prop, "EyeCup") == 0)
    {
        switch (sval[0])
        {
            case 'C': EyeCups = EyeCup_C; break;
            case 'B': EyeCups = EyeCup_B; break;
            default:  EyeCups = EyeCup_A; break;
        }
        return true;
    }
        
    return HMDProfile::ParseProperty(prop, sval);
}
Esempio n. 14
0
bool ProfileManager::RemoveUser(const char* user)
{
    Lock::Locker lockScope(&ProfileLock);

    if (ProfileCache == NULL)
    {   // Load the cache
        LoadCache(false);
        if (ProfileCache == NULL)
            return true;
    }

    JSON* users = ProfileCache->GetItemByName("Users");
    if (users == NULL)
        return true;

    // Remove this user from the User table
    JSON* user_item = users->GetFirstItem();
    while (user_item)
    {
        JSON* userid = user_item->GetItemByName("User");
        if (OVR_strcmp(user, userid->Value) == 0)
        {   // Delete the user entry
            user_item->RemoveNode();
            user_item->Release();
            Changed = true;
            break;
        }
        
        user_item = users->GetNextItem(user_item);
    }

    // Now remove all data entries with this user tag
    JSON* tagged_data = ProfileCache->GetItemByName("TaggedData");
    Array<JSON*> user_items;
    FilterTaggedData(tagged_data, "User", user, user_items);
    for (unsigned int i=0; i<user_items.GetSize(); i++)
    {
        user_items[i]->RemoveNode();
        user_items[i]->Release();
        Changed = true;
    }
 
    return Changed;
}
Esempio n. 15
0
// Returns a profile object for a particular device and user name.  The returned 
// memory should be encapsulated in a Ptr<> object or released after use.  Returns 
// NULL if the profile is not found
Profile* ProfileManager::LoadProfile(ProfileType device, const char* user)
{
    if (user == NULL)
        return NULL;

    Lock::Locker lockScope(&ProfileLock);
    
    if (CacheDevice == Profile_Unknown)
        LoadCache(device);

    for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
    {
        if (OVR_strcmp(user, ProfileCache[i]->Name) == 0)
        {   // Found the requested user profile
            Profile* profile = ProfileCache[i];
            return profile->Clone();
        }
    }

    return NULL;
}
// Returns the child item with the given name or NULL if not found
JSON* JSON::GetItemByName(const char* name)
{
    JSON* child = 0;

    if (!Children.IsEmpty())
    {
        child = Children.GetFirst();

        while (OVR_strcmp(child->Name, name) != 0)
        {   
            if (Children.IsNull(child->pNext))
            {
                child = 0;
                break;
            }
            child = child->pNext;
        }
    }

    return child;
}
Esempio n. 17
0
// Poplulates the local profile cache.  This occurs on the first access of the profile
// data.  All profile operations are performed against the local cache until the
// ProfileManager is released or goes out of scope at which time the cache is serialized
// to disk.
void ProfileManager::LoadCache(ProfileType device)
{
    Lock::Locker lockScope(&ProfileLock);

    ClearCache();

    String path = GetProfilePath(false);

    Ptr<JSON> root = *JSON::Load(path);
    if (!root || root->GetItemCount() < 3)
        return;

    // First read the file type and version to make sure this is a valid file
    JSON* item0 = root->GetFirstItem();
    JSON* item1 = root->GetNextItem(item0);
    JSON* item2 = root->GetNextItem(item1);

    if (OVR_strcmp(item0->Name, "Oculus Profile Version") == 0)
    {   // In the future I may need to check versioning to determine parse method
    }
    else
    {
        return;
    }

    DefaultProfile = item1->Value;

    // Read the number of profiles
    int   profileCount = (int)item2->dValue;
    JSON* profileItem  = item2;

    for (int p=0; p<profileCount; p++)
    {
        profileItem = profileItem->GetNextItem(profileItem);
        if (!profileItem)
            break;
        
        // Read the required Name field
        const char* profileName;
        JSON* item = profileItem->GetFirstItem();
        
        if (item && (OVR_strcmp(item->Name, "Name") == 0))
        {   
            profileName = item->Value;
        }
        else
        {
            return;   // invalid field
        }

        const char*   deviceName  = 0;
        bool          deviceFound = false;
        Ptr<Profile>  profile     = *CreateProfileObject(profileName, device, &deviceName);

        // Read the base profile fields.
        if (profile)
        {
            while (item = profileItem->GetNextItem(item), item)
            {
                if (item->Type != JSON_Object)
                {
                    profile->ParseProperty(item->Name, item->Value);
                }
                else
                {   // Search for the matching device to get device specific fields
                    if (!deviceFound && OVR_strcmp(item->Name, deviceName) == 0)
                    {
                        deviceFound = true;

                        for (JSON* deviceItem = item->GetFirstItem(); deviceItem;
                             deviceItem = item->GetNextItem(deviceItem))
                        {
                            profile->ParseProperty(deviceItem->Name, deviceItem->Value);
                        }
                    }
                }
            }
        }

        // Add the new profile
        if (deviceFound)
            ProfileCache.PushBack(profile);
    }

    CacheDevice = device;
}
Esempio n. 18
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;
}
Esempio n. 19
0
bool HMDProfile::ParseProperty(const char* prop, const char* sval)
{
    if (OVR_strcmp(prop, "LL") == 0)
    {
        LL = atoi(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "LR") == 0)
    {
        LR = atoi(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "RL") == 0)
    {
        RL = atoi(sval);
        return true;
    }
    else if (OVR_strcmp(prop, "RR") == 0)
    {
        RR = atoi(sval);
        return true;
    }

    if (OVR_strcmp(prop, "EyeCup") == 0)
    {
        if      ( 0 == OVR_strcmp ( sval, "A"        ) ) { EyeCups = EyeCup_BlackA; }
        else if ( 0 == OVR_strcmp ( sval, "B"        ) ) { EyeCups = EyeCup_BlackB; }
        else if ( 0 == OVR_strcmp ( sval, "C"        ) ) { EyeCups = EyeCup_BlackC; }
        else if ( 0 == OVR_strcmp ( sval, "Orange A" ) ) { EyeCups = EyeCup_OrangeA; }
        else if ( 0 == OVR_strcmp ( sval, "Red A"    ) ) { EyeCups = EyeCup_RedA; }
        else if ( 0 == OVR_strcmp ( sval, "Blue A"   ) ) { EyeCups = EyeCup_BlueA; }
        else 
        {
            OVR_ASSERT ( !"Unknown lens type in profile" );
            EyeCups = EyeCup_BlackA;
        }
        return true;
    }

    return Profile::ParseProperty(prop, sval);
}
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. 21
0
void ProfileManager::LoadV1Profiles(JSON* v1)
{
    JSON* item0 = v1->GetFirstItem();
    JSON* item1 = v1->GetNextItem(item0);
    JSON* item2 = v1->GetNextItem(item1);

    // Create the new profile database
    Ptr<JSON> root = *JSON::CreateObject();
    root->AddNumberItem("Oculus Profile Version", 2.0);
    root->AddItem("Users", JSON::CreateArray());
    root->AddItem("TaggedData", JSON::CreateArray());
    ProfileCache = root;

    const char* default_dk1_user = item1->Value;
    
    // Read the number of profiles
    int   profileCount = (int)item2->dValue;
    JSON* profileItem  = item2;

    for (int p=0; p<profileCount; p++)
    {
        profileItem = root->GetNextItem(profileItem);
        if (profileItem == NULL)
            break;

        if (profileItem->Name == "Profile")
        {
            // Read the required Name field
            const char* profileName;
            JSON* item = profileItem->GetFirstItem();
        
            if (item && (item->Name == "Name"))
            {   
                profileName = item->Value;
            }
            else
            {
                return;   // invalid field
            }
            
            // Read the user profile fields
            if (CreateUser(profileName, profileName))
            {
                const char* tag_names[2] = {"User", "Product"};
                const char* tags[2];
                tags[0] = profileName;

                Ptr<Profile> user_profile = *CreateProfile();
                user_profile->SetValue(OVR_KEY_NAME, profileName);

                float neckeye[2] = { 0, 0 };

                item = profileItem->GetNextItem(item);
                while (item)
                {
                    if (item->Type != JSON_Object)
                    {
                        if (item->Name == OVR_KEY_PLAYER_HEIGHT)
                        {   // Add an explicit eye height

                        }
                        if (item->Name == "NeckEyeHori")
                            neckeye[0] = (float)item->dValue;
                        else if (item->Name == "NeckEyeVert")
                            neckeye[1] = (float)item->dValue;
                        else 
                            user_profile->SetValue(item);
                    }
                    else
                    {   
                        // Add the user/device tag values
                        const char* device_name = item->Name.ToCStr();
                        Ptr<Profile> device_profile = *CreateProfile();

                        JSON* device_item = item->GetFirstItem();
                        while (device_item)
                        {
                            device_profile->SetValue(device_item);
                            device_item = item->GetNextItem(device_item);
                        }

                        tags[1] = device_name;
                        SetTaggedProfile(tag_names, tags, 2, device_profile);
                    }

                    item = profileItem->GetNextItem(item);
                }

                // Add an explicit eye-height field
                float player_height = user_profile->GetFloatValue(OVR_KEY_PLAYER_HEIGHT,
                                                                  OVR_DEFAULT_PLAYER_HEIGHT);
                if (player_height > 0)
                {
                    char gender[16];
                    user_profile->GetValue(OVR_KEY_GENDER, gender, 16);
        
                    const float EYE_TO_HEADTOP_RATIO =   0.44538f;
                    const float MALE_AVG_HEAD_HEIGHT =   0.232f;
                    const float FEMALE_AVG_HEAD_HEIGHT = 0.218f;
     
                    // compute distance from top of skull to the eye
                    float head_height;
                    if (OVR_strcmp(gender, "Female") == 0)
                        head_height = FEMALE_AVG_HEAD_HEIGHT;
                    else
                        head_height = MALE_AVG_HEAD_HEIGHT;

                    float skull = EYE_TO_HEADTOP_RATIO * head_height;
                    float eye_height = player_height - skull;

                    user_profile->SetFloatValue(OVR_KEY_EYE_HEIGHT, eye_height);
                }

                // Convert NeckEye values to an array
                if (neckeye[0] > 0 && neckeye[1] > 0)
                    user_profile->SetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, neckeye, 2);

                // Add the user tag values
                SetTaggedProfile(tag_names, tags, 1, user_profile);
            }
        }
    }

    // since V1 profiles were only for DK1, the assign the user to all DK1's
    const char* tag_names[1] = { "Product" };
    const char* tags[1] = { "RiftDK1" };
    Ptr<Profile> product_profile = *CreateProfile();
    product_profile->SetValue("DefaultUser", default_dk1_user);
    SetTaggedProfile(tag_names, tags, 1, product_profile);
}
Esempio n. 22
0
// Serializes the profiles to disk.
void ProfileManager::SaveCache()
{
    String path = GetProfilePath(true);
 
    Lock::Locker lockScope(&ProfileLock);

    Ptr<JSON> oldroot = *JSON::Load(path);
    if (oldroot)
    {
        if (oldroot->GetItemCount() >= 3)
        {
            JSON* item0 = oldroot->GetFirstItem();
            JSON* item1 = oldroot->GetNextItem(item0);
            oldroot->GetNextItem(item1);

            if (item0->Name == "Oculus Profile Version")
            {
                int major = atoi(item0->Value.ToCStr());
                if (major > MAX_PROFILE_MAJOR_VERSION)
                    oldroot.Clear();   // don't use the file on unsupported major version number
            }
            else
            {
                oldroot.Clear(); 
            }
        }
        else
        {
            oldroot.Clear();
        }
    }
    
    // Create a new json root
    Ptr<JSON> root = *JSON::CreateObject();
    root->AddNumberItem("Oculus Profile Version", PROFILE_VERSION);
    root->AddStringItem("CurrentProfile", DefaultProfile);
    root->AddNumberItem("ProfileCount", (double) ProfileCache.GetSize());

    // Generate a JSON subtree for each profile
    for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
    {
        Profile* profile = ProfileCache[i];

        // Write the base profile information
        JSON* json_profile = JSON::CreateObject();
        json_profile->Name = "Profile";
        json_profile->AddStringItem("Name", profile->Name);
        const char* gender;
        switch (profile->GetGender())
        {
            case Profile::Gender_Male:   gender = "Male"; break;
            case Profile::Gender_Female: gender = "Female"; break;
            default: gender = "Unspecified";
        }
        json_profile->AddStringItem("Gender", gender);
        json_profile->AddNumberItem("PlayerHeight", profile->PlayerHeight);
        json_profile->AddNumberItem("IPD", profile->IPD);

        const char* device_name = NULL;
        // Create a device-specific subtree for the cached device
        if (profile->Type == Profile_RiftDK1)
        {
            device_name = "RiftDK1";
            
            RiftDK1Profile* rift = (RiftDK1Profile*)profile;
            JSON* json_rift = JSON::CreateObject();
            json_profile->AddItem(device_name, json_rift);

            const char* eyecup = "A";
            switch (rift->EyeCups)
            {
                case EyeCup_A: eyecup = "A"; break;
                case EyeCup_B: eyecup = "B"; break;
                case EyeCup_C: eyecup = "C"; break;
            }
            json_rift->AddStringItem("EyeCup", eyecup);
            json_rift->AddNumberItem("LL", rift->LL);
            json_rift->AddNumberItem("LR", rift->LR);
            json_rift->AddNumberItem("RL", rift->RL);
            json_rift->AddNumberItem("RR", rift->RR);
        }
        else if (profile->Type == Profile_RiftDKHD)
        {
            device_name = "RiftDKHD";
            
            RiftDKHDProfile* rift = (RiftDKHDProfile*)profile;
            JSON* json_rift = JSON::CreateObject();
            json_profile->AddItem(device_name, json_rift);

            const char* eyecup = "A";
            switch (rift->EyeCups)
            {
                case EyeCup_A: eyecup = "A"; break;
                case EyeCup_B: eyecup = "B"; break;
                case EyeCup_C: eyecup = "C"; break;
            }
            json_rift->AddStringItem("EyeCup", eyecup);
            //json_rift->AddNumberItem("LL", rift->LL);
            //json_rift->AddNumberItem("LR", rift->LR);
            //json_rift->AddNumberItem("RL", rift->RL);
            //json_rift->AddNumberItem("RR", rift->RR);
        }

        // There may be multiple devices stored per user, but only a single
        // device is represented by this root.  We don't want to overwrite
        // the other devices so we need to examine the older root 
        // and merge previous devices into new json root
        if (oldroot)
        {
            JSON* old_profile = oldroot->GetFirstItem();
            while (old_profile)
            {
                if (old_profile->Name == "Profile")
                {
                    JSON* profile_name = old_profile->GetItemByName("Name");
                    if (profile_name && OVR_strcmp(profile->Name, profile_name->Value) == 0)
                    {   // Now that we found the user in the older root, add all the 
                        // object children to the new root - except for the one for the
                        // current device
                        JSON* old_item = old_profile->GetFirstItem();
                        while (old_item)
                        {
                            if (old_item->Type == JSON_Object 
                                && (device_name == NULL || OVR_strcmp(old_item->Name, device_name) != 0))
                            {
                                JSON* old_device = old_item;
                                old_item = old_profile->GetNextItem(old_item);

                                // remove the node from the older root to avoid multiple reference
                                old_device->RemoveNode();
                                // add the node pointer to the new root
                                json_profile->AddItem(old_device->Name, old_device);
                            }
                            else
                            {
                                old_item = old_profile->GetNextItem(old_item);
                            }
                        }

                        break;
                    }
                }

                old_profile = oldroot->GetNextItem(old_profile);
            }
        }

        // Add the completed user profile to the new root
        root->AddItem("Profile", json_profile);
    }

    // Save the profile to disk
    root->Save(path);
}
Esempio n. 23
0
// Poplulates the local profile cache.  This occurs on the first access of the profile
// data.  All profile operations are performed against the local cache until the
// ProfileManager is released or goes out of scope at which time the cache is serialized
// to disk.
void ProfileManager::LoadCache(ProfileType device)
{
    Lock::Locker lockScope(&ProfileLock);

    ClearCache();

    String path = GetProfilePath(false);

    Ptr<JSON> root = *JSON::Load(path);
    if (!root || root->GetItemCount() < 3)
        return;

    // First read the file type and version to make sure this is a valid file
    JSON* item0 = root->GetFirstItem();
    JSON* item1 = root->GetNextItem(item0);
    JSON* item2 = root->GetNextItem(item1);

    if (item0->Name == "Oculus Profile Version")
    {
        int major = atoi(item0->Value.ToCStr());
        if (major > MAX_PROFILE_MAJOR_VERSION)
            return;   // don't parse the file on unsupported major version number
    }
    else
    {
        return;
    }

    DefaultProfile = item1->Value;

    // Read the number of profiles
    int   profileCount = (int)item2->dValue;
    JSON* profileItem  = item2;

    for (int p=0; p<profileCount; p++)
    {
        profileItem = root->GetNextItem(profileItem);
        if (profileItem == NULL)
            break;

        if (profileItem->Name == "Profile")
        {
            // Read the required Name field
            const char* profileName;
            JSON* item = profileItem->GetFirstItem();
        
            if (item && (item->Name == "Name"))
            {   
                profileName = item->Value;
            }
            else
            {
                return;   // invalid field
            }

            const char*   deviceName  = 0;
            bool          deviceFound = false;
            Ptr<Profile>  profile     = *CreateProfileObject(profileName, device, &deviceName);

            // Read the base profile fields.
            if (profile)
            {
                while (item = profileItem->GetNextItem(item), item)
                {
                    if (item->Type != JSON_Object)
                    {
                        profile->ParseProperty(item->Name, item->Value);
                    }
                    else
                    {   // Search for the matching device to get device specific fields
                        if (!deviceFound && deviceName && OVR_strcmp(item->Name, deviceName) == 0)
                        {
                            deviceFound = true;

                            for (JSON* deviceItem = item->GetFirstItem(); deviceItem;
                                 deviceItem = item->GetNextItem(deviceItem))
                            {
                                profile->ParseProperty(deviceItem->Name, deviceItem->Value);
                            }
                        }
                    }
                }
            }

            // Add the new profile
            ProfileCache.PushBack(profile);
        }
    }

    CacheDevice = device;
}
//-----------------------------------------------------------------------------
void HIDDeviceManager::OnEvent(int i, int fd)
{
    OVR_UNUSED(i);
    OVR_UNUSED(fd);

    // There is a device status change
    udev_device* hid = udev_monitor_receive_device(HIDMonitor);
    if (hid)
    {
        const char* dev_path = udev_device_get_devnode(hid);
        const char* action = udev_device_get_action(hid);

        HIDDeviceDesc device_info;
        device_info.Path = dev_path;

        MessageType notify_type;
        if (OVR_strcmp(action, "add") == 0)
        {
            notify_type = Message_DeviceAdded;

            // Retrieve the device info.  This can only be done on a connected
            // device and is invalid for a disconnected device

            // Get the USB device
            hid = udev_device_get_parent_with_subsystem_devtype(hid, "usb", "usb_device");
            if (!hid)
            {
                return;
            }

            const char* path = udev_device_get_syspath(hid);

            GetDescriptorFromPath(path, &device_info);
        }
        else if (OVR_strcmp(action, "remove") == 0)
        {
            notify_type = Message_DeviceRemoved;
        }
        else
        {
            return;
        }

        bool error = false;
        bool deviceFound = false;
        for (UPInt i = 0; i < NotificationDevices.GetSize(); i++)
        {
            if (NotificationDevices[i] &&
                NotificationDevices[i]->OnDeviceNotification(notify_type, &device_info, &error))
            {
                // The notification was for an existing device
                deviceFound = true;
                break;
            }
        }

        if (notify_type == Message_DeviceAdded && !deviceFound)
        {
            DevManager->DetectHIDDevice(device_info);
        }

        udev_device_unref(hid);
    }
}