mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 03:03:35 +02:00
Merge pull request #438 from Geenz/19308
#19308 - Store menu settings in the avatar data file
This commit is contained in:
commit
bc5af6e399
3 changed files with 343 additions and 30 deletions
|
@ -254,8 +254,6 @@ void Application::initializeGL() {
|
||||||
printLog("Network receive thread created.\n");
|
printLog("Network receive thread created.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
_myAvatar.readAvatarDataFromFile();
|
|
||||||
|
|
||||||
// call terminate before exiting
|
// call terminate before exiting
|
||||||
connect(this, SIGNAL(aboutToQuit()), SLOT(terminate()));
|
connect(this, SIGNAL(aboutToQuit()), SLOT(terminate()));
|
||||||
|
|
||||||
|
@ -269,6 +267,8 @@ void Application::initializeGL() {
|
||||||
connect(idleTimer, SIGNAL(timeout()), SLOT(idle()));
|
connect(idleTimer, SIGNAL(timeout()), SLOT(idle()));
|
||||||
idleTimer->start(0);
|
idleTimer->start(0);
|
||||||
|
|
||||||
|
readSettings();
|
||||||
|
|
||||||
if (_justStarted) {
|
if (_justStarted) {
|
||||||
float startupTime = (usecTimestampNow() - usecTimestamp(&_applicationStartupTime))/1000000.0;
|
float startupTime = (usecTimestampNow() - usecTimestamp(&_applicationStartupTime))/1000000.0;
|
||||||
_justStarted = false;
|
_justStarted = false;
|
||||||
|
@ -723,7 +723,178 @@ void Application::wheelEvent(QWheelEvent* event) {
|
||||||
decreaseVoxelSize();
|
decreaseVoxelSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char AVATAR_DATA_FILENAME[] = "avatar.ifd";
|
||||||
|
|
||||||
|
void Application::readSettingsFile() {
|
||||||
|
FILE* settingsFile = fopen(AVATAR_DATA_FILENAME, "rt");
|
||||||
|
|
||||||
|
if (settingsFile) {
|
||||||
|
char line[LINE_MAX];
|
||||||
|
|
||||||
|
while (fgets(line, LINE_MAX, settingsFile) != NULL)
|
||||||
|
{
|
||||||
|
if (strcmp(line, " \n") > 0) {
|
||||||
|
char* token = NULL;
|
||||||
|
char* settingLine = NULL;
|
||||||
|
char* toFree = NULL;
|
||||||
|
|
||||||
|
settingLine = strdup(line);
|
||||||
|
|
||||||
|
if (settingLine != NULL) {
|
||||||
|
toFree = settingLine;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
char key[128];
|
||||||
|
char value[128];
|
||||||
|
|
||||||
|
|
||||||
|
while ((token = strsep(&settingLine, "=")) != NULL)
|
||||||
|
{
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
strcpy(key, token);
|
||||||
|
_settingsTable[key] = "";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
strcpy(value, token);
|
||||||
|
_settingsTable[key] = token;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(toFree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(settingsFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::saveSettingsFile() {
|
||||||
|
FILE* settingsFile = fopen(AVATAR_DATA_FILENAME, "wt");
|
||||||
|
|
||||||
|
if (settingsFile) {
|
||||||
|
for (std::map<std::string, std::string>::iterator i = _settingsTable.begin(); i != _settingsTable.end(); i++)
|
||||||
|
{
|
||||||
|
fprintf(settingsFile, "\n%s=%s", i->first.data(), i->second.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(settingsFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Application::getSetting(const char* setting, bool& value, const bool defaultSetting) const {
|
||||||
|
std::map<std::string, std::string>::const_iterator iter = _settingsTable.find(setting);
|
||||||
|
|
||||||
|
if (iter != _settingsTable.end()) {
|
||||||
|
int readBool;
|
||||||
|
|
||||||
|
int res = sscanf(iter->second.data(), "%d", &readBool);
|
||||||
|
|
||||||
|
const char EXPECTED_ITEMS = 1;
|
||||||
|
|
||||||
|
if (res == EXPECTED_ITEMS) {
|
||||||
|
if (readBool == 1) {
|
||||||
|
value = true;
|
||||||
|
} else if (readBool == 0) {
|
||||||
|
value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = defaultSetting;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Application::getSetting(const char* setting, float& value, const float defaultSetting) const {
|
||||||
|
std::map<std::string, std::string>::const_iterator iter = _settingsTable.find(setting);
|
||||||
|
|
||||||
|
if (iter != _settingsTable.end()) {
|
||||||
|
float readFloat;
|
||||||
|
|
||||||
|
int res = sscanf(iter->second.data(), "%f", &readFloat);
|
||||||
|
|
||||||
|
const char EXPECTED_ITEMS = 1;
|
||||||
|
|
||||||
|
if (res == EXPECTED_ITEMS) {
|
||||||
|
if (!isnan(readFloat)) {
|
||||||
|
value = readFloat;
|
||||||
|
} else {
|
||||||
|
value = defaultSetting;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = defaultSetting;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = defaultSetting;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Application::getSetting(const char* setting, glm::vec3& value, const glm::vec3& defaultSetting) const {
|
||||||
|
std::map<std::string, std::string>::const_iterator iter = _settingsTable.find(setting);
|
||||||
|
|
||||||
|
if (iter != _settingsTable.end()) {
|
||||||
|
glm::vec3 readVec;
|
||||||
|
|
||||||
|
int res = sscanf(iter->second.data(), "%f,%f,%f", &readVec.x, &readVec.y, &readVec.z);
|
||||||
|
|
||||||
|
const char EXPECTED_ITEMS = 3;
|
||||||
|
|
||||||
|
if (res == EXPECTED_ITEMS) {
|
||||||
|
if (!isnan(readVec.x) && !isnan(readVec.y) && !isnan(readVec.z)) {
|
||||||
|
value = readVec;
|
||||||
|
} else {
|
||||||
|
value = defaultSetting;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = defaultSetting;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = defaultSetting;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const short MAX_SETTINGS_LENGTH = 128;
|
||||||
|
|
||||||
|
void Application::setSetting(const char* setting, const bool value) {
|
||||||
|
char settingValues[MAX_SETTINGS_LENGTH];
|
||||||
|
sprintf(settingValues, "%d", value);
|
||||||
|
_settingsTable[setting] = settingValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::setSetting(const char* setting, const float value) {
|
||||||
|
char settingValues[MAX_SETTINGS_LENGTH];
|
||||||
|
sprintf(settingValues, "%f", value);
|
||||||
|
_settingsTable[setting] = settingValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::setSetting(const char* setting, const glm::vec3& value) {
|
||||||
|
char settingValues[MAX_SETTINGS_LENGTH];
|
||||||
|
sprintf(settingValues, "%f,%f,%f", value.x, value.y, value.z);
|
||||||
|
_settingsTable[setting] = settingValues;
|
||||||
|
}
|
||||||
|
|
||||||
// Every second, check the frame rates and other stuff
|
// Every second, check the frame rates and other stuff
|
||||||
void Application::timer() {
|
void Application::timer() {
|
||||||
gettimeofday(&_timerEnd, NULL);
|
gettimeofday(&_timerEnd, NULL);
|
||||||
|
@ -945,7 +1116,7 @@ void Application::terminate() {
|
||||||
// Close serial port
|
// Close serial port
|
||||||
// close(serial_fd);
|
// close(serial_fd);
|
||||||
|
|
||||||
_myAvatar.writeAvatarDataToFile();
|
saveSettings();
|
||||||
|
|
||||||
if (_enableNetworkThread) {
|
if (_enableNetworkThread) {
|
||||||
_stopNetworkReceiveThread = true;
|
_stopNetworkReceiveThread = true;
|
||||||
|
@ -2186,3 +2357,95 @@ void* Application::networkReceive(void* args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::saveSettings()
|
||||||
|
{
|
||||||
|
// Handle any persistent settings saving here when we get a call to terminate.
|
||||||
|
// This should probably be moved to a map stored in memory at some point to cache settings.
|
||||||
|
_myAvatar.writeAvatarDataToFile();
|
||||||
|
|
||||||
|
setSetting("_gyroLook", _gyroLook->isChecked());
|
||||||
|
|
||||||
|
setSetting("_mouseLook", _mouseLook->isChecked());
|
||||||
|
|
||||||
|
setSetting("_transmitterDrives", _transmitterDrives->isChecked());
|
||||||
|
|
||||||
|
setSetting("_renderVoxels", _renderVoxels->isChecked());
|
||||||
|
|
||||||
|
setSetting("_renderVoxelTextures", _renderVoxelTextures->isChecked());
|
||||||
|
|
||||||
|
setSetting("_renderStarsOn", _renderStarsOn->isChecked());
|
||||||
|
|
||||||
|
setSetting("_renderAtmosphereOn", _renderAtmosphereOn->isChecked());
|
||||||
|
|
||||||
|
setSetting("_renderAvatarsOn", _renderAvatarsOn->isChecked());
|
||||||
|
|
||||||
|
setSetting("_renderStatsOn", _renderStatsOn->isChecked());
|
||||||
|
|
||||||
|
setSetting("_renderFrameTimerOn", _renderFrameTimerOn->isChecked());
|
||||||
|
|
||||||
|
setSetting("_renderLookatOn", _renderLookatOn->isChecked());
|
||||||
|
|
||||||
|
setSetting("_logOn", _logOn->isChecked());
|
||||||
|
|
||||||
|
setSetting("_frustumOn", _frustumOn->isChecked());
|
||||||
|
|
||||||
|
setSetting("_viewFrustumFromOffset", _viewFrustumFromOffset->isChecked());
|
||||||
|
|
||||||
|
setSetting("_cameraFrustum", _cameraFrustum->isChecked());
|
||||||
|
|
||||||
|
saveSettingsFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::readSettings()
|
||||||
|
{
|
||||||
|
readSettingsFile();
|
||||||
|
_myAvatar.readAvatarDataFromFile();
|
||||||
|
|
||||||
|
bool settingState;
|
||||||
|
getSetting("_gyroLook", settingState, _gyroLook->isChecked());
|
||||||
|
_gyroLook->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_mouseLook", settingState, _mouseLook->isChecked());
|
||||||
|
_mouseLook->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_transmitterDrives", settingState, _transmitterDrives->isChecked());
|
||||||
|
_transmitterDrives->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_renderVoxels", settingState, _renderVoxels->isChecked());
|
||||||
|
_renderVoxels->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_renderVoxelTextures", settingState, _renderVoxelTextures->isChecked());
|
||||||
|
_renderVoxelTextures->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_renderStarsOn", settingState, _renderStarsOn->isChecked());
|
||||||
|
_renderStarsOn->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_renderAtmosphereOn", settingState, _renderAtmosphereOn->isChecked());
|
||||||
|
_renderAtmosphereOn->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_renderAvatarsOn", settingState, _renderAvatarsOn->isChecked());
|
||||||
|
_renderAvatarsOn->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_renderStatsOn", settingState, _renderStatsOn->isChecked());
|
||||||
|
_renderStatsOn->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_renderFrameTimerOn", settingState, _renderFrameTimerOn->isChecked());
|
||||||
|
_renderFrameTimerOn->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_renderLookatOn", settingState, _renderLookatOn->isChecked());
|
||||||
|
_renderLookatOn->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_logOn", settingState, _logOn->isChecked());
|
||||||
|
_logOn->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_frustumOn", settingState, _frustumOn->isChecked());
|
||||||
|
_frustumOn->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_viewFrustumFromOffset", settingState, _viewFrustumFromOffset->isChecked());
|
||||||
|
_viewFrustumFromOffset->setChecked(settingState);
|
||||||
|
|
||||||
|
getSetting("_cameraFrustum", settingState, _cameraFrustum->isChecked());
|
||||||
|
_cameraFrustum->setChecked(settingState);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
@ -67,6 +68,57 @@ public:
|
||||||
VoxelSystem* getVoxels() { return &_voxels; }
|
VoxelSystem* getVoxels() { return &_voxels; }
|
||||||
Environment* getEnvironment() { return &_environment; }
|
Environment* getEnvironment() { return &_environment; }
|
||||||
bool shouldEchoAudio() { return _echoAudioMode->isChecked(); }
|
bool shouldEchoAudio() { return _echoAudioMode->isChecked(); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@fn getSettingBool
|
||||||
|
@brief A function for getting boolean settings from the settings file.
|
||||||
|
@param settingName The desired setting to get the value for.
|
||||||
|
@param boolSetting The referenced variable where the setting will be stored.
|
||||||
|
@param defaultSetting The default setting to assign to boolSetting if this function fails to find the appropriate setting. Defaults to false.
|
||||||
|
*/
|
||||||
|
bool getSetting(const char* setting, bool &value, const bool defaultSetting = false) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@fn getSettingFloat
|
||||||
|
@brief A function for getting float settings from the settings file.
|
||||||
|
@param settingName The desired setting to get the value for.
|
||||||
|
@param floatSetting The referenced variable where the setting will be stored.
|
||||||
|
@param defaultSetting The default setting to assign to boolSetting if this function fails to find the appropriate setting. Defaults to 0.0f.
|
||||||
|
*/
|
||||||
|
bool getSetting(const char* setting, float &value, const float defaultSetting = 0.0f) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@fn getSettingVec3
|
||||||
|
@brief A function for getting boolean settings from the settings file.
|
||||||
|
@param settingName The desired setting to get the value for.
|
||||||
|
@param vecSetting The referenced variable where the setting will be stored.
|
||||||
|
@param defaultSetting The default setting to assign to boolSetting if this function fails to find the appropriate setting. Defaults to <0.0f, 0.0f, 0.0f>
|
||||||
|
*/
|
||||||
|
bool getSetting(const char* setting, glm::vec3 &value, const glm::vec3& defaultSetting = glm::vec3(0.0f, 0.0f, 0.0f)) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@fn setSettingBool
|
||||||
|
@brief A function for setting boolean setting values when saving the settings file.
|
||||||
|
@param settingName The desired setting to populate a value for.
|
||||||
|
@param boolSetting The value to set.
|
||||||
|
*/
|
||||||
|
void setSetting(const char* setting, const bool value);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@fn setSettingFloat
|
||||||
|
@brief A function for setting boolean setting values when saving the settings file.
|
||||||
|
@param settingName The desired setting to populate a value for.
|
||||||
|
@param floatSetting The value to set.
|
||||||
|
*/
|
||||||
|
void setSetting(const char* setting, const float value);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@fn setSettingVec3
|
||||||
|
@brief A function for setting boolean setting values when saving the settings file.
|
||||||
|
@param settingName The desired setting to populate a value for.
|
||||||
|
@param vecSetting The value to set.
|
||||||
|
*/
|
||||||
|
void setSetting(const char* setting, const glm::vec3& value);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
@ -137,6 +189,13 @@ private:
|
||||||
static void attachNewHeadToAgent(Agent *newAgent);
|
static void attachNewHeadToAgent(Agent *newAgent);
|
||||||
static void* networkReceive(void* args);
|
static void* networkReceive(void* args);
|
||||||
|
|
||||||
|
// These two functions are technically not necessary, but they help keep things in one place.
|
||||||
|
void readSettings(); //! This function is largely to help consolidate getting settings in one place.
|
||||||
|
void saveSettings(); //! This function is to consolidate any settings setting in one place.
|
||||||
|
|
||||||
|
void readSettingsFile(); //! This function reads data from the settings file, splitting data into key value pairs using '=' as a delimiter.
|
||||||
|
void saveSettingsFile(); //! This function writes all changes in the settings table to the settings file, serializing all settings added through the setSetting functions.
|
||||||
|
|
||||||
QMainWindow* _window;
|
QMainWindow* _window;
|
||||||
QGLWidget* _glWidget;
|
QGLWidget* _glWidget;
|
||||||
|
|
||||||
|
@ -255,6 +314,12 @@ private:
|
||||||
int _packetsPerSecond;
|
int _packetsPerSecond;
|
||||||
int _bytesPerSecond;
|
int _bytesPerSecond;
|
||||||
int _bytesCount;
|
int _bytesCount;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Store settings in a map, storing keys and values as strings.
|
||||||
|
* Interpret values as needed on demand. through the appropriate getters and setters.
|
||||||
|
*/
|
||||||
|
std::map<std::string, std::string> _settingsTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__interface__Application__) */
|
#endif /* defined(__interface__Application__) */
|
||||||
|
|
|
@ -1237,40 +1237,25 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char AVATAR_DATA_FILENAME[] = "avatar.ifd";
|
|
||||||
|
|
||||||
void Avatar::writeAvatarDataToFile() {
|
void Avatar::writeAvatarDataToFile() {
|
||||||
// write the avatar position and yaw to a local file
|
Application::getInstance()->setSetting("avatarPos", _position);
|
||||||
FILE* avatarFile = fopen(AVATAR_DATA_FILENAME, "w");
|
Application::getInstance()->setSetting("avatarRotation", glm::vec3(_bodyYaw, _bodyPitch, _bodyRoll));
|
||||||
|
|
||||||
if (avatarFile) {
|
|
||||||
fprintf(avatarFile, "%f,%f,%f %f,%f,%f", _position.x, _position.y, _position.z, _bodyYaw, _bodyPitch, _bodyRoll);
|
|
||||||
fclose(avatarFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::readAvatarDataFromFile() {
|
void Avatar::readAvatarDataFromFile() {
|
||||||
FILE* avatarFile = fopen(AVATAR_DATA_FILENAME, "r");
|
glm::vec3 readPosition;
|
||||||
|
glm::vec3 readRotation;
|
||||||
|
|
||||||
if (avatarFile) {
|
Application::getInstance()->getSetting("avatarPos", readPosition, glm::vec3(6.1f, 0, 1.4f));
|
||||||
glm::vec3 readPosition;
|
Application::getInstance()->getSetting("avatarRotation", readRotation, glm::vec3(0, 0, 0));
|
||||||
float readYaw, readPitch, readRoll;
|
|
||||||
fscanf(avatarFile, "%f,%f,%f %f,%f,%f", &readPosition.x, &readPosition.y, &readPosition.z,
|
_bodyYaw = readRotation.x;
|
||||||
&readYaw, &readPitch, &readRoll);
|
_bodyPitch = readRotation.y;
|
||||||
|
_bodyRoll = readRotation.z;
|
||||||
// make sure these values are sane
|
_position = readPosition;
|
||||||
if (!isnan(readPosition.x) && !isnan(readPosition.y) && !isnan(readPosition.z) &&
|
|
||||||
!isnan(readYaw) && !isnan(readPitch) && !isnan(readRoll)) {
|
|
||||||
_position = readPosition;
|
|
||||||
_bodyYaw = readYaw;
|
|
||||||
_bodyPitch = readPitch;
|
|
||||||
_bodyRoll = readRoll;
|
|
||||||
}
|
|
||||||
fclose(avatarFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// render a makeshift cone section that serves as a body part connecting joint spheres
|
// render a makeshift cone section that serves as a body part connecting joint spheres
|
||||||
void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2) {
|
void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2) {
|
||||||
|
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
|
|
Loading…
Reference in a new issue