From 17a5e6a700cd0cbd7046949040cd21650ffcb610 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 27 May 2013 12:37:42 -0400 Subject: [PATCH 01/66] First round of settings serialization. Setup an API to load and save different settings to the avatar data file. Initial serialized settings: Gyro look Mouse look Transmitter drives Voxel rendering Voxel textures Star rendering Atmosphere rendering Avatar rendering Oculus rift mode Render stats Frame stats Look at vectors Logging Frustum debugging View frustum offset Camera frustum --- interface/src/Application.cpp | 269 +++++++++++++++++++++++++++++++++- interface/src/Application.h | 16 ++ interface/src/Avatar.cpp | 33 ++--- 3 files changed, 292 insertions(+), 26 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a66b56b809..44c65e2613 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -255,8 +255,6 @@ void Application::initializeGL() { printLog("Network receive thread created.\n"); } - _myAvatar.readAvatarDataFromFile(); - // call terminate before exiting connect(this, SIGNAL(aboutToQuit()), SLOT(terminate())); @@ -270,6 +268,8 @@ void Application::initializeGL() { connect(idleTimer, SIGNAL(timeout()), SLOT(idle())); idleTimer->start(0); + readSettings(); + if (_justStarted) { float startupTime = (usecTimestampNow() - usecTimestamp(&_applicationStartupTime))/1000000.0; _justStarted = false; @@ -775,7 +775,176 @@ void Application::wheelEvent(QWheelEvent* event) { decreaseVoxelSize(); } } + +const char AVATAR_DATA_FILENAME[] = "avatar.ifd"; + +bool Application::openSettingsFile(const char *mode) +{ + _settingsFile = fopen(AVATAR_DATA_FILENAME, mode); + if (_settingsFile) + { + return true; + } else { + return false; + } +} + +void Application::closeSettingsFile() +{ + if (_settingsFile) + { + fclose(_settingsFile); + _settingsFile = NULL; + } +} + +bool Application::getSettingBool(const char *settingName, bool &boolSetting, bool defaultSetting) +{ + if (_settingsFile) + { + int readPosition; + + char setting[128]; + char vals[] = "%d"; + sprintf(setting, "\n%s=%s", settingName, vals); + + int res = fscanf(_settingsFile, setting, &readPosition); + + if (res != EOF) + { + if (readPosition == 1) + { + boolSetting = true; + } else if (readPosition == 0) { + boolSetting = false; + } + } else { + boolSetting = defaultSetting; + return false; + } + + } else { + boolSetting = defaultSetting; + + printLog("Call to getSetting function without _settingsFile being open! Forgot to call openSettingsFile perhaps?\n"); + + return false; + } + + return true; +} + +bool Application::getSettingFloat(const char *settingName, float &floatSetting, float defaultSetting) +{ + if (_settingsFile) + { + float readPosition; + + char setting[128]; + char vals[] = "%f"; + sprintf(setting, "\n%s=%s", settingName, vals); + + int res = fscanf(_settingsFile, setting, &readPosition); + + if (res != EOF) + { + if (!isnan(readPosition)) { + floatSetting = readPosition; + } else { + floatSetting = defaultSetting; + } + } else { + floatSetting = defaultSetting; + return false; + } + } else { + floatSetting = defaultSetting; + + printLog("Call to getSetting function without _settingsFile! Forgot to call openSettingsFile perhaps?\n"); + + return false; + } + + return true; +} + +bool Application::getSettingVec3(const char *settingName, glm::vec3 &vecSetting, glm::vec3 defaultSetting) +{ + if (_settingsFile) + { + glm::vec3 readPosition; + + char setting[128]; + char vals[] = "%f,%f,%f"; + sprintf(setting, "\n%s=%s", settingName, vals); + + int res = fscanf(_settingsFile, setting, &readPosition.x, &readPosition.y, &readPosition.z); + + if (res != EOF) + { + if (!isnan(readPosition.x) && !isnan(readPosition.y) && !isnan(readPosition.z)) { + vecSetting = readPosition; + } else { + vecSetting = defaultSetting; + } + } else { + vecSetting = defaultSetting; + return false; + } + } else { + vecSetting = defaultSetting; + + printLog("Call to getSetting function without _settingsFile! Forgot to call openSettingsFile perhaps?\n"); + + return false; + } + + return true; +} + +void Application::setSettingBool(const char *settingName, bool boolSetting) +{ + if (_settingsFile) + { + char setting[128]; + char vals[] = "%d"; + sprintf(setting, "\n%s=%s", settingName, vals); + printLog(setting, boolSetting); + fprintf(_settingsFile, setting, boolSetting); + } else { + printLog("Call to setSetting function without _settingsFile! Forgot to call openSettingsFile perhaps?\n"); + } +} + +void Application::setSettingFloat(const char *settingName, float floatSetting) +{ + if (_settingsFile) + { + char setting[128]; + char vals[] = "%f"; + sprintf(setting, "\n%s=%s", settingName, vals); + printLog(setting, floatSetting); + fprintf(_settingsFile, setting, floatSetting); + } else { + printLog("Call to setSetting function without _settingsFile! Forgot to call openSettingsFile perhaps?\n"); + } +} + +void Application::setSettingVec3(const char *settingName, glm::vec3 vecSetting) +{ + if (_settingsFile) + { + char setting[128]; + char vals[] = "%f,%f,%f"; + sprintf(setting, "\n%s=%s", settingName, vals); + printLog(setting, vecSetting.x, vecSetting.y, vecSetting.z); + fprintf(_settingsFile, setting, vecSetting.x, vecSetting.y, vecSetting.z); + } else { + printLog("Call to setSetting function without _settingsFile! Forgot to call openSettingsFile perhaps?\n"); + } +} + // Every second, check the frame rates and other stuff void Application::timer() { gettimeofday(&_timerEnd, NULL); @@ -1008,7 +1177,7 @@ void Application::terminate() { // Close serial port // close(serial_fd); - _myAvatar.writeAvatarDataToFile(); + saveSettings(); if (_enableNetworkThread) { _stopNetworkReceiveThread = true; @@ -2157,3 +2326,97 @@ void* Application::networkReceive(void* args) { 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. + openSettingsFile("wt"); + _myAvatar.writeAvatarDataToFile(); + + setSettingBool("_gyroLook", _gyroLook->isChecked()); + + setSettingBool("_mouseLook", _mouseLook->isChecked()); + + setSettingBool("_transmitterDrives", _transmitterDrives->isChecked()); + + setSettingBool("_renderVoxels", _renderVoxels->isChecked()); + + setSettingBool("_renderVoxelTextures", _renderVoxelTextures->isChecked()); + + setSettingBool("_renderStarsOn", _renderStarsOn->isChecked()); + + setSettingBool("_renderAtmosphereOn", _renderAtmosphereOn->isChecked()); + + setSettingBool("_renderAvatarsOn", _renderAvatarsOn->isChecked()); + + setSettingBool("_oculusOn", _oculusOn->isChecked()); + + setSettingBool("_renderStatsOn", _renderStatsOn->isChecked()); + + setSettingBool("_renderFrameTimerOn", _renderFrameTimerOn->isChecked()); + + setSettingBool("_renderLookatOn", _renderLookatOn->isChecked()); + + setSettingBool("_logOn", _logOn->isChecked()); + + setSettingBool("_frustumOn", _frustumOn->isChecked()); + + setSettingBool("_viewFrustumFromOffset", _viewFrustumFromOffset->isChecked()); + + closeSettingsFile(); +} + +void Application::readSettings() +{ + openSettingsFile("rt"); + _myAvatar.readAvatarDataFromFile(); + + bool settingState; + getSettingBool("_gyroLook", settingState, _gyroLook->isChecked()); + _gyroLook->setChecked(settingState); + + getSettingBool("_mouseLook", settingState, _mouseLook->isChecked()); + _mouseLook->setChecked(settingState); + + getSettingBool("_transmitterDrives", settingState, _transmitterDrives->isChecked()); + _transmitterDrives->setChecked(settingState); + + getSettingBool("_renderVoxels", settingState, _renderVoxels->isChecked()); + _renderVoxels->setChecked(settingState); + + getSettingBool("_renderVoxelTextures", settingState, _renderVoxelTextures->isChecked()); + _renderVoxelTextures->setChecked(settingState); + + getSettingBool("_renderStarsOn", settingState, _renderStarsOn->isChecked()); + _renderStarsOn->setChecked(settingState); + + getSettingBool("_renderAtmosphereOn", settingState, _renderAtmosphereOn->isChecked()); + _renderAtmosphereOn->setChecked(settingState); + + getSettingBool("_renderAvatarsOn", settingState, _renderAvatarsOn->isChecked()); + _renderAvatarsOn->setChecked(settingState); + + getSettingBool("_oculusOn", settingState, _oculusOn->isChecked()); + _oculusOn->setChecked(settingState); + + getSettingBool("_renderStatsOn", settingState, _renderStatsOn->isChecked()); + _renderStatsOn->setChecked(settingState); + + getSettingBool("_renderFrameTimerOn", settingState, _renderFrameTimerOn->isChecked()); + _renderFrameTimerOn->setChecked(settingState); + + getSettingBool("_renderLookatOn", settingState, _renderLookatOn->isChecked()); + _renderLookatOn->setChecked(settingState); + + getSettingBool("_logOn", settingState, _logOn->isChecked()); + _logOn->setChecked(settingState); + + getSettingBool("_frustumOn", settingState, _frustumOn->isChecked()); + _frustumOn->setChecked(settingState); + + getSettingBool("_viewFrustumFromOffset", settingState, _viewFrustumFromOffset->isChecked()); + _viewFrustumFromOffset->setChecked(settingState); + + closeSettingsFile(); +} + diff --git a/interface/src/Application.h b/interface/src/Application.h index 98a41e89c2..62df328425 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -64,6 +64,14 @@ public: Avatar* getAvatar() { return &_myAvatar; } VoxelSystem* getVoxels() { return &_voxels; } Environment* getEnvironment() { return &_environment; } + + bool getSettingBool(const char* settingName, bool &boolSetting, bool defaultSetting = false); + bool getSettingFloat(const char* settingName, float &floatSetting, float defaultSetting = 0.0f); + bool getSettingVec3(const char* settingName, glm::vec3 &vecSetting, glm::vec3 defaultSetting = glm::vec3(0, 0, 0)); + + void setSettingBool(const char* settingName, bool boolSetting); + void setSettingFloat(const char* settingName, float floatSetting); + void setSettingVec3(const char* settingName, glm::vec3 vecSetting); private slots: @@ -132,6 +140,12 @@ private: static void attachNewHeadToAgent(Agent *newAgent); static void* networkReceive(void* args); + bool openSettingsFile(const char* mode); + void closeSettingsFile(); + + void saveSettings(); + void readSettings(); + QMainWindow* _window; QGLWidget* _glWidget; @@ -248,6 +262,8 @@ private: int _packetsPerSecond; int _bytesPerSecond; int _bytesCount; + + FILE* _settingsFile; }; #endif /* defined(__interface__Application__) */ diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 6d278e641b..e59998dfcf 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1203,36 +1203,23 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity } } -const char AVATAR_DATA_FILENAME[] = "avatar.ifd"; - void Avatar::writeAvatarDataToFile() { - // write the avatar position and yaw to a local file - FILE* avatarFile = fopen(AVATAR_DATA_FILENAME, "w"); - - if (avatarFile) { - fprintf(avatarFile, "%f,%f,%f %f", _position.x, _position.y, _position.z, _bodyYaw); - fclose(avatarFile); - } + Application::getInstance()->setSettingVec3("avatarPos", _position); + Application::getInstance()->setSettingFloat("avatarYaw", _bodyYaw); } void Avatar::readAvatarDataFromFile() { - FILE* avatarFile = fopen(AVATAR_DATA_FILENAME, "r"); + glm::vec3 readPosition; + float readYaw; - if (avatarFile) { - glm::vec3 readPosition; - float readYaw; - fscanf(avatarFile, "%f,%f,%f %f", &readPosition.x, &readPosition.y, &readPosition.z, &readYaw); - - // make sure these values are sane - if (!isnan(readPosition.x) && !isnan(readPosition.y) && !isnan(readPosition.z) && !isnan(readYaw)) { - _position = readPosition; - _bodyYaw = readYaw; - } - fclose(avatarFile); - } + Application::getInstance()->getSettingVec3("avatarPos", readPosition, glm::vec3(6.1f, 0, 1.4f)); + Application::getInstance()->getSettingFloat("avatarYaw", readYaw, -90.0f); + + _bodyYaw = readYaw; + _position = readPosition; } -// 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) { glBegin(GL_TRIANGLES); From 93eac0c0dcb871a41e38a6adf4c305d4192e78d0 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 27 May 2013 12:56:41 -0400 Subject: [PATCH 02/66] Setup various debug options. --- interface/src/Application.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 44c65e2613..ac0187a26f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2363,6 +2363,14 @@ void Application::saveSettings() setSettingBool("_viewFrustumFromOffset", _viewFrustumFromOffset->isChecked()); + setSettingBool("wantsViewDeltaSending", _myAvatar.getWantDelta()); + + setSettingBool("wantsResIn", _myAvatar.getWantResIn()); + + setSettingBool("wantsMonochrome", _myAvatar.getWantColor()); + + setSettingBool("renderPipelineWarnings", _voxels.getRenderPipelineWarnings()); + closeSettingsFile(); } @@ -2417,6 +2425,18 @@ void Application::readSettings() getSettingBool("_viewFrustumFromOffset", settingState, _viewFrustumFromOffset->isChecked()); _viewFrustumFromOffset->setChecked(settingState); + getSettingBool("wantsResIn", settingState, false); + setWantsResIn(settingState); + + getSettingBool("wantsMonochrome", settingState, false); + setWantsMonochrome(settingState); + + getSettingBool("renderPipelineWarnings", settingState, false); + setRenderWarnings(settingState); + + getSettingBool("wantsViewDeltaSending", settingState, false); + setWantsDelta(settingState); + closeSettingsFile(); } From 94a07b92a7da6fe43651a2af6ed2bde2b88f0a65 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 27 May 2013 15:54:32 -0400 Subject: [PATCH 03/66] Documentation for #19308. --- interface/src/Application.h | 47 +++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index 62df328425..3934ff1610 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -65,12 +65,55 @@ public: VoxelSystem* getVoxels() { return &_voxels; } Environment* getEnvironment() { return &_environment; } + /*! + @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 getSettingBool(const char* settingName, bool &boolSetting, bool defaultSetting = false); - bool getSettingFloat(const char* settingName, float &floatSetting, float defaultSetting = 0.0f); - bool getSettingVec3(const char* settingName, glm::vec3 &vecSetting, glm::vec3 defaultSetting = glm::vec3(0, 0, 0)); + /*! + @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 getSettingFloat(const char* settingName, float &floatSetting, float defaultSetting = 0.0f); + + /*! + @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 getSettingVec3(const char* settingName, glm::vec3 &vecSetting, glm::vec3 defaultSetting = glm::vec3(0.0f, 0.0f, 0.0f)); + + /*! + @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 setSettingBool(const char* settingName, bool boolSetting); + + /*! + @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 setSettingFloat(const char* settingName, float floatSetting); + + /*! + @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 setSettingVec3(const char* settingName, glm::vec3 vecSetting); private slots: From 5efda079c93b9f9e27424b355b93cacea3b5aded Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 27 May 2013 18:48:05 -0400 Subject: [PATCH 04/66] Store settings in an ordered map to allow for runtime getting and setting of settings. Read the setting file on startup, then write on shut down. --- interface/src/Application.cpp | 213 ++++++++++++++-------------------- interface/src/Application.h | 18 ++- 2 files changed, 102 insertions(+), 129 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ac0187a26f..2049dc2e92 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -778,57 +778,93 @@ void Application::wheelEvent(QWheelEvent* event) { const char AVATAR_DATA_FILENAME[] = "avatar.ifd"; -bool Application::openSettingsFile(const char *mode) +void Application::readSettingsFile() { - _settingsFile = fopen(AVATAR_DATA_FILENAME, mode); + FILE* settingsFile = fopen(AVATAR_DATA_FILENAME, "rt"); - if (_settingsFile) + if (settingsFile) { - return true; - } else { - return false; + 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::closeSettingsFile() +void Application::saveSettingsFile() { - if (_settingsFile) + FILE* settingsFile = fopen(AVATAR_DATA_FILENAME, "wt"); + + if (settingsFile) { - fclose(_settingsFile); - _settingsFile = NULL; + for (std::map::iterator i = _settingsTable.begin(); i != _settingsTable.end(); i++) + { + fprintf(settingsFile, "\n%s=%s", i->first.data(), i->second.data()); + } } + + fclose(settingsFile); } bool Application::getSettingBool(const char *settingName, bool &boolSetting, bool defaultSetting) { - if (_settingsFile) + if (_settingsTable[settingName] != "") { - int readPosition; + int readBool; + sscanf(_settingsTable[settingName].data(), "%d", &readBool); - char setting[128]; - char vals[] = "%d"; - sprintf(setting, "\n%s=%s", settingName, vals); - - int res = fscanf(_settingsFile, setting, &readPosition); - - if (res != EOF) + if (readBool == 1) { - if (readPosition == 1) - { - boolSetting = true; - } else if (readPosition == 0) { - boolSetting = false; - } - } else { - boolSetting = defaultSetting; - return false; + boolSetting = true; + } else if (readBool == 0) { + boolSetting = false; } - } else { boolSetting = defaultSetting; - - printLog("Call to getSetting function without _settingsFile being open! Forgot to call openSettingsFile perhaps?\n"); - return false; } @@ -837,32 +873,19 @@ bool Application::getSettingBool(const char *settingName, bool &boolSetting, boo bool Application::getSettingFloat(const char *settingName, float &floatSetting, float defaultSetting) { - if (_settingsFile) + if (_settingsTable[settingName] != "") { - float readPosition; + float readFloat; + sscanf(_settingsTable[settingName].data(), "%f", &readFloat); - char setting[128]; - char vals[] = "%f"; - sprintf(setting, "\n%s=%s", settingName, vals); - - int res = fscanf(_settingsFile, setting, &readPosition); - - if (res != EOF) - { - if (!isnan(readPosition)) { - floatSetting = readPosition; - } else { - floatSetting = defaultSetting; - } + if (!isnan(readFloat)) { + floatSetting = readFloat; } else { floatSetting = defaultSetting; return false; } } else { floatSetting = defaultSetting; - - printLog("Call to getSetting function without _settingsFile! Forgot to call openSettingsFile perhaps?\n"); - return false; } @@ -871,32 +894,19 @@ bool Application::getSettingFloat(const char *settingName, float &floatSetting, bool Application::getSettingVec3(const char *settingName, glm::vec3 &vecSetting, glm::vec3 defaultSetting) { - if (_settingsFile) + if (_settingsTable[settingName] != "") { - glm::vec3 readPosition; + glm::vec3 readVec; + sscanf(_settingsTable[settingName].data(), "%f,%f,%f", &readVec.x, &readVec.y, &readVec.z); - char setting[128]; - char vals[] = "%f,%f,%f"; - sprintf(setting, "\n%s=%s", settingName, vals); - - int res = fscanf(_settingsFile, setting, &readPosition.x, &readPosition.y, &readPosition.z); - - if (res != EOF) - { - if (!isnan(readPosition.x) && !isnan(readPosition.y) && !isnan(readPosition.z)) { - vecSetting = readPosition; - } else { - vecSetting = defaultSetting; - } + if (!isnan(readVec.x) && !isnan(readVec.y) && !isnan(readVec.z)) { + vecSetting = readVec; } else { vecSetting = defaultSetting; - return false; + return false; } } else { vecSetting = defaultSetting; - - printLog("Call to getSetting function without _settingsFile! Forgot to call openSettingsFile perhaps?\n"); - return false; } @@ -905,44 +915,23 @@ bool Application::getSettingVec3(const char *settingName, glm::vec3 &vecSetting, void Application::setSettingBool(const char *settingName, bool boolSetting) { - if (_settingsFile) - { - char setting[128]; - char vals[] = "%d"; - sprintf(setting, "\n%s=%s", settingName, vals); - printLog(setting, boolSetting); - fprintf(_settingsFile, setting, boolSetting); - } else { - printLog("Call to setSetting function without _settingsFile! Forgot to call openSettingsFile perhaps?\n"); - } + char setting[128]; + sprintf(setting, "%d", boolSetting); + _settingsTable[settingName] = setting; } void Application::setSettingFloat(const char *settingName, float floatSetting) { - if (_settingsFile) - { - char setting[128]; - char vals[] = "%f"; - sprintf(setting, "\n%s=%s", settingName, vals); - printLog(setting, floatSetting); - fprintf(_settingsFile, setting, floatSetting); - } else { - printLog("Call to setSetting function without _settingsFile! Forgot to call openSettingsFile perhaps?\n"); - } + char setting[128]; + sprintf(setting, "%f", floatSetting); + _settingsTable[settingName] = setting; } void Application::setSettingVec3(const char *settingName, glm::vec3 vecSetting) { - if (_settingsFile) - { - char setting[128]; - char vals[] = "%f,%f,%f"; - sprintf(setting, "\n%s=%s", settingName, vals); - printLog(setting, vecSetting.x, vecSetting.y, vecSetting.z); - fprintf(_settingsFile, setting, vecSetting.x, vecSetting.y, vecSetting.z); - } else { - printLog("Call to setSetting function without _settingsFile! Forgot to call openSettingsFile perhaps?\n"); - } + char setting[128]; + sprintf(setting, "%f,%f,%f", vecSetting.x, vecSetting.y, vecSetting.z); + _settingsTable[settingName] = setting; } // Every second, check the frame rates and other stuff @@ -2330,7 +2319,6 @@ 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. - openSettingsFile("wt"); _myAvatar.writeAvatarDataToFile(); setSettingBool("_gyroLook", _gyroLook->isChecked()); @@ -2363,20 +2351,12 @@ void Application::saveSettings() setSettingBool("_viewFrustumFromOffset", _viewFrustumFromOffset->isChecked()); - setSettingBool("wantsViewDeltaSending", _myAvatar.getWantDelta()); - - setSettingBool("wantsResIn", _myAvatar.getWantResIn()); - - setSettingBool("wantsMonochrome", _myAvatar.getWantColor()); - - setSettingBool("renderPipelineWarnings", _voxels.getRenderPipelineWarnings()); - - closeSettingsFile(); + saveSettingsFile(); } void Application::readSettings() { - openSettingsFile("rt"); + readSettingsFile(); _myAvatar.readAvatarDataFromFile(); bool settingState; @@ -2425,18 +2405,5 @@ void Application::readSettings() getSettingBool("_viewFrustumFromOffset", settingState, _viewFrustumFromOffset->isChecked()); _viewFrustumFromOffset->setChecked(settingState); - getSettingBool("wantsResIn", settingState, false); - setWantsResIn(settingState); - - getSettingBool("wantsMonochrome", settingState, false); - setWantsMonochrome(settingState); - - getSettingBool("renderPipelineWarnings", settingState, false); - setRenderWarnings(settingState); - - getSettingBool("wantsViewDeltaSending", settingState, false); - setWantsDelta(settingState); - - closeSettingsFile(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 3934ff1610..bde3f989d2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -11,6 +11,7 @@ #include #include +#include #include @@ -183,11 +184,12 @@ private: static void attachNewHeadToAgent(Agent *newAgent); static void* networkReceive(void* args); - bool openSettingsFile(const char* mode); - void closeSettingsFile(); + // 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 saveSettings(); - void readSettings(); + 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; QGLWidget* _glWidget; @@ -214,7 +216,7 @@ private: QAction* _destructiveAddVoxel; // when doing voxel editing do we want them to be destructive QAction* _frustumOn; // Whether or not to display the debug view frustum QAction* _viewFrustumFromOffset; // Whether or not to offset the view of the frustum - QAction* _cameraFrustum; // which frustum to look at + QAction* _cameraFrustum; // which frustum to look at QAction* _frustumRenderModeAction; SerialInterface _serialPort; @@ -306,7 +308,11 @@ private: int _bytesPerSecond; int _bytesCount; - FILE* _settingsFile; + /*! + * 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 _settingsTable; }; #endif /* defined(__interface__Application__) */ From 8ac83357764896c26d1fca306b246519b732f07e Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 27 May 2013 19:18:36 -0400 Subject: [PATCH 05/66] Check how many matches were found for the given data type we're checking for. 1 for bool and float, 3 for vec3. Return false and assign default values if this isn't true. --- interface/src/Application.cpp | 48 +++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2049dc2e92..e9b7fc0053 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -855,13 +855,18 @@ bool Application::getSettingBool(const char *settingName, bool &boolSetting, boo if (_settingsTable[settingName] != "") { int readBool; - sscanf(_settingsTable[settingName].data(), "%d", &readBool); + int res = sscanf(_settingsTable[settingName].data(), "%d", &readBool); - if (readBool == 1) + printLog("Found setting %d times!", res); + + if (res == 1) { - boolSetting = true; - } else if (readBool == 0) { - boolSetting = false; + if (readBool == 1) + { + boolSetting = true; + } else if (readBool == 0) { + boolSetting = false; + } } } else { boolSetting = defaultSetting; @@ -876,10 +881,18 @@ bool Application::getSettingFloat(const char *settingName, float &floatSetting, if (_settingsTable[settingName] != "") { float readFloat; - sscanf(_settingsTable[settingName].data(), "%f", &readFloat); + int res = sscanf(_settingsTable[settingName].data(), "%f", &readFloat); - if (!isnan(readFloat)) { - floatSetting = readFloat; + printLog("Found setting %d times!", res); + + if (res == 1) + { + if (!isnan(readFloat)) { + floatSetting = readFloat; + } else { + floatSetting = defaultSetting; + return false; + } } else { floatSetting = defaultSetting; return false; @@ -897,10 +910,18 @@ bool Application::getSettingVec3(const char *settingName, glm::vec3 &vecSetting, if (_settingsTable[settingName] != "") { glm::vec3 readVec; - sscanf(_settingsTable[settingName].data(), "%f,%f,%f", &readVec.x, &readVec.y, &readVec.z); + int res = sscanf(_settingsTable[settingName].data(), "%f,%f,%f", &readVec.x, &readVec.y, &readVec.z); - if (!isnan(readVec.x) && !isnan(readVec.y) && !isnan(readVec.z)) { - vecSetting = readVec; + printLog("Found setting %d times!", res); + + if (res == 3) + { + if (!isnan(readVec.x) && !isnan(readVec.y) && !isnan(readVec.z)) { + vecSetting = readVec; + } else { + vecSetting = defaultSetting; + return false; + } } else { vecSetting = defaultSetting; return false; @@ -2351,6 +2372,8 @@ void Application::saveSettings() setSettingBool("_viewFrustumFromOffset", _viewFrustumFromOffset->isChecked()); + setSettingBool("_cameraFrustum", _cameraFrustum->isChecked()); + saveSettingsFile(); } @@ -2405,5 +2428,8 @@ void Application::readSettings() getSettingBool("_viewFrustumFromOffset", settingState, _viewFrustumFromOffset->isChecked()); _viewFrustumFromOffset->setChecked(settingState); + getSettingBool("_cameraFrustum", settingState, _cameraFrustum->isChecked()); + _cameraFrustum->setChecked(settingState); + } From b4241da1f0d3ad04d7624d64b480f08d026ee737 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 29 May 2013 00:49:51 -0700 Subject: [PATCH 06/66] add --local option to avatar-mixer --- avatar-mixer/src/main.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index eca698e673..6882fde23e 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -51,7 +51,19 @@ void attachAvatarDataToAgent(Agent* newAgent) { } } +bool wantLocalDomain = false; + int main(int argc, const char* argv[]) { + + // Handle Local Domain testing with the --local command line + const char* local = "--local"; + ::wantLocalDomain = cmdOptionExists(argc, argv,local); + if (::wantLocalDomain) { + printf("Local Domain MODE!\n"); + int ip = getLocalAddress(); + sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); + } + AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT); setvbuf(stdout, NULL, _IOLBF, 0); From 31ff76836344f2b664ce07c90ed6e334cf495d91 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 08:30:14 -0700 Subject: [PATCH 07/66] fixed some glitches in avatar render alpha transition between 3p and 1p --- interface/src/Avatar.cpp | 23 ++++++++++++++--------- interface/src/AvatarTouch.cpp | 7 +++---- interface/src/AvatarTouch.h | 4 ++-- interface/src/Head.cpp | 11 +++++++---- interface/src/Head.h | 3 ++- 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 25e1764025..403918c830 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1114,16 +1114,19 @@ void Avatar::updateArmIKAndConstraints(float deltaTime) { void Avatar::renderBody(bool lookingInMirror) { - const float RENDER_OPAQUE_BEYOND = 1.2f; // Meters beyond which body is shown opaque + const float RENDER_OPAQUE_BEYOND = 1.0f; // Meters beyond which body is shown opaque const float RENDER_TRANSLUCENT_BEYOND = 0.5f; // Render the body as balls and cones for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { float distanceToCamera = glm::length(_cameraPosition - _joint[b].position); + + float alpha = glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f); + // Always render other people, and render myself when beyond threshold distance if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case - if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND) { - _head.render(lookingInMirror, _cameraPosition); + if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND * 0.5) { + _head.render(lookingInMirror, _cameraPosition, alpha); } } else if (_owningAgent || distanceToCamera > RENDER_TRANSLUCENT_BEYOND || b == AVATAR_JOINT_RIGHT_ELBOW @@ -1140,14 +1143,16 @@ void Avatar::renderBody(bool lookingInMirror) { glColor4f(SKIN_COLOR[0] + _joint[b].touchForce * 0.3f, SKIN_COLOR[1] - _joint[b].touchForce * 0.2f, SKIN_COLOR[2] - _joint[b].touchForce * 0.1f, - glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) - / (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f)); + alpha); } - glPushMatrix(); - glTranslatef(_joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z); - glutSolidSphere(_joint[b].radius, 20.0f, 20.0f); - glPopMatrix(); + if ((b != AVATAR_JOINT_HEAD_TOP ) + && (b != AVATAR_JOINT_HEAD_BASE )) { + glPushMatrix(); + glTranslatef(_joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z); + glutSolidSphere(_joint[b].radius, 20.0f, 20.0f); + glPopMatrix(); + } // Render the cone connecting this joint to its parent if (_joint[b].parent != AVATAR_JOINT_NULL) { diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 499e132922..18f4847d33 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -32,7 +32,7 @@ AvatarTouch::AvatarTouch() { _myOrientation.setToIdentity(); _yourOrientation.setToIdentity(); - for (int p=0; p irisTexture; Head::Head(Avatar* owningAvatar) : HeadData((AvatarData*)owningAvatar), + _renderAlpha(0.0), yawRate(0.0f), _returnHeadToCenter(false), _skinColor(0.0f, 0.0f, 0.0f), @@ -205,8 +206,10 @@ void Head::calculateGeometry(bool lookingInMirror) { } -void Head::render(bool lookingInMirror, glm::vec3 cameraPosition) { +void Head::render(bool lookingInMirror, glm::vec3 cameraPosition, float alpha) { + _renderAlpha = alpha; + calculateGeometry(lookingInMirror); glEnable(GL_DEPTH_TEST); @@ -314,7 +317,7 @@ void Head::renderHeadSphere() { glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); //translate to head position glScalef(_scale, _scale, _scale); //scale to head size - glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); + glColor4f(_skinColor.x, _skinColor.y, _skinColor.z, _renderAlpha); glutSolidSphere(1, 30, 30); glPopMatrix(); } @@ -322,13 +325,13 @@ void Head::renderHeadSphere() { void Head::renderEars() { glPushMatrix(); - glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); + glColor4f(_skinColor.x, _skinColor.y, _skinColor.z, _renderAlpha); glTranslatef(_leftEarPosition.x, _leftEarPosition.y, _leftEarPosition.z); glutSolidSphere(0.02, 30, 30); glPopMatrix(); glPushMatrix(); - glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); + glColor4f(_skinColor.x, _skinColor.y, _skinColor.z, _renderAlpha); glTranslatef(_rightEarPosition.x, _rightEarPosition.y, _rightEarPosition.z); glutSolidSphere(0.02, 30, 30); glPopMatrix(); diff --git a/interface/src/Head.h b/interface/src/Head.h index 07d7351cb3..b98fa8c6b6 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -34,7 +34,7 @@ public: void reset(); void simulate(float deltaTime, bool isMine); - void render(bool lookingInMirror, glm::vec3 cameraPosition); + void render(bool lookingInMirror, glm::vec3 cameraPosition, float alpha); void renderMohawk(bool lookingInMirror, glm::vec3 cameraPosition); void setScale (float scale ) { _scale = scale; } @@ -71,6 +71,7 @@ private: glm::vec3 endVelocity; }; + float _renderAlpha; bool _returnHeadToCenter; glm::vec3 _skinColor; glm::vec3 _position; From ca8c78162d524d7182edce8fc94ba581ec2cc91a Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 29 May 2013 10:46:10 -0700 Subject: [PATCH 08/66] one line fix for translucent head --- interface/src/Avatar.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index bf6238779c..51a197f7af 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1158,9 +1158,9 @@ void Avatar::renderBody(bool lookingInMirror) { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { float distanceToCamera = glm::length(_cameraPosition - _joint[b].position); // Always render other people, and render myself when beyond threshold distance - if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case - if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND) { - _head.render(lookingInMirror, _cameraPosition); + if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special + if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND * 0.5) { + _head.render(lookingInMirror, _cameraPosition, 1.f); } } else if (_owningAgent || distanceToCamera > RENDER_TRANSLUCENT_BEYOND || b == AVATAR_JOINT_RIGHT_ELBOW From ad95190e157691300bf58c3bd5776a3d2a4a4ab4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 10:52:20 -0700 Subject: [PATCH 09/66] add debugging for current mixer crash --- audio-mixer/src/main.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index e4a4f83b07..b6e3ab2d7a 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -225,15 +225,15 @@ int main(int argc, const char* argv[]) { } int16_t* goodChannel = bearingRelativeAngleToSource > 0.0f - ? clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL - : clientSamples; + ? clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL + : clientSamples; int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f - ? clientSamples - : clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; + ? clientSamples + : clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; int16_t* delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer() - ? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay - : otherAgentBuffer->getNextOutput() - numSamplesDelay; + ? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay + : otherAgentBuffer->getNextOutput() - numSamplesDelay; for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { @@ -247,6 +247,9 @@ int main(int argc, const char* argv[]) { plateauAdditionOfSamples(goodChannel[s], currentSample); if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { + printf("Attemping to grab a sample at %d\n", s + numSamplesDelay); + printf("The sample here is %d\n", delayedChannel[s + numSamplesDelay]); + plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay], currentSample * weakChannelAmplitudeRatio); } From 2a1357e8e11f84a5fe55cf99c30da3a6504f0276 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 11:00:51 -0700 Subject: [PATCH 10/66] more debugging to track down a mixer crash --- audio-mixer/src/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index b6e3ab2d7a..3a7aa7eb63 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -214,12 +214,13 @@ int main(int argc, const char* argv[]) { (OFF_AXIS_ATTENUATION_FORMULA_STEP * (fabsf(angleOfDelivery) / 90.0f)); attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex] - * otherAgentBuffer->getAttenuationRatio() - * offAxisCoefficient; + * otherAgentBuffer->getAttenuationRatio() + * offAxisCoefficient; bearingRelativeAngleToSource *= (M_PI / 180); float sinRatio = fabsf(sinf(bearingRelativeAngleToSource)); + printf("BRA: %f, SR: %f\n", bearingRelativeAngleToSource, sinRatio); numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); } From 78df9fb2edb43e95baf4f5af5ffb972f79e65c66 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 11:04:46 -0700 Subject: [PATCH 11/66] last pieces of debugging for mixer crash --- libraries/audio/src/AudioRingBuffer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 299ffcc2cb..a9a514ebcb 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -36,6 +36,8 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char* dataBuffer = sourceBuffer + 1; + printf("The number of bytes received is %d\n", numBytes); + if (sourceBuffer[0] == PACKET_HEADER_INJECT_AUDIO || sourceBuffer[0] == PACKET_HEADER_MICROPHONE_AUDIO) { // if this came from an injector or interface client @@ -56,6 +58,8 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { memcpy(&_bearing, dataBuffer, sizeof(float)); dataBuffer += sizeof(_bearing); + printf("This agent's bearing is %f\n", _bearing); + if (_bearing > 180 || _bearing < -180) { // we were passed an invalid bearing because this agent wants loopback (pressed the H key) _shouldLoopbackForAgent = true; From f45062a097a39f84a32dd3d599e63bb9a91c1b16 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 11:14:50 -0700 Subject: [PATCH 12/66] don't use audio when the bearing sent by the agent is garbage --- libraries/audio/src/AudioRingBuffer.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index a9a514ebcb..7cc45ff39f 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -36,8 +36,6 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char* dataBuffer = sourceBuffer + 1; - printf("The number of bytes received is %d\n", numBytes); - if (sourceBuffer[0] == PACKET_HEADER_INJECT_AUDIO || sourceBuffer[0] == PACKET_HEADER_MICROPHONE_AUDIO) { // if this came from an injector or interface client @@ -58,19 +56,22 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { memcpy(&_bearing, dataBuffer, sizeof(float)); dataBuffer += sizeof(_bearing); - printf("This agent's bearing is %f\n", _bearing); - - if (_bearing > 180 || _bearing < -180) { + // if this agent sent us a NaN bearing then don't consider this good audio and bail + if (_bearing != _bearing) { + _endOfLastWrite = _nextOutput = _buffer; + _started = false; + return 0; + } else if (_bearing > 180 || _bearing < -180) { // we were passed an invalid bearing because this agent wants loopback (pressed the H key) _shouldLoopbackForAgent = true; // correct the bearing _bearing = _bearing > 0 - ? _bearing - AGENT_LOOPBACK_MODIFIER - : _bearing + AGENT_LOOPBACK_MODIFIER; + ? _bearing - AGENT_LOOPBACK_MODIFIER + : _bearing + AGENT_LOOPBACK_MODIFIER; } else { _shouldLoopbackForAgent = false; - } + } } // make sure we have enough bytes left for this to be the right amount of audio From 1fb61faded185318e761e49e72e12f6265e26e3b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 11:22:25 -0700 Subject: [PATCH 13/66] fix the isnan check for agent bearing --- libraries/audio/src/AudioRingBuffer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 7cc45ff39f..f397c3210b 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -7,6 +7,7 @@ // #include +#include #include "PacketHeaders.h" @@ -57,7 +58,8 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { dataBuffer += sizeof(_bearing); // if this agent sent us a NaN bearing then don't consider this good audio and bail - if (_bearing != _bearing) { + if (std::isnan(_bearing)) { + printf("Got a nan bearing for this agent\n"); _endOfLastWrite = _nextOutput = _buffer; _started = false; return 0; From 39499e4a9269e36cdd71c69387556c7cfb96ed52 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 11:26:06 -0700 Subject: [PATCH 14/66] fix to head transparency --- interface/src/Avatar.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 403918c830..4118debd14 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1123,6 +1123,10 @@ void Avatar::renderBody(bool lookingInMirror) { float alpha = glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f); + if (lookingInMirror || _owningAgent) { + alpha = 1.0f; + } + // Always render other people, and render myself when beyond threshold distance if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND * 0.5) { From 56e0e3882d51cf34672eedd080ad85b84ced36d1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 11:29:38 -0700 Subject: [PATCH 15/66] kill agents who send NaN bearings --- audio-mixer/src/main.cpp | 6 +++++- libraries/audio/src/AudioRingBuffer.cpp | 5 ++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 3a7aa7eb63..0b4d21ab6e 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -220,7 +220,6 @@ int main(int argc, const char* argv[]) { bearingRelativeAngleToSource *= (M_PI / 180); float sinRatio = fabsf(sinf(bearingRelativeAngleToSource)); - printf("BRA: %f, SR: %f\n", bearingRelativeAngleToSource, sinRatio); numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); } @@ -291,6 +290,11 @@ int main(int argc, const char* argv[]) { } agentList->updateAgentWithData(agentAddress, packetData, receivedBytes); + + if (std::isnan(((AudioRingBuffer *)avatarAgent->getLinkedData())->getBearing())) { + // kill off this agent - temporary solution to mixer crash on mac sleep + avatarAgent->setAlive(false); + } } else if (packetData[0] == PACKET_HEADER_INJECT_AUDIO) { Agent* matchingInjector = NULL; diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index f397c3210b..006dd825bf 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -59,7 +59,6 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { // if this agent sent us a NaN bearing then don't consider this good audio and bail if (std::isnan(_bearing)) { - printf("Got a nan bearing for this agent\n"); _endOfLastWrite = _nextOutput = _buffer; _started = false; return 0; @@ -69,8 +68,8 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { // correct the bearing _bearing = _bearing > 0 - ? _bearing - AGENT_LOOPBACK_MODIFIER - : _bearing + AGENT_LOOPBACK_MODIFIER; + ? _bearing - AGENT_LOOPBACK_MODIFIER + : _bearing + AGENT_LOOPBACK_MODIFIER; } else { _shouldLoopbackForAgent = false; } From 76f7752f2f38db4f816b586149feb8c4f0bff53c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 11:31:46 -0700 Subject: [PATCH 16/66] remove debugging used to track down mixer crash --- audio-mixer/src/main.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 0b4d21ab6e..9204e39b8e 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -246,10 +246,7 @@ int main(int argc, const char* argv[]) { int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient); plateauAdditionOfSamples(goodChannel[s], currentSample); - if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - printf("Attemping to grab a sample at %d\n", s + numSamplesDelay); - printf("The sample here is %d\n", delayedChannel[s + numSamplesDelay]); - + if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay], currentSample * weakChannelAmplitudeRatio); } From 5d74a865e85d2b619dd1cc1bdd5843a3340d0819 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 11:35:32 -0700 Subject: [PATCH 17/66] make audio echo a menu option instead of forcing with mirror --- interface/src/Application.cpp | 8 +++----- interface/src/Application.h | 4 +++- interface/src/Audio.cpp | 4 ++-- interface/src/Audio.h | 3 --- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a8e62a68e7..f307efa470 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -965,11 +965,7 @@ void Application::pair() { PairingHandler::sendPairRequest(); } -void Application::setHead(bool head) { - #ifndef _WIN32 - _audio.setMixerLoopbackFlag(head); - #endif - +void Application::setHead(bool head) { if (head) { _myCamera.setMode(CAMERA_MODE_MIRROR); _myCamera.setModeShiftRate(100.0f); @@ -1133,6 +1129,8 @@ void Application::initMenu() { QMenu* optionsMenu = menuBar->addMenu("Options"); (_lookingInMirror = optionsMenu->addAction("Mirror", this, SLOT(setHead(bool)), Qt::Key_H))->setCheckable(true); + (_echoAudioMode = optionsMenu->addAction("Echo Audio"))->setCheckable(true); + optionsMenu->addAction("Noise", this, SLOT(setNoise(bool)), Qt::Key_N)->setCheckable(true); (_gyroLook = optionsMenu->addAction("Gyro Look"))->setCheckable(true); _gyroLook->setChecked(true); diff --git a/interface/src/Application.h b/interface/src/Application.h index 35d49d275a..ac089b4dd4 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -64,6 +64,7 @@ public: Avatar* getAvatar() { return &_myAvatar; } VoxelSystem* getVoxels() { return &_voxels; } Environment* getEnvironment() { return &_environment; } + QAction* getEchoAudioMode() { return _echoAudioMode; } private slots: @@ -137,7 +138,8 @@ private: QMainWindow* _window; QGLWidget* _glWidget; - QAction* _lookingInMirror; // Are we currently rendering one's own head as if in mirror? + QAction* _lookingInMirror; // Are we currently rendering one's own head as if in mirror? + QAction* _echoAudioMode; // Are we asking the mixer to echo back our audio? QAction* _gyroLook; // Whether to allow the gyro data from head to move your view QAction* _mouseLook; // Whether the have the mouse near edge of screen move your view QAction* _showHeadMouse; // Whether the have the mouse near edge of screen move your view diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 8acb70ebcc..8b484e1fb8 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "Application.h" #include "Audio.h" @@ -158,7 +159,7 @@ int audioCallback (const void* inputBuffer, correctedYaw += 360; } - if (parentAudio->_mixerLoopbackFlag) { + if (Application::getInstance()->getEchoAudioMode()->isChecked()) { correctedYaw = correctedYaw > 0 ? correctedYaw + AGENT_LOOPBACK_MODIFIER : correctedYaw - AGENT_LOOPBACK_MODIFIER; @@ -310,7 +311,6 @@ Audio::Audio(Oscilloscope* scope) : NUM_AUDIO_CHANNELS * (SAMPLE_RATE / 1000.0)), _wasStarved(0), _lastInputLoudness(0), - _mixerLoopbackFlag(false), _lastVelocity(0), _lastAcceleration(0), _totalPacketsReceived(0), diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 34a342a1d4..197daf0194 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -24,8 +24,6 @@ public: void render(int screenWidth, int screenHeight); - void setMixerLoopbackFlag(bool mixerLoopbackFlag) { _mixerLoopbackFlag = mixerLoopbackFlag; } - float getLastInputLoudness() const { return _lastInputLoudness; }; void setLastAcceleration(glm::vec3 lastAcceleration) { _lastAcceleration = lastAcceleration; }; @@ -52,7 +50,6 @@ private: short _jitterBufferSamples; int _wasStarved; float _lastInputLoudness; - bool _mixerLoopbackFlag; glm::vec3 _lastVelocity; glm::vec3 _lastAcceleration; int _totalPacketsReceived; From 350bd878fcb0f27d450f7deff9d38ce21a155484 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 11:39:53 -0700 Subject: [PATCH 18/66] fix --- interface/src/AvatarTouch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 18f4847d33..93899c8400 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -13,7 +13,7 @@ const float THREAD_RADIUS = 0.007; const float HANDS_CLOSE_ENOUGH_TO_GRASP = 0.2; -const float AVATAR_FACING_THRESHOLD = 0.1f; // (-1 to 1) (larger value indicates narrower angle of influence +const float AVATAR_FACING_THRESHOLD = -0.5f; // (-1 to 1) (larger value indicates narrower angle of influence AvatarTouch::AvatarTouch() { From a5a30efec94062109fe7d5375e6137762262d990 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 11:42:10 -0700 Subject: [PATCH 19/66] CR fixes --- interface/src/Application.cpp | 4 ++++ interface/src/Application.h | 3 ++- interface/src/Audio.cpp | 7 +++---- interface/src/Head.cpp | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f307efa470..e8419fd79b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -217,6 +217,10 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : // initialization continues in initializeGL when OpenGL context is ready } +bool Application::shouldEchoAudio() { + return _echoAudioMode->isChecked(); +} + void Application::initializeGL() { printLog( "Created Display Window.\n" ); diff --git a/interface/src/Application.h b/interface/src/Application.h index ac089b4dd4..050f29895a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -61,10 +61,11 @@ public: void wheelEvent(QWheelEvent* event); + bool shouldEchoAudio(); + Avatar* getAvatar() { return &_myAvatar; } VoxelSystem* getVoxels() { return &_voxels; } Environment* getEnvironment() { return &_environment; } - QAction* getEchoAudioMode() { return _echoAudioMode; } private slots: diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 8b484e1fb8..97929a99ca 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include "Application.h" #include "Audio.h" @@ -159,10 +158,10 @@ int audioCallback (const void* inputBuffer, correctedYaw += 360; } - if (Application::getInstance()->getEchoAudioMode()->isChecked()) { + if (Application::getInstance()->shouldEchoAudio()) { correctedYaw = correctedYaw > 0 - ? correctedYaw + AGENT_LOOPBACK_MODIFIER - : correctedYaw - AGENT_LOOPBACK_MODIFIER; + ? correctedYaw + AGENT_LOOPBACK_MODIFIER + : correctedYaw - AGENT_LOOPBACK_MODIFIER; } memcpy(currentPacketPtr, &correctedYaw, sizeof(float)); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 762b9f16ac..6f7f330010 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -40,8 +40,8 @@ vector irisTexture; Head::Head(Avatar* owningAvatar) : HeadData((AvatarData*)owningAvatar), - _renderAlpha(0.0), yawRate(0.0f), + _renderAlpha(0.0), _returnHeadToCenter(false), _skinColor(0.0f, 0.0f, 0.0f), _position(0.0f, 0.0f, 0.0f), From ab3b0c8aa34b04e7fde20cd2466e024d85d8338c Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 11:43:42 -0700 Subject: [PATCH 20/66] alpha --- interface/src/Avatar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index d861623c6f..ac021689c0 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1126,11 +1126,11 @@ void Avatar::renderBody(bool lookingInMirror) { if (lookingInMirror || _owningAgent) { alpha = 1.0f; } - + // Always render other people, and render myself when beyond threshold distance if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND * 0.5) { - _head.render(lookingInMirror, _cameraPosition, 1.f); + _head.render(lookingInMirror, _cameraPosition, alpha); } } else if (_owningAgent || distanceToCamera > RENDER_TRANSLUCENT_BEYOND || b == AVATAR_JOINT_RIGHT_ELBOW From b6a0662c98e333f56d7d52841f401585838c39cb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 11:47:02 -0700 Subject: [PATCH 21/66] inline the shouldEchoAudio --- interface/src/Application.cpp | 4 ---- interface/src/Application.h | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e8419fd79b..f307efa470 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -217,10 +217,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : // initialization continues in initializeGL when OpenGL context is ready } -bool Application::shouldEchoAudio() { - return _echoAudioMode->isChecked(); -} - void Application::initializeGL() { printLog( "Created Display Window.\n" ); diff --git a/interface/src/Application.h b/interface/src/Application.h index 050f29895a..f611a803b9 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -13,6 +13,7 @@ #include #include +#include #include @@ -61,11 +62,10 @@ public: void wheelEvent(QWheelEvent* event); - bool shouldEchoAudio(); - Avatar* getAvatar() { return &_myAvatar; } VoxelSystem* getVoxels() { return &_voxels; } Environment* getEnvironment() { return &_environment; } + bool shouldEchoAudio() { return _echoAudioMode->isChecked(); } private slots: From e34193f1d722e7d6aab15e2bff5d7f6f7408d3cf Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 11:51:16 -0700 Subject: [PATCH 22/66] increased hand motion sensitivity --- interface/src/Avatar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index ac021689c0..68fd9b1c8e 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -470,8 +470,8 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { // reset hand and arm positions according to hand movement glm::vec3 transformedHandMovement = _orientation.getRight() * _movedHandOffset.x * 2.0f - + _orientation.getUp() * -_movedHandOffset.y * 1.0f - + _orientation.getFront() * -_movedHandOffset.y * 1.0f; + + _orientation.getUp() * -_movedHandOffset.y * 2.0f + + _orientation.getFront() * -_movedHandOffset.y * 2.0f; _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement; From c70ade0cc1046ee62b316c606c873e107d6c41a0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 29 May 2013 12:14:45 -0700 Subject: [PATCH 23/66] temporary hack fix to not discarding voxels --- interface/src/VoxelSystem.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index ea8787a902..5e1b72e5c4 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -887,11 +887,14 @@ bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) { bool VoxelSystem::isViewChanging() { bool result = false; // assume the best + +/** TEMPORARY HACK ****** // If our viewFrustum has changed since our _lastKnowViewFrustum if (_viewFrustum && !_lastKnowViewFrustum.matches(_viewFrustum)) { result = true; _lastKnowViewFrustum = *_viewFrustum; // save last known } +**/ return result; } From c33d2ee25ef5a62f48ed6955f914ac6002513e77 Mon Sep 17 00:00:00 2001 From: Geenz Date: Wed, 29 May 2013 16:46:47 -0400 Subject: [PATCH 24/66] Coding standard cleanup based upon ZappoMan's suggestions. --- interface/src/Application.cpp | 120 ++++++++++++++++------------------ interface/src/Application.h | 12 ++-- 2 files changed, 62 insertions(+), 70 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e9b7fc0053..2a978ee17b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -778,26 +778,22 @@ void Application::wheelEvent(QWheelEvent* event) { const char AVATAR_DATA_FILENAME[] = "avatar.ifd"; -void Application::readSettingsFile() -{ +void Application::readSettingsFile() { FILE* settingsFile = fopen(AVATAR_DATA_FILENAME, "rt"); - if (settingsFile) - { + if (settingsFile) { char line[LINE_MAX]; while (fgets(line, LINE_MAX, settingsFile) != NULL) { - if (strcmp(line, " \n") > 0) - { + if (strcmp(line, " \n") > 0) { char *token = NULL; char *settingLine = NULL; char *toFree = NULL; settingLine = strdup(line); - if (settingLine != NULL) - { + if (settingLine != NULL) { toFree = settingLine; int i = 0; @@ -835,12 +831,10 @@ void Application::readSettingsFile() fclose(settingsFile); } -void Application::saveSettingsFile() -{ +void Application::saveSettingsFile() { FILE* settingsFile = fopen(AVATAR_DATA_FILENAME, "wt"); - if (settingsFile) - { + if (settingsFile) { for (std::map::iterator i = _settingsTable.begin(); i != _settingsTable.end(); i++) { fprintf(settingsFile, "\n%s=%s", i->first.data(), i->second.data()); @@ -850,109 +844,107 @@ void Application::saveSettingsFile() fclose(settingsFile); } -bool Application::getSettingBool(const char *settingName, bool &boolSetting, bool defaultSetting) -{ - if (_settingsTable[settingName] != "") - { +bool Application::getSettingBool(const char* setting, bool& value, const bool defaultSetting) const { + std::map::const_iterator iter = _settingsTable.find(setting); + + if (iter != _settingsTable.end()) { int readBool; - int res = sscanf(_settingsTable[settingName].data(), "%d", &readBool); - printLog("Found setting %d times!", res); + int res = sscanf(iter->second.data(), "%d", &readBool); - if (res == 1) - { - if (readBool == 1) - { - boolSetting = true; + const char EXPECTED_ITEMS = 1; + + if (res == EXPECTED_ITEMS) { + if (readBool == 1) { + value = true; } else if (readBool == 0) { - boolSetting = false; + value = false; } } } else { - boolSetting = defaultSetting; + value = defaultSetting; return false; } return true; } -bool Application::getSettingFloat(const char *settingName, float &floatSetting, float defaultSetting) -{ - if (_settingsTable[settingName] != "") - { +bool Application::getSettingFloat(const char* setting, float& value, const float defaultSetting) const { + std::map::const_iterator iter = _settingsTable.find(setting); + + if (iter != _settingsTable.end()) { float readFloat; - int res = sscanf(_settingsTable[settingName].data(), "%f", &readFloat); - printLog("Found setting %d times!", res); + int res = sscanf(iter->second.data(), "%f", &readFloat); - if (res == 1) - { + const char EXPECTED_ITEMS = 1; + + if (res == EXPECTED_ITEMS) { if (!isnan(readFloat)) { - floatSetting = readFloat; + value = readFloat; } else { - floatSetting = defaultSetting; + value = defaultSetting; return false; } } else { - floatSetting = defaultSetting; + value = defaultSetting; return false; } } else { - floatSetting = defaultSetting; + value = defaultSetting; return false; } return true; } -bool Application::getSettingVec3(const char *settingName, glm::vec3 &vecSetting, glm::vec3 defaultSetting) -{ - if (_settingsTable[settingName] != "") - { +bool Application::getSettingVec3(const char* setting, glm::vec3& value, const glm::vec3& defaultSetting) const { + std::map::const_iterator iter = _settingsTable.find(setting); + + if (iter != _settingsTable.end()) { glm::vec3 readVec; - int res = sscanf(_settingsTable[settingName].data(), "%f,%f,%f", &readVec.x, &readVec.y, &readVec.z); - printLog("Found setting %d times!", res); + int res = sscanf(iter->second.data(), "%f,%f,%f", &readVec.x, &readVec.y, &readVec.z); - if (res == 3) - { + const char EXPECTED_ITEMS = 3; + + if (res == EXPECTED_ITEMS) { if (!isnan(readVec.x) && !isnan(readVec.y) && !isnan(readVec.z)) { - vecSetting = readVec; + value = readVec; } else { - vecSetting = defaultSetting; + value = defaultSetting; return false; } } else { - vecSetting = defaultSetting; + value = defaultSetting; return false; } } else { - vecSetting = defaultSetting; + value = defaultSetting; return false; } return true; } -void Application::setSettingBool(const char *settingName, bool boolSetting) -{ - char setting[128]; - sprintf(setting, "%d", boolSetting); - _settingsTable[settingName] = setting; +const short MAX_SETTINGS_LENGTH = 128; + +void Application::setSettingBool(const char* setting, const bool value) { + char settingValues[MAX_SETTINGS_LENGTH]; + sprintf(settingValues, "%d", value); + _settingsTable[setting] = settingValues; } -void Application::setSettingFloat(const char *settingName, float floatSetting) -{ - char setting[128]; - sprintf(setting, "%f", floatSetting); - _settingsTable[settingName] = setting; +void Application::setSettingFloat(const char* setting, const float value) { + char settingValues[MAX_SETTINGS_LENGTH]; + sprintf(settingValues, "%f", value); + _settingsTable[setting] = settingValues; } -void Application::setSettingVec3(const char *settingName, glm::vec3 vecSetting) -{ - char setting[128]; - sprintf(setting, "%f,%f,%f", vecSetting.x, vecSetting.y, vecSetting.z); - _settingsTable[settingName] = setting; +void Application::setSettingVec3(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 diff --git a/interface/src/Application.h b/interface/src/Application.h index bde3f989d2..ffa9b4eda3 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -73,7 +73,7 @@ public: @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 getSettingBool(const char* settingName, bool &boolSetting, bool defaultSetting = false); + bool getSettingBool(const char* setting, bool &value, const bool defaultSetting = false) const; /*! @fn getSettingFloat @@ -82,7 +82,7 @@ public: @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 getSettingFloat(const char* settingName, float &floatSetting, float defaultSetting = 0.0f); + bool getSettingFloat(const char* setting, float &value, const float defaultSetting = 0.0f) const; /*! @fn getSettingVec3 @@ -91,7 +91,7 @@ public: @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 getSettingVec3(const char* settingName, glm::vec3 &vecSetting, glm::vec3 defaultSetting = glm::vec3(0.0f, 0.0f, 0.0f)); + bool getSettingVec3(const char* setting, glm::vec3 &value, const glm::vec3& defaultSetting = glm::vec3(0.0f, 0.0f, 0.0f)) const; /*! @fn setSettingBool @@ -99,7 +99,7 @@ public: @param settingName The desired setting to populate a value for. @param boolSetting The value to set. */ - void setSettingBool(const char* settingName, bool boolSetting); + void setSettingBool(const char* setting, const bool value); /*! @fn setSettingFloat @@ -107,7 +107,7 @@ public: @param settingName The desired setting to populate a value for. @param floatSetting The value to set. */ - void setSettingFloat(const char* settingName, float floatSetting); + void setSettingFloat(const char* setting, const float value); /*! @fn setSettingVec3 @@ -115,7 +115,7 @@ public: @param settingName The desired setting to populate a value for. @param vecSetting The value to set. */ - void setSettingVec3(const char* settingName, glm::vec3 vecSetting); + void setSettingVec3(const char* setting, const glm::vec3& value); private slots: From eb5375869d0d6d2443902e84f0fe74d76d0ab7c9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 14:34:58 -0700 Subject: [PATCH 25/66] also return the list of avatars to audio injectors --- avatar-mixer/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index eca698e673..3e46d698c8 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -86,7 +86,7 @@ int main(int argc, const char* argv[]) { agentList->updateAgentWithData(avatarAgent, packetData, receivedBytes); currentBufferPosition = broadcastPacket + 1; - + case PACKET_HEADER_INJECT_AUDIO: // send back a packet with other active agent data to this agent for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { if (agent->getLinkedData() && !socketMatch(agentAddress, agent->getActiveSocket())) { From 19e29585fc2afff19108bc8c92c5abeddce2d7c4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 15:04:22 -0700 Subject: [PATCH 26/66] remove some spacing at the bottom of eve main --- eve/src/main.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/eve/src/main.cpp b/eve/src/main.cpp index bf32474b33..c670be050e 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -204,6 +204,4 @@ int main(int argc, const char* argv[]) { agentList->stopDomainServerCheckInThread(); agentList->stopPingUnknownAgentsThread(); agentList->stopSilentAgentRemovalThread(); -} - - +} \ No newline at end of file From c259b025db6abfed4c300d13b25e986346d5dea1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 15:05:39 -0700 Subject: [PATCH 27/66] fix a crash in audio injector when there is no audio mixer --- libraries/audio/src/AudioInjectionManager.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioInjectionManager.cpp b/libraries/audio/src/AudioInjectionManager.cpp index 275161730e..f8fc9f742f 100644 --- a/libraries/audio/src/AudioInjectionManager.cpp +++ b/libraries/audio/src/AudioInjectionManager.cpp @@ -58,7 +58,11 @@ void* AudioInjectionManager::injectAudioViaThread(void* args) { // if we don't have an explicit destination socket then pull active socket for current audio mixer from agent list if (!_isDestinationSocketExplicit) { - _destinationSocket = *AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AUDIO_MIXER)->getActiveSocket(); + Agent* audioMixer = AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AUDIO_MIXER); + + if (audioMixer) { + _destinationSocket = *audioMixer->getActiveSocket(); + } } injector->injectAudio(_injectorSocket, &_destinationSocket); From 7611972bcaeb69148467f2529f7b4e6547601f4b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 15:06:10 -0700 Subject: [PATCH 28/66] link the avatars library to the injector target --- injector/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/injector/CMakeLists.txt b/injector/CMakeLists.txt index ba3393956a..2c022b0e92 100644 --- a/injector/CMakeLists.txt +++ b/injector/CMakeLists.txt @@ -18,4 +18,5 @@ include_glm(${TARGET_NAME} ${ROOT_DIR}) # link the shared hifi library include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) -link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file +link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR}) +link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file From 02333644dc5fc71421200725e28a7d4251c03ba7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 15:31:18 -0700 Subject: [PATCH 29/66] one line fix in AvatarTouch --- interface/src/AvatarTouch.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 93899c8400..644c802d1f 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -54,8 +54,7 @@ void AvatarTouch::simulate (float deltaTime) { facingEachOther = true; } - if ((distanceBetweenBodies < _reachableRadius) - && (facingEachOther)) { + if (distanceBetweenBodies < _reachableRadius) { _canReachToOtherAvatar = true; _vectorBetweenHands = _yourHandPosition - _myHandPosition; From 1fcf787991f6caa782c6c6244ece347017a8c3ed Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 29 May 2013 15:42:29 -0700 Subject: [PATCH 30/66] dance floor --- animation-server/src/main.cpp | 108 +++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index a26b1a4674..1922864632 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -33,6 +33,7 @@ bool includeBillboard = true; bool includeBorderTracer = true; bool includeMovingBug = true; bool includeBlinkingVoxel = false; +bool includeDanceFloor = true; const int ANIMATION_LISTEN_PORT = 40107; @@ -392,6 +393,105 @@ static void sendBlinkingStringOfLights() { } } +bool danceFloorInitialized = false; +const float DANCE_FLOOR_LIGHT_SIZE = 1.0f / TREE_SCALE; // approximately 1 meter +const int DANCE_FLOOR_LENGTH = 10; +const int DANCE_FLOOR_WIDTH = 10; +//const int DANCE_FLOOR_HEIGHT = 10; +glm::vec3 danceFloorPosition(100.0f / TREE_SCALE, 30.0f / TREE_SCALE, 10.0f / TREE_SCALE); //(1.0f - (DANCE_FLOOR_WIDTH * DANCE_FLOOR_LIGHT_SIZE), 0, 0); +glm::vec3 danceFloorLights[DANCE_FLOOR_LENGTH][DANCE_FLOOR_WIDTH]; +unsigned char danceFloorOffColor[3] = { 240, 240, 240 }; +unsigned char danceFloorOnColorA[3] = { 0, 0, 255 }; +unsigned char danceFloorOnColorB[3] = { 0, 255, 0 }; +float danceFloorGradient = 0.5f; +float danceFloorGradientIncrement = 0.01f; +const float DANCE_FLOOR_MAX_GRADIENT = 1.0f; +const float DANCE_FLOOR_MIN_GRADIENT = 0.0f; +const int DANCE_FLOOR_VOXELS_PER_PACKET = 100; +const int PACKETS_PER_DANCE_FLOOR = DANCE_FLOOR_VOXELS_PER_PACKET / (DANCE_FLOOR_WIDTH * DANCE_FLOOR_LENGTH); +bool danceFloorColors[DANCE_FLOOR_WIDTH][DANCE_FLOOR_LENGTH] = { + { 0,1,0,1,0,1,0,1,0,1 }, + { 1,0,1,0,1,0,1,0,1,0 }, + { 0,1,0,1,0,1,0,1,0,1 }, + { 1,0,1,0,1,0,1,0,1,0 }, + { 0,1,0,1,0,1,0,1,0,1 }, + { 1,0,1,0,1,0,1,0,1,0 }, + { 0,1,0,1,0,1,0,1,0,1 }, + { 1,0,1,0,1,0,1,0,1,0 }, + { 0,1,0,1,0,1,0,1,0,1 }, + { 1,0,1,0,1,0,1,0,1,0 }, +}; + + +void sendDanceFloor() { + PACKET_HEADER message = PACKET_HEADER_SET_VOXEL_DESTRUCTIVE; // we're a bully! + float lightScale = DANCE_FLOOR_LIGHT_SIZE; + static VoxelDetail details[DANCE_FLOOR_VOXELS_PER_PACKET]; + unsigned char* bufferOut; + int sizeOut; + + // first initialized the billboard of lights if needed... + if (!danceFloorInitialized) { + for (int i = 0; i < DANCE_FLOOR_WIDTH; i++) { + for (int j = 0; j < DANCE_FLOOR_LENGTH; j++) { + danceFloorLights[i][j] = danceFloorPosition + glm::vec3(i * DANCE_FLOOR_LIGHT_SIZE, 0, j * DANCE_FLOOR_LIGHT_SIZE); + } + } + danceFloorInitialized = true; + } + + ::danceFloorGradient += ::danceFloorGradientIncrement; + + if (::danceFloorGradient >= DANCE_FLOOR_MAX_GRADIENT) { + ::danceFloorGradient = DANCE_FLOOR_MAX_GRADIENT; + ::danceFloorGradientIncrement = -::danceFloorGradientIncrement; + } + if (::danceFloorGradient <= DANCE_FLOOR_MIN_GRADIENT) { + ::danceFloorGradient = DANCE_FLOOR_MIN_GRADIENT; + ::danceFloorGradientIncrement = -::danceFloorGradientIncrement; + } + + for (int i = 0; i < DANCE_FLOOR_LENGTH; i++) { + for (int j = 0; j < DANCE_FLOOR_WIDTH; j++) { + + int nthVoxel = ((i * DANCE_FLOOR_WIDTH) + j); + int item = nthVoxel % DANCE_FLOOR_VOXELS_PER_PACKET; + + danceFloorLights[i][j] = danceFloorPosition + glm::vec3(i * DANCE_FLOOR_LIGHT_SIZE, 0, j * DANCE_FLOOR_LIGHT_SIZE); + + //printf("danceFloorLights[%d][%d] = %f,%f,%f\n",i,j, danceFloorLights[i][j].x, danceFloorLights[i][j].y, danceFloorLights[i][j].z); + + + details[item].s = lightScale; + details[item].x = danceFloorLights[i][j].x; + details[item].y = danceFloorLights[i][j].y; + details[item].z = danceFloorLights[i][j].z; + + if (danceFloorColors[i][j]) { + details[item].red = (danceFloorOnColorA[0] + ((danceFloorOnColorB[0] - danceFloorOnColorA[0]) * ::danceFloorGradient)); + details[item].green = (danceFloorOnColorA[1] + ((danceFloorOnColorB[1] - danceFloorOnColorA[1]) * ::danceFloorGradient)); + details[item].blue = (danceFloorOnColorA[2] + ((danceFloorOnColorB[2] - danceFloorOnColorA[2]) * ::danceFloorGradient)); + } else { + details[item].red = danceFloorOffColor[0]; + details[item].green = danceFloorOffColor[1]; + details[item].blue = danceFloorOffColor[2]; + } + + if (item == DANCE_FLOOR_VOXELS_PER_PACKET - 1) { + if (createVoxelEditMessage(message, 0, DANCE_FLOOR_VOXELS_PER_PACKET, (VoxelDetail*)&details, bufferOut, sizeOut)){ + ::packetsSent++; + ::bytesSent += sizeOut; + if (::shouldShowPacketsPerSecond) { + printf("sending packet of size=%d\n", sizeOut); + } + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + delete[] bufferOut; + } + } + } + } +} + bool billboardInitialized = false; const int BILLBOARD_HEIGHT = 9; const int BILLBOARD_WIDTH = 45; @@ -405,7 +505,7 @@ float billboardGradientIncrement = 0.01f; const float BILLBOARD_MAX_GRADIENT = 1.0f; const float BILLBOARD_MIN_GRADIENT = 0.0f; const float BILLBOARD_LIGHT_SIZE = 0.125f / TREE_SCALE; // approximately 1/8 meter per light -const int VOXELS_PER_PACKET = 135; +const int VOXELS_PER_PACKET = 100; const int PACKETS_PER_BILLBOARD = VOXELS_PER_PACKET / (BILLBOARD_HEIGHT * BILLBOARD_WIDTH); @@ -514,6 +614,9 @@ void* animateVoxels(void* args) { if (::includeBlinkingVoxel) { sendVoxelBlinkMessage(); } + if (::includeDanceFloor) { + sendDanceFloor(); + } double end = usecTimestampNow(); double elapsedSeconds = (end - ::start) / 1000000.0; @@ -555,6 +658,9 @@ int main(int argc, const char * argv[]) const char* INCLUDE_BLINKING_VOXEL = "--includeBlinkingVoxel"; ::includeBlinkingVoxel = cmdOptionExists(argc, argv, INCLUDE_BLINKING_VOXEL); + const char* NO_DANCE_FLOOR = "--NoDanceFloor"; + ::includeDanceFloor = !cmdOptionExists(argc, argv, NO_DANCE_FLOOR); + // Handle Local Domain testing with the --local command line const char* showPPS = "--showPPS"; ::shouldShowPacketsPerSecond = cmdOptionExists(argc, argv, showPPS); From c0a9914efdc20b88839fa75f3578900ce1f58228 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 16:03:32 -0700 Subject: [PATCH 31/66] add trigger based firing to audio injector --- injector/src/main.cpp | 168 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 139 insertions(+), 29 deletions(-) diff --git a/injector/src/main.cpp b/injector/src/main.cpp index df751f50a1..32a8442d8f 100644 --- a/injector/src/main.cpp +++ b/injector/src/main.cpp @@ -14,14 +14,16 @@ #include #include +#include +#include +#include #include #include #include #include #include -char EC2_WEST_AUDIO_SERVER[] = "54.241.92.53"; -const int AUDIO_UDP_LISTEN_PORT = 55443; +const int AVATAR_MIXER_DATA_SEND_INTERVAL_MSECS = 15; const int DEFAULT_INJECTOR_VOLUME = 0xFF; @@ -30,12 +32,12 @@ bool loopAudio = true; float sleepIntervalMin = 1.00; float sleepIntervalMax = 2.00; char *sourceAudioFile = NULL; -const char *allowedParameters = ":rb::t::c::a::f:"; +const char *allowedParameters = ":rb::t::c::a::f::d:"; float floatArguments[4] = {0.0f, 0.0f, 0.0f, 0.0f}; unsigned char volume = DEFAULT_INJECTOR_VOLUME; +float triggerDistance = 0; -void usage(void) -{ +void usage(void) { std::cout << "High Fidelity - Interface audio injector" << std::endl; std::cout << " -r Random sleep mode. If not specified will default to constant loop." << std::endl; std::cout << " -b FLOAT Min. number of seconds to sleep. Only valid in random sleep mode. Default 1.0" << std::endl; @@ -43,10 +45,10 @@ void usage(void) std::cout << " -c FLOAT,FLOAT,FLOAT,FLOAT X,Y,Z,YAW position in universe where audio will be originating from and direction. Defaults to 0,0,0,0" << std::endl; std::cout << " -a 0-255 Attenuation curve modifier, defaults to 255" << std::endl; std::cout << " -f FILENAME Name of audio source file. Required - RAW format, 22050hz 16bit signed mono" << std::endl; + std::cout << " -d FLOAT Trigger distance for injection. If not specified will loop constantly" << std::endl; } -bool processParameters(int parameterCount, char* parameterData[]) -{ +bool processParameters(int parameterCount, char* parameterData[]) { int p; while ((p = getopt(parameterCount, parameterData, allowedParameters)) != -1) { switch (p) { @@ -86,6 +88,10 @@ bool processParameters(int parameterCount, char* parameterData[]) ::volume = atoi(optarg); std::cout << "[DEBUG] Attenuation modifier: " << optarg << std::endl; break; + case 'd': + ::triggerDistance = atof(optarg); + std::cout << "[DEBUG] Trigger distance: " << optarg << std::endl; + break; default: usage(); return false; @@ -94,45 +100,149 @@ bool processParameters(int parameterCount, char* parameterData[]) return true; }; -int main(int argc, char* argv[]) { +bool stopReceiveAgentDataThread; +void *receiveAgentData(void *args) { + sockaddr senderAddress; + ssize_t bytesReceived; + unsigned char incomingPacket[MAX_PACKET_SIZE]; + + AgentList* agentList = AgentList::getInstance(); + + while (!::stopReceiveAgentDataThread) { + if (agentList->getAgentSocket()->receive(&senderAddress, incomingPacket, &bytesReceived)) { + switch (incomingPacket[0]) { + case PACKET_HEADER_BULK_AVATAR_DATA: + // this is the positional data for other agents + // pass that off to the agentList processBulkAgentData method + agentList->processBulkAgentData(&senderAddress, incomingPacket, bytesReceived); + break; + default: + // have the agentList handle list of agents from DS, replies from other agents, etc. + agentList->processAgentData(&senderAddress, incomingPacket, bytesReceived); + break; + } + } + } + + pthread_exit(0); + return NULL; +} + +void createAvatarDataForAgent(Agent* agent) { + if (!agent->getLinkedData()) { + agent->setLinkedData(new AvatarData(agent)); + } +} + +int main(int argc, char* argv[]) { + // new seed for random audio sleep times srand(time(0)); + int AUDIO_UDP_SEND_PORT = 1500 + (rand() % (int)(1500 - 2000 + 1)); - UDPSocket streamSocket(AUDIO_UDP_SEND_PORT); - - sockaddr_in mixerSocket; - mixerSocket.sin_family = AF_INET; - mixerSocket.sin_addr.s_addr = inet_addr(EC2_WEST_AUDIO_SERVER); - mixerSocket.sin_port = htons((uint16_t)AUDIO_UDP_LISTEN_PORT); - - - if (processParameters(argc, argv)) { + if (processParameters(argc, argv)) { if (::sourceAudioFile == NULL) { std::cout << "[FATAL] Source audio file not specified" << std::endl; exit(-1); } else { AudioInjector injector(sourceAudioFile); + // create an AgentList instance to handle communication with other agents + AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AUDIO_INJECTOR, AUDIO_UDP_SEND_PORT); + + pthread_t receiveAgentDataThread; + pthread_create(&receiveAgentDataThread, NULL, receiveAgentData, NULL); + + // start telling the domain server that we are alive + agentList->startDomainServerCheckInThread(); + + // start the agent list thread that will kill off agents when they stop talking + agentList->startSilentAgentRemovalThread(); + injector.setPosition(glm::vec3(::floatArguments[0], ::floatArguments[1], ::floatArguments[2])); injector.setBearing(*(::floatArguments + 3)); injector.setVolume(::volume); - - float delay = 0; - int usecDelay = 0; + + // register the callback for agent data creation + agentList->linkedDataCreateCallback = createAvatarDataForAgent; + + unsigned char broadcastPacket = PACKET_HEADER_INJECT_AUDIO; + + timeval thisSend; + double numMicrosecondsSleep = 0; while (true) { - injector.injectAudio(&streamSocket, (sockaddr*) &mixerSocket); - - if (!::loopAudio) { - delay = randFloatInRange(::sleepIntervalMin, ::sleepIntervalMax); - usecDelay = delay * 1000 * 1000; - usleep(usecDelay); + if (::triggerDistance) { + + // update the thisSend timeval to the current time + gettimeofday(&thisSend, NULL); + + // find the current avatar mixer + Agent* avatarMixer = agentList->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER); + + // make sure we actually have an avatar mixer with an active socket + if (avatarMixer && avatarMixer->getActiveSocket() != NULL) { + // use the UDPSocket instance attached to our agent list to ask avatar mixer for a list of avatars + agentList->getAgentSocket()->send(avatarMixer->getActiveSocket(), + &broadcastPacket, + sizeof(broadcastPacket)); + } + + if (!injector.isInjectingAudio()) { + // enumerate the other agents to decide if one is close enough that we should inject + for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { + AvatarData* avatarData = (AvatarData*) agent->getLinkedData(); + + if (avatarData) { + glm::vec3 tempVector = injector.getPosition() - avatarData->getPosition(); + float squareDistance = glm::dot(tempVector, tempVector); + + if (squareDistance <= ::triggerDistance) { + // look for an audio mixer in our agent list + Agent* audioMixer = AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AUDIO_MIXER); + + if (audioMixer) { + // we have an active audio mixer we can send data to + AudioInjectionManager::threadInjector(&injector); + } + } + } + } + } + + // sleep for the correct amount of time to have data send be consistently timed + if ((numMicrosecondsSleep = (AVATAR_MIXER_DATA_SEND_INTERVAL_MSECS * 1000) - + (usecTimestampNow() - usecTimestamp(&thisSend))) > 0) { + usleep(numMicrosecondsSleep); + } + } else { + // look for an audio mixer in our agent list + Agent* audioMixer = AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AUDIO_MIXER); + + if (audioMixer) { + injector.injectAudio(agentList->getAgentSocket(), audioMixer->getActiveSocket()); + } + + float delay = 0; + int usecDelay = 0; + + if (!::loopAudio) { + delay = randFloatInRange(::sleepIntervalMin, ::sleepIntervalMax); + usecDelay = delay * 1000 * 1000; + usleep(usecDelay); + } } } - } + + // stop the receive agent data thread + stopReceiveAgentDataThread = true; + pthread_join(receiveAgentDataThread, NULL); + + // stop the agent list's threads + agentList->stopDomainServerCheckInThread(); + agentList->stopSilentAgentRemovalThread(); + } } - return 0; } - From b0a8de818d8f08968b85fad1933fda345c88662c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 16:05:03 -0700 Subject: [PATCH 32/66] make quit CMD-Q instead of just Q --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f307efa470..bf68798d62 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1122,7 +1122,7 @@ void Application::initMenu() { _window->setMenuBar(menuBar); QMenu* fileMenu = menuBar->addMenu("File"); - fileMenu->addAction("Quit", this, SLOT(quit()), Qt::Key_Q); + fileMenu->addAction("Quit", this, SLOT(quit()), (Qt::Key_Q || Qt::Key_Control)); QMenu* pairMenu = menuBar->addMenu("Pair"); pairMenu->addAction("Pair", this, SLOT(pair())); From 089dc3669d80d3dd11b7ada6cc6ed8376e8d5c17 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 16:37:40 -0700 Subject: [PATCH 33/66] push the mouth out in front of the face --- interface/src/Head.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 6f7f330010..65d6c71860 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -354,7 +354,9 @@ void Head::renderMouth() { glm::vec3 rightBottom = _mouthPosition + r * 0.4f - u * 1.0f + f * 0.7f; // constrain all mouth vertices to a sphere slightly larger than the head... - float constrainedRadius = _scale + 0.001f; + const float MOUTH_OFFSET_OFF_FACE = 0.003f; + + float constrainedRadius = _scale + MOUTH_OFFSET_OFF_FACE; middle = _position + glm::normalize(middle - _position) * constrainedRadius; leftCorner = _position + glm::normalize(leftCorner - _position) * constrainedRadius; rightCorner = _position + glm::normalize(rightCorner - _position) * constrainedRadius; From bb3feb13eb03512604556f81b3768e96adbdf1e1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 16:57:13 -0700 Subject: [PATCH 34/66] correct the currentBufferPosition for injector packets as well --- avatar-mixer/src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index 3e46d698c8..89861ddcc8 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -84,9 +84,9 @@ int main(int argc, const char* argv[]) { // parse positional data from an agent agentList->updateAgentWithData(avatarAgent, packetData, receivedBytes); - - currentBufferPosition = broadcastPacket + 1; case PACKET_HEADER_INJECT_AUDIO: + currentBufferPosition = broadcastPacket + 1; + // send back a packet with other active agent data to this agent for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { if (agent->getLinkedData() && !socketMatch(agentAddress, agent->getActiveSocket())) { From ffffa71d1a6f2f85462787f9c73b5bc70aac255f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 29 May 2013 16:58:17 -0700 Subject: [PATCH 35/66] new floor --- animation-server/src/main.cpp | 76 +++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index 1922864632..35dc4be7cf 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -397,31 +397,29 @@ bool danceFloorInitialized = false; const float DANCE_FLOOR_LIGHT_SIZE = 1.0f / TREE_SCALE; // approximately 1 meter const int DANCE_FLOOR_LENGTH = 10; const int DANCE_FLOOR_WIDTH = 10; -//const int DANCE_FLOOR_HEIGHT = 10; -glm::vec3 danceFloorPosition(100.0f / TREE_SCALE, 30.0f / TREE_SCALE, 10.0f / TREE_SCALE); //(1.0f - (DANCE_FLOOR_WIDTH * DANCE_FLOOR_LIGHT_SIZE), 0, 0); +glm::vec3 danceFloorPosition(100.0f / TREE_SCALE, 30.0f / TREE_SCALE, 10.0f / TREE_SCALE); glm::vec3 danceFloorLights[DANCE_FLOOR_LENGTH][DANCE_FLOOR_WIDTH]; unsigned char danceFloorOffColor[3] = { 240, 240, 240 }; -unsigned char danceFloorOnColorA[3] = { 0, 0, 255 }; -unsigned char danceFloorOnColorB[3] = { 0, 255, 0 }; +const int DANCE_FLOOR_COLORS = 6; + +unsigned char danceFloorOnColorA[DANCE_FLOOR_COLORS][3] = { + { 255, 0, 0 }, { 0, 255, 0 }, { 0, 0, 255 }, + { 0, 191, 255 }, { 0, 250, 154 }, { 255, 69, 0 }, +}; +unsigned char danceFloorOnColorB[DANCE_FLOOR_COLORS][3] = { + { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } , + { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } +}; float danceFloorGradient = 0.5f; -float danceFloorGradientIncrement = 0.01f; +const float BEATS_PER_MINUTE = 118.0f; +const float SECONDS_PER_MINUTE = 60.0f; +const float FRAMES_PER_BEAT = (SECONDS_PER_MINUTE * ACTUAL_FPS) / BEATS_PER_MINUTE; +float danceFloorGradientIncrement = 1.0f/FRAMES_PER_BEAT; const float DANCE_FLOOR_MAX_GRADIENT = 1.0f; const float DANCE_FLOOR_MIN_GRADIENT = 0.0f; const int DANCE_FLOOR_VOXELS_PER_PACKET = 100; const int PACKETS_PER_DANCE_FLOOR = DANCE_FLOOR_VOXELS_PER_PACKET / (DANCE_FLOOR_WIDTH * DANCE_FLOOR_LENGTH); -bool danceFloorColors[DANCE_FLOOR_WIDTH][DANCE_FLOOR_LENGTH] = { - { 0,1,0,1,0,1,0,1,0,1 }, - { 1,0,1,0,1,0,1,0,1,0 }, - { 0,1,0,1,0,1,0,1,0,1 }, - { 1,0,1,0,1,0,1,0,1,0 }, - { 0,1,0,1,0,1,0,1,0,1 }, - { 1,0,1,0,1,0,1,0,1,0 }, - { 0,1,0,1,0,1,0,1,0,1 }, - { 1,0,1,0,1,0,1,0,1,0 }, - { 0,1,0,1,0,1,0,1,0,1 }, - { 1,0,1,0,1,0,1,0,1,0 }, -}; - +int danceFloorColors[DANCE_FLOOR_WIDTH][DANCE_FLOOR_LENGTH]; void sendDanceFloor() { PACKET_HEADER message = PACKET_HEADER_SET_VOXEL_DESTRUCTIVE; // we're a bully! @@ -434,7 +432,11 @@ void sendDanceFloor() { if (!danceFloorInitialized) { for (int i = 0; i < DANCE_FLOOR_WIDTH; i++) { for (int j = 0; j < DANCE_FLOOR_LENGTH; j++) { - danceFloorLights[i][j] = danceFloorPosition + glm::vec3(i * DANCE_FLOOR_LIGHT_SIZE, 0, j * DANCE_FLOOR_LIGHT_SIZE); + + int randomColorIndex = randIntInRange( -(DANCE_FLOOR_COLORS), (DANCE_FLOOR_COLORS + 1)); + danceFloorColors[i][j] = randomColorIndex; + danceFloorLights[i][j] = danceFloorPosition + + glm::vec3(i * DANCE_FLOOR_LIGHT_SIZE, 0, j * DANCE_FLOOR_LIGHT_SIZE); } } danceFloorInitialized = true; @@ -459,26 +461,40 @@ void sendDanceFloor() { danceFloorLights[i][j] = danceFloorPosition + glm::vec3(i * DANCE_FLOOR_LIGHT_SIZE, 0, j * DANCE_FLOOR_LIGHT_SIZE); - //printf("danceFloorLights[%d][%d] = %f,%f,%f\n",i,j, danceFloorLights[i][j].x, danceFloorLights[i][j].y, danceFloorLights[i][j].z); - - details[item].s = lightScale; details[item].x = danceFloorLights[i][j].x; details[item].y = danceFloorLights[i][j].y; details[item].z = danceFloorLights[i][j].z; - if (danceFloorColors[i][j]) { - details[item].red = (danceFloorOnColorA[0] + ((danceFloorOnColorB[0] - danceFloorOnColorA[0]) * ::danceFloorGradient)); - details[item].green = (danceFloorOnColorA[1] + ((danceFloorOnColorB[1] - danceFloorOnColorA[1]) * ::danceFloorGradient)); - details[item].blue = (danceFloorOnColorA[2] + ((danceFloorOnColorB[2] - danceFloorOnColorA[2]) * ::danceFloorGradient)); + if (danceFloorColors[i][j] > 0) { + int color = danceFloorColors[i][j] - 1; + details[item].red = (danceFloorOnColorA[color][0] + + ((danceFloorOnColorB[color][0] - danceFloorOnColorA[color][0]) * ::danceFloorGradient)); + details[item].green = (danceFloorOnColorA[color][1] + + ((danceFloorOnColorB[color][1] - danceFloorOnColorA[color][1]) * ::danceFloorGradient)); + details[item].blue = (danceFloorOnColorA[color][2] + + ((danceFloorOnColorB[color][2] - danceFloorOnColorA[color][2]) * ::danceFloorGradient)); + } else if (danceFloorColors[i][j] < 0) { + int color = -(danceFloorColors[i][j] + 1); + details[item].red = (danceFloorOnColorB[color][0] + + ((danceFloorOnColorA[color][0] - danceFloorOnColorB[color][0]) * ::danceFloorGradient)); + details[item].green = (danceFloorOnColorB[color][1] + + ((danceFloorOnColorA[color][1] - danceFloorOnColorB[color][1]) * ::danceFloorGradient)); + details[item].blue = (danceFloorOnColorB[color][2] + + ((danceFloorOnColorA[color][2] - danceFloorOnColorB[color][2]) * ::danceFloorGradient)); } else { - details[item].red = danceFloorOffColor[0]; - details[item].green = danceFloorOffColor[1]; - details[item].blue = danceFloorOffColor[2]; + int color = 0; + details[item].red = (danceFloorOnColorB[color][0] + + ((danceFloorOnColorA[color][0] - danceFloorOnColorB[color][0]) * ::danceFloorGradient)); + details[item].green = (danceFloorOnColorB[color][1] + + ((danceFloorOnColorA[color][1] - danceFloorOnColorB[color][1]) * ::danceFloorGradient)); + details[item].blue = (danceFloorOnColorB[color][2] + + ((danceFloorOnColorA[color][2] - danceFloorOnColorB[color][2]) * ::danceFloorGradient)); } if (item == DANCE_FLOOR_VOXELS_PER_PACKET - 1) { - if (createVoxelEditMessage(message, 0, DANCE_FLOOR_VOXELS_PER_PACKET, (VoxelDetail*)&details, bufferOut, sizeOut)){ + if (createVoxelEditMessage(message, 0, DANCE_FLOOR_VOXELS_PER_PACKET, + (VoxelDetail*)&details, bufferOut, sizeOut)){ ::packetsSent++; ::bytesSent += sizeOut; if (::shouldShowPacketsPerSecond) { From 871cddfcc113670fd7b2547eec8ef237ec0d5660 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 29 May 2013 17:05:22 -0700 Subject: [PATCH 36/66] coding standard cleanup --- animation-server/src/main.cpp | 66 ++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index 35dc4be7cf..80336a767c 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -429,17 +429,17 @@ void sendDanceFloor() { int sizeOut; // first initialized the billboard of lights if needed... - if (!danceFloorInitialized) { + if (!::danceFloorInitialized) { for (int i = 0; i < DANCE_FLOOR_WIDTH; i++) { for (int j = 0; j < DANCE_FLOOR_LENGTH; j++) { int randomColorIndex = randIntInRange( -(DANCE_FLOOR_COLORS), (DANCE_FLOOR_COLORS + 1)); - danceFloorColors[i][j] = randomColorIndex; - danceFloorLights[i][j] = danceFloorPosition + + ::danceFloorColors[i][j] = randomColorIndex; + ::danceFloorLights[i][j] = ::danceFloorPosition + glm::vec3(i * DANCE_FLOOR_LIGHT_SIZE, 0, j * DANCE_FLOOR_LIGHT_SIZE); } } - danceFloorInitialized = true; + ::danceFloorInitialized = true; } ::danceFloorGradient += ::danceFloorGradientIncrement; @@ -459,37 +459,47 @@ void sendDanceFloor() { int nthVoxel = ((i * DANCE_FLOOR_WIDTH) + j); int item = nthVoxel % DANCE_FLOOR_VOXELS_PER_PACKET; - danceFloorLights[i][j] = danceFloorPosition + glm::vec3(i * DANCE_FLOOR_LIGHT_SIZE, 0, j * DANCE_FLOOR_LIGHT_SIZE); + ::danceFloorLights[i][j] = ::danceFloorPosition + + glm::vec3(i * DANCE_FLOOR_LIGHT_SIZE, 0, j * DANCE_FLOOR_LIGHT_SIZE); details[item].s = lightScale; - details[item].x = danceFloorLights[i][j].x; - details[item].y = danceFloorLights[i][j].y; - details[item].z = danceFloorLights[i][j].z; + details[item].x = ::danceFloorLights[i][j].x; + details[item].y = ::danceFloorLights[i][j].y; + details[item].z = ::danceFloorLights[i][j].z; if (danceFloorColors[i][j] > 0) { int color = danceFloorColors[i][j] - 1; - details[item].red = (danceFloorOnColorA[color][0] + - ((danceFloorOnColorB[color][0] - danceFloorOnColorA[color][0]) * ::danceFloorGradient)); - details[item].green = (danceFloorOnColorA[color][1] + - ((danceFloorOnColorB[color][1] - danceFloorOnColorA[color][1]) * ::danceFloorGradient)); - details[item].blue = (danceFloorOnColorA[color][2] + - ((danceFloorOnColorB[color][2] - danceFloorOnColorA[color][2]) * ::danceFloorGradient)); - } else if (danceFloorColors[i][j] < 0) { - int color = -(danceFloorColors[i][j] + 1); - details[item].red = (danceFloorOnColorB[color][0] + - ((danceFloorOnColorA[color][0] - danceFloorOnColorB[color][0]) * ::danceFloorGradient)); - details[item].green = (danceFloorOnColorB[color][1] + - ((danceFloorOnColorA[color][1] - danceFloorOnColorB[color][1]) * ::danceFloorGradient)); - details[item].blue = (danceFloorOnColorB[color][2] + - ((danceFloorOnColorA[color][2] - danceFloorOnColorB[color][2]) * ::danceFloorGradient)); + details[item].red = (::danceFloorOnColorA[color][0] + + ((::danceFloorOnColorB[color][0] - ::danceFloorOnColorA[color][0]) + * ::danceFloorGradient)); + details[item].green = (::danceFloorOnColorA[color][1] + + ((::danceFloorOnColorB[color][1] - ::danceFloorOnColorA[color][1]) + * ::danceFloorGradient)); + details[item].blue = (::danceFloorOnColorA[color][2] + + ((::danceFloorOnColorB[color][2] - ::danceFloorOnColorA[color][2]) + * ::danceFloorGradient)); + } else if (::danceFloorColors[i][j] < 0) { + int color = -(::danceFloorColors[i][j] + 1); + details[item].red = (::danceFloorOnColorB[color][0] + + ((::danceFloorOnColorA[color][0] - ::danceFloorOnColorB[color][0]) + * ::danceFloorGradient)); + details[item].green = (::danceFloorOnColorB[color][1] + + ((::danceFloorOnColorA[color][1] - ::danceFloorOnColorB[color][1]) + * ::danceFloorGradient)); + details[item].blue = (::danceFloorOnColorB[color][2] + + ((::danceFloorOnColorA[color][2] - ::danceFloorOnColorB[color][2]) + * ::danceFloorGradient)); } else { int color = 0; - details[item].red = (danceFloorOnColorB[color][0] + - ((danceFloorOnColorA[color][0] - danceFloorOnColorB[color][0]) * ::danceFloorGradient)); - details[item].green = (danceFloorOnColorB[color][1] + - ((danceFloorOnColorA[color][1] - danceFloorOnColorB[color][1]) * ::danceFloorGradient)); - details[item].blue = (danceFloorOnColorB[color][2] + - ((danceFloorOnColorA[color][2] - danceFloorOnColorB[color][2]) * ::danceFloorGradient)); + details[item].red = (::danceFloorOnColorB[color][0] + + ((::danceFloorOnColorA[color][0] - ::danceFloorOnColorB[color][0]) + * ::danceFloorGradient)); + details[item].green = (::danceFloorOnColorB[color][1] + + ((::danceFloorOnColorA[color][1] - ::danceFloorOnColorB[color][1]) + * ::danceFloorGradient)); + details[item].blue = (::danceFloorOnColorB[color][2] + + ((::danceFloorOnColorA[color][2] - ::danceFloorOnColorB[color][2]) + * ::danceFloorGradient)); } if (item == DANCE_FLOOR_VOXELS_PER_PACKET - 1) { From 49f4df3a5edf83e9794f01bde81d58941fc52749 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 29 May 2013 17:07:12 -0700 Subject: [PATCH 37/66] coding standard cleanup --- animation-server/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index 80336a767c..32a6393525 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -414,7 +414,7 @@ float danceFloorGradient = 0.5f; const float BEATS_PER_MINUTE = 118.0f; const float SECONDS_PER_MINUTE = 60.0f; const float FRAMES_PER_BEAT = (SECONDS_PER_MINUTE * ACTUAL_FPS) / BEATS_PER_MINUTE; -float danceFloorGradientIncrement = 1.0f/FRAMES_PER_BEAT; +float danceFloorGradientIncrement = 1.0f / FRAMES_PER_BEAT; const float DANCE_FLOOR_MAX_GRADIENT = 1.0f; const float DANCE_FLOOR_MIN_GRADIENT = 0.0f; const int DANCE_FLOOR_VOXELS_PER_PACKET = 100; From 1b2b0afe3a0ff119d28459ff8303c81068e44678 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 17:32:32 -0700 Subject: [PATCH 38/66] tune the distance attenuation on audio-mixer --- audio-mixer/src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 9204e39b8e..3d1690e39a 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -55,7 +55,7 @@ const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES_PER_CHANNEL / SA const long MAX_SAMPLE_VALUE = std::numeric_limits::max(); const long MIN_SAMPLE_VALUE = std::numeric_limits::min(); -const float DISTANCE_RATIO = 3.0f / 0.3f; +const float DISTANCE_SCALE = 5.0f; const float PHASE_AMPLITUDE_RATIO_AT_90 = 0.5; const int PHASE_DELAY_AT_90 = 20; @@ -166,8 +166,8 @@ int main(int argc, const char* argv[]) { powf(agentPosition.z - otherAgentPosition.z, 2)); float minCoefficient = std::min(1.0f, - powf(0.5, - (logf(DISTANCE_RATIO * distanceToAgent) / logf(2.5)) + powf(0.3, + (logf(DISTANCE_SCALE * distanceToAgent) / logf(2.5)) - 1)); distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient; } From a3942a072f2c2057f40fe8a765a656c910f49e50 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 17:38:00 -0700 Subject: [PATCH 39/66] more tuning on distance attenuation for audio mixer --- audio-mixer/src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 3d1690e39a..05ecaa1ed6 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -55,7 +55,7 @@ const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES_PER_CHANNEL / SA const long MAX_SAMPLE_VALUE = std::numeric_limits::max(); const long MIN_SAMPLE_VALUE = std::numeric_limits::min(); -const float DISTANCE_SCALE = 5.0f; +const float DISTANCE_SCALE = 2.5f; const float PHASE_AMPLITUDE_RATIO_AT_90 = 0.5; const int PHASE_DELAY_AT_90 = 20; @@ -166,7 +166,7 @@ int main(int argc, const char* argv[]) { powf(agentPosition.z - otherAgentPosition.z, 2)); float minCoefficient = std::min(1.0f, - powf(0.3, + powf(0.4, (logf(DISTANCE_SCALE * distanceToAgent) / logf(2.5)) - 1)); distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient; From 8ba23bc027241cd594065e0e408cfa13ffc2177d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 17:46:54 -0700 Subject: [PATCH 40/66] tune distance attenuation --- audio-mixer/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 05ecaa1ed6..982ebc526c 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -166,7 +166,7 @@ int main(int argc, const char* argv[]) { powf(agentPosition.z - otherAgentPosition.z, 2)); float minCoefficient = std::min(1.0f, - powf(0.4, + powf(0.3, (logf(DISTANCE_SCALE * distanceToAgent) / logf(2.5)) - 1)); distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient; From 1f4e9f305117ba2b2273381821170bff2a6f4faf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 May 2013 18:36:31 -0700 Subject: [PATCH 41/66] update last heard from time for audio injectors --- libraries/shared/src/AgentList.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 170b86147b..2b28ac620d 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -250,7 +250,8 @@ Agent* AgentList::addOrUpdateAgent(sockaddr* publicSocket, sockaddr* localSocket if (agent->getType() == AGENT_TYPE_AUDIO_MIXER || agent->getType() == AGENT_TYPE_VOXEL || - agent->getType() == AGENT_TYPE_ANIMATION_SERVER) { + agent->getType() == AGENT_TYPE_ANIMATION_SERVER || + agent->getType() == AGENT_TYPE_AUDIO_INJECTOR) { // until the Audio class also uses our agentList, we need to update // the lastRecvTimeUsecs for the audio mixer so it doesn't get killed and re-added continously agent->setLastHeardMicrostamp(usecTimestampNow()); From d6855b643078e5888daa6fbe002979161281ca64 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 29 May 2013 19:05:33 -0700 Subject: [PATCH 42/66] Massive changes to orientations: use quaternions rather than Orientation class. --- interface/src/Application.cpp | 57 ++---- interface/src/Avatar.cpp | 294 ++++++++++++++------------- interface/src/Avatar.h | 50 ++--- interface/src/AvatarTouch.cpp | 9 +- interface/src/AvatarTouch.h | 8 +- interface/src/Camera.cpp | 51 +---- interface/src/Camera.h | 25 +-- interface/src/Environment.cpp | 2 +- interface/src/Head.cpp | 136 +++++++------ interface/src/Head.h | 15 +- interface/src/Util.cpp | 60 ++++++ interface/src/Util.h | 4 + libraries/voxels/src/ViewFrustum.cpp | 2 +- 13 files changed, 384 insertions(+), 329 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a8e62a68e7..80d095329d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -288,33 +288,22 @@ void Application::paintGL() { if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myCamera.setTightness (100.0f); _myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getBodyYaw() - 180.0f, - 0.0f, - 0.0f); + _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation()); + } else if (OculusManager::isConnected()) { _myCamera.setUpShift (0.0f); _myCamera.setDistance (0.0f); _myCamera.setTightness (100.0f); _myCamera.setTargetPosition(_myAvatar.getHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getAbsoluteHeadYaw(), - _myAvatar.getHead().getPitch(), - -_myAvatar.getHead().getRoll()); + _myCamera.setTargetRotation(_myAvatar.getHead().getOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); + } else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { _myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getAbsoluteHeadYaw(), - _myAvatar.getAbsoluteHeadPitch(), - 0.0f); - // Take a look at whether we are inside head, don't render it if so. - const float HEAD_RENDER_DISTANCE = 0.5; - glm::vec3 distanceToHead(_myCamera.getPosition() - _myAvatar.getSpringyHeadPosition()); + _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); - if (glm::length(distanceToHead) < HEAD_RENDER_DISTANCE) { - } } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { _myCamera.setTargetPosition(_myAvatar.getHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getAbsoluteHeadYaw(), - _myAvatar.getAbsoluteHeadPitch(), - 0.0f); + _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); } // important... @@ -344,9 +333,9 @@ void Application::paintGL() { if (_viewFrustumFromOffset->isChecked() && _frustumOn->isChecked()) { // set the camera to third-person view but offset so we can see the frustum - _viewFrustumOffsetCamera.setTargetYaw(_viewFrustumOffsetYaw + _myAvatar.getBodyYaw()); - _viewFrustumOffsetCamera.setPitch (_viewFrustumOffsetPitch ); - _viewFrustumOffsetCamera.setRoll (_viewFrustumOffsetRoll ); + _viewFrustumOffsetCamera.setTargetPosition(_myCamera.getTargetPosition()); + _viewFrustumOffsetCamera.setTargetRotation(_myCamera.getTargetRotation() * glm::quat(glm::radians(glm::vec3( + _viewFrustumOffsetPitch, _viewFrustumOffsetYaw, _viewFrustumOffsetRoll)))); _viewFrustumOffsetCamera.setUpShift (_viewFrustumOffsetUp ); _viewFrustumOffsetCamera.setDistance (_viewFrustumOffsetDistance); _viewFrustumOffsetCamera.update(1.f/_fps); @@ -1381,10 +1370,6 @@ void Application::updateAvatar(float deltaTime) { void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { // We will use these below, from either the camera or head vectors calculated above glm::vec3 position; - glm::vec3 direction; - glm::vec3 up; - glm::vec3 right; - float fov, nearClip, farClip; // Camera or Head? if (_cameraFrustum->isChecked()) { @@ -1393,15 +1378,14 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { position = _myAvatar.getHeadPosition(); } - fov = camera.getFieldOfView(); - nearClip = camera.getNearClip(); - farClip = camera.getFarClip(); + float fov = camera.getFieldOfView(); + float nearClip = camera.getNearClip(); + float farClip = camera.getFarClip(); - Orientation o = camera.getOrientation(); - - direction = o.getFront(); - up = o.getUp(); - right = o.getRight(); + glm::quat rotation = camera.getRotation(); + glm::vec3 direction = rotation * IDENTITY_FRONT; + glm::vec3 up = rotation * IDENTITY_UP; + glm::vec3 right = rotation * IDENTITY_RIGHT; /* printf("position.x=%f, position.y=%f, position.z=%f\n", position.x, position.y, position.z); @@ -1416,7 +1400,7 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { // Set the viewFrustum up with the correct position and orientation of the camera viewFrustum.setPosition(position); - viewFrustum.setOrientation(direction,up,right); + viewFrustum.setOrientation(direction,up,-right); // Also make sure it's got the correct lens details from the camera viewFrustum.setFieldOfView(fov); @@ -1587,11 +1571,10 @@ void Application::displaySide(Camera& whichCamera) { // transform view according to whichCamera // could be myCamera (if in normal mode) // or could be viewFrustumOffsetCamera if in offset mode - // I changed the ordering here - roll is FIRST (JJV) - glRotatef ( whichCamera.getRoll(), IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z); - glRotatef ( whichCamera.getPitch(), IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z); - glRotatef (180.0 - whichCamera.getYaw(), IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z ); + glm::quat rotation = whichCamera.getRotation(); + glm::vec3 axis = glm::axis(rotation); + glRotatef(-glm::angle(rotation), axis.x, axis.y, axis.z); glTranslatef(-whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 403918c830..766109255f 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -51,7 +51,6 @@ const float HEAD_MIN_YAW = -85; const float PERIPERSONAL_RADIUS = 1.0f; const float AVATAR_BRAKING_STRENGTH = 40.0f; const float JOINT_TOUCH_RANGE = 0.0005f; -const float ANGULAR_RIGHTING_SPEED = 45.0f; const float FLOATING_HEIGHT = 0.13f; const bool USING_HEAD_LEAN = false; const float LEAN_SENSITIVITY = 0.15; @@ -86,11 +85,11 @@ Avatar::Avatar(Agent* owningAgent) : _thrust(0.0f, 0.0f, 0.0f), _speed(0.0f), _maxArmLength(0.0f), - _orientation(), _pelvisStandingHeight(0.0f), _pelvisFloatingHeight(0.0f), _distanceToNearestAvatar(std::numeric_limits::max()), _gravity(0.0f, -1.0f, 0.0f), + _worldUpDirection(0.0f, 1.0f, 0.0), _mouseRayOrigin(0.0f, 0.0f, 0.0f), _mouseRayDirection(0.0f, 0.0f, 0.0f), _interactingOther(NULL), @@ -157,11 +156,19 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa } float Avatar::getAbsoluteHeadYaw() const { - return _bodyYaw + _head.getYaw(); + return glm::yaw(_head.getOrientation()); } float Avatar::getAbsoluteHeadPitch() const { - return _bodyPitch + _head.getPitch(); + return glm::pitch(_head.getOrientation()); +} + +glm::quat Avatar::getOrientation() const { + return glm::quat(glm::radians(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll))); +} + +glm::quat Avatar::getWorldAlignedOrientation () const { + return computeRotationFromBodyToWorldUp() * getOrientation(); } void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight) { @@ -218,9 +225,9 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // if other avatar, update head position from network data - // update avatar skeleton - updateSkeleton(); - + // update avatar skeleton + updateSkeleton(); + //detect and respond to collisions with other avatars... if (!_owningAgent) { updateAvatarCollisions(deltaTime); @@ -238,7 +245,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { updateCollisionWithEnvironment(); } - // update body springs + // update body springs updateBodySprings(deltaTime); // test for avatar collision response with the big sphere @@ -251,18 +258,23 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { updateCollisionWithVoxels(); } + glm::quat orientation = getOrientation(); + glm::vec3 front = orientation * IDENTITY_FRONT; + glm::vec3 right = orientation * IDENTITY_RIGHT; + glm::vec3 up = orientation * IDENTITY_UP; + // driving the avatar around should only apply if this is my avatar (as opposed to an avatar being driven remotely) if (!_owningAgent) { _thrust = glm::vec3(0.0f, 0.0f, 0.0f); // Add Thrusts from keyboard - if (_driveKeys[FWD ]) {_thrust += THRUST_MAG * deltaTime * _orientation.getFront();} - if (_driveKeys[BACK ]) {_thrust -= THRUST_MAG * deltaTime * _orientation.getFront();} - if (_driveKeys[RIGHT ]) {_thrust += THRUST_MAG * deltaTime * _orientation.getRight();} - if (_driveKeys[LEFT ]) {_thrust -= THRUST_MAG * deltaTime * _orientation.getRight();} - if (_driveKeys[UP ]) {_thrust += THRUST_MAG * deltaTime * _orientation.getUp();} - if (_driveKeys[DOWN ]) {_thrust -= THRUST_MAG * deltaTime * _orientation.getUp();} + if (_driveKeys[FWD ]) {_thrust += THRUST_MAG * deltaTime * front;} + if (_driveKeys[BACK ]) {_thrust -= THRUST_MAG * deltaTime * front;} + if (_driveKeys[RIGHT ]) {_thrust += THRUST_MAG * deltaTime * right;} + if (_driveKeys[LEFT ]) {_thrust -= THRUST_MAG * deltaTime * right;} + if (_driveKeys[UP ]) {_thrust += THRUST_MAG * deltaTime * up;} + if (_driveKeys[DOWN ]) {_thrust -= THRUST_MAG * deltaTime * up;} if (_driveKeys[ROT_RIGHT]) {_bodyYawDelta -= YAW_MAG * deltaTime;} if (_driveKeys[ROT_LEFT ]) {_bodyYawDelta += YAW_MAG * deltaTime;} @@ -277,10 +289,10 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { const float TRANSMITTER_LIFT_SCALE = 3.f; const float TOUCH_POSITION_RANGE_HALF = 32767.f; if (fabs(rotation.z) > TRANSMITTER_MIN_RATE) { - _thrust += rotation.z * TRANSMITTER_LATERAL_FORCE_SCALE * deltaTime * _orientation.getRight(); + _thrust += rotation.z * TRANSMITTER_LATERAL_FORCE_SCALE * deltaTime * right; } if (fabs(rotation.x) > TRANSMITTER_MIN_RATE) { - _thrust += -rotation.x * TRANSMITTER_FWD_FORCE_SCALE * deltaTime * _orientation.getFront(); + _thrust += -rotation.x * TRANSMITTER_FWD_FORCE_SCALE * deltaTime * front; } if (fabs(rotation.y) > TRANSMITTER_MIN_YAW_RATE) { _bodyYawDelta += rotation.y * TRANSMITTER_YAW_SCALE * deltaTime; @@ -290,27 +302,26 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { (float)(transmitter->getTouchState()->y - TOUCH_POSITION_RANGE_HALF) / TOUCH_POSITION_RANGE_HALF * TRANSMITTER_LIFT_SCALE * deltaTime * - _orientation.getUp(); + up; } } - } - - // update body yaw by body yaw delta - if (!_owningAgent) { - _bodyPitch += _bodyPitchDelta * deltaTime; - _bodyYaw += _bodyYawDelta * deltaTime; - _bodyRoll += _bodyRollDelta * deltaTime; } - // decay body rotation momentum + // update body yaw by body yaw delta + if (!_owningAgent) { + orientation = orientation * glm::quat(glm::radians( + glm::vec3(_bodyPitchDelta, _bodyYawDelta, _bodyRollDelta) * deltaTime)); + } + + // decay body rotation momentum float bodySpinMomentum = 1.0 - BODY_SPIN_FRICTION * deltaTime; if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; } _bodyPitchDelta *= bodySpinMomentum; _bodyYawDelta *= bodySpinMomentum; _bodyRollDelta *= bodySpinMomentum; - // add thrust to velocity - _velocity += _thrust * deltaTime; + // add thrust to velocity + _velocity += _thrust * deltaTime; // calculate speed _speed = glm::length(_velocity); @@ -318,37 +329,25 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { //pitch and roll the body as a function of forward speed and turning delta const float BODY_PITCH_WHILE_WALKING = 20.0; const float BODY_ROLL_WHILE_TURNING = 0.2; - float forwardComponentOfVelocity = glm::dot(_orientation.getFront(), _velocity); - _bodyPitch += BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity; - _bodyRoll += BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta; - - // these forces keep the body upright... - float tiltDecay = 1.0 - BODY_UPRIGHT_FORCE * deltaTime; - if (tiltDecay < 0.0f) {tiltDecay = 0.0f;} - _bodyPitch *= tiltDecay; - _bodyRoll *= tiltDecay; + float forwardComponentOfVelocity = glm::dot(getBodyFrontDirection(), _velocity); + orientation = orientation * glm::quat(glm::radians(glm::vec3( + BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, + -BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta))); + // these forces keep the body upright... + float tiltDecay = BODY_UPRIGHT_FORCE * deltaTime; + if (tiltDecay > 1.0f) {tiltDecay = 1.0f;} + + // update the euler angles + setOrientation(orientation); + //the following will be used to make the avatar upright no matter what gravity is - float gravityLength = glm::length(_gravity); - if (gravityLength > 0.0f) { - glm::vec3 targetUp = _gravity / -gravityLength; - const glm::vec3& currentUp = _righting * glm::vec3(0.0f, 1.0f, 0.0f); - float angle = glm::degrees(acosf(glm::dot(currentUp, targetUp))); - if (angle > 0.0f) { - glm::vec3 axis; - if (angle > 180.0f - EPSILON) { // 180 degree rotation; must use another axis - axis = _orientation.getRight(); - } else { - axis = glm::normalize(glm::cross(currentUp, targetUp)); - } - //_righting = glm::angleAxis(min(deltaTime * ANGULAR_RIGHTING_SPEED, angle), axis) * _righting; - } - } - + setOrientation(computeRotationFromBodyToWorldUp(tiltDecay) * orientation); + // update position by velocity _position += _velocity * deltaTime; - // decay velocity + // decay velocity float decay = 1.0 - VELOCITY_DECAY * deltaTime; if ( decay < 0.0 ) { _velocity = glm::vec3( 0.0f, 0.0f, 0.0f ); @@ -400,8 +399,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { if (USING_HEAD_LEAN) { if (fabs(_head.getLeanSideways() + _head.getLeanForward()) > 0.0f) { glm::vec3 headLean = - _orientation.getRight() * _head.getLeanSideways() + - _orientation.getFront() * _head.getLeanForward(); + right * _head.getLeanSideways() + + front * _head.getLeanForward(); _joint[ AVATAR_JOINT_TORSO ].springyPosition += headLean * 0.1f; _joint[ AVATAR_JOINT_CHEST ].springyPosition += headLean * 0.4f; @@ -431,18 +430,18 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } } - _head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); + _head.setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); _head.setPosition(_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition); _head.setScale (_joint[ AVATAR_JOINT_HEAD_BASE ].radius); _head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2])); _head.simulate(deltaTime, !_owningAgent); // use speed and angular velocity to determine walking vs. standing - if (_speed + fabs(_bodyYawDelta) > 0.2) { - _mode = AVATAR_MODE_WALKING; - } else { - _mode = AVATAR_MODE_INTERACTING; - } + if (_speed + fabs(_bodyYawDelta) > 0.2) { + _mode = AVATAR_MODE_WALKING; + } else { + _mode = AVATAR_MODE_INTERACTING; + } } void Avatar::checkForMouseRayTouching() { @@ -465,19 +464,25 @@ void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction ) { _mouseRayDirection = direction; } +void Avatar::setOrientation(const glm::quat& orientation) { + glm::vec3 eulerAngles = safeEulerAngles(orientation); + _bodyPitch = eulerAngles.x; + _bodyYaw = eulerAngles.y; + _bodyRoll = eulerAngles.z; +} + void Avatar::updateHandMovementAndTouching(float deltaTime) { + glm::quat orientation = getOrientation(); + // reset hand and arm positions according to hand movement - glm::vec3 transformedHandMovement - = _orientation.getRight() * _movedHandOffset.x * 2.0f - + _orientation.getUp() * -_movedHandOffset.y * 1.0f - + _orientation.getFront() * -_movedHandOffset.y * 1.0f; + glm::vec3 transformedHandMovement = orientation * (_movedHandOffset * glm::vec3(-2.0f, -1.0f, -1.0f)); _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement; if (!_owningAgent) { _avatarTouch.setMyBodyPosition(_position); - _avatarTouch.setMyOrientation(_orientation); + _avatarTouch.setMyOrientation(orientation); float closestDistance = std::numeric_limits::max(); @@ -492,7 +497,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { //Test: Show angle between your fwd vector and nearest avatar //glm::vec3 vectorBetweenUs = otherAvatar->getJointPosition(AVATAR_JOINT_PELVIS) - // getJointPosition(AVATAR_JOINT_PELVIS); - //printLog("Angle between: %f\n", angleBetween(vectorBetweenUs, _orientation.getFront())); + //printLog("Angle between: %f\n", angleBetween(vectorBetweenUs, getBodyFrontDirection())); // test whether shoulders are close enough to allow for reaching to touch hands glm::vec3 v(_position - otherAvatar->_position); @@ -511,7 +516,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { _avatarTouch.setHasInteractingOther(true); _avatarTouch.setYourBodyPosition(_interactingOther->_position); - _avatarTouch.setYourOrientation (_interactingOther->_orientation); + _avatarTouch.setYourOrientation (_interactingOther->getOrientation()); _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); _avatarTouch.setYourHandState (_interactingOther->_handState); @@ -616,11 +621,12 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d } void Avatar::updateCollisionWithEnvironment() { + glm::vec3 up = getBodyUpDirection(); float radius = _height * 0.125f; glm::vec3 penetration; if (Application::getInstance()->getEnvironment()->findCapsulePenetration( - _position - glm::vec3(0.0f, _pelvisFloatingHeight - radius, 0.0f), - _position + glm::vec3(0.0f, _height - _pelvisFloatingHeight - radius, 0.0f), radius, penetration)) { + _position - up * (_pelvisFloatingHeight - radius), + _position + up * (_height - _pelvisFloatingHeight - radius), radius, penetration)) { applyCollisionWithScene(penetration); } } @@ -740,6 +746,12 @@ static TextRenderer* textRenderer() { void Avatar::setGravity(glm::vec3 gravity) { _gravity = gravity; _head.setGravity(_gravity); + + // use the gravity to determine the new world up direction, if possible + float gravityLength = glm::length(gravity); + if (gravityLength > EPSILON) { + _worldUpDirection = _gravity / -gravityLength; + } } void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { @@ -823,49 +835,45 @@ void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { void Avatar::initializeSkeleton() { - for (int b=0; b 0.0f) { // to avoid divide by zero glm::vec3 springDirection = springVector / length; - + float force = (length - _joint[b].length) * BODY_SPRING_FORCE * deltaTime; - + _joint[b].springyVelocity -= springDirection * force; if (_joint[b].parent != AVATAR_JOINT_NULL) { @@ -1051,7 +1051,7 @@ void Avatar::updateBodySprings(float deltaTime) { } // apply tightness force - (causing springy position to be close to rigid body position) - _joint[b].springyVelocity += (_joint[b].position - _joint[b].springyPosition) * _joint[b].springBodyTightness * deltaTime; + _joint[b].springyVelocity += (_joint[b].position - _joint[b].springyPosition) * _joint[b].springBodyTightness * deltaTime; // apply decay float decay = 1.0 - BODY_SPRING_DECAY * deltaTime; @@ -1082,7 +1082,7 @@ void Avatar::updateArmIKAndConstraints(float deltaTime) { // test to see if right hand is being dragged beyond maximum arm length float distance = glm::length(armVector); - + // don't let right hand get dragged beyond maximum arm length... if (distance > _maxArmLength) { // reset right hand to be constrained to maximum arm length @@ -1099,7 +1099,7 @@ void Avatar::updateArmIKAndConstraints(float deltaTime) { glm::vec3 newElbowPosition = _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; newElbowPosition += armVector * ONE_HALF; - glm::vec3 perpendicular = glm::cross(_orientation.getFront(), armVector); + glm::vec3 perpendicular = glm::cross(getBodyFrontDirection(), armVector); newElbowPosition += perpendicular * (1.0f - (_maxArmLength / distance)) * ONE_HALF; _joint[ AVATAR_JOINT_RIGHT_ELBOW ].position = newElbowPosition; @@ -1111,6 +1111,21 @@ void Avatar::updateArmIKAndConstraints(float deltaTime) { _joint[ AVATAR_JOINT_RIGHT_WRIST ].position = newWristPosition; } +glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { + glm::quat orientation = getOrientation(); + glm::vec3 currentUp = orientation * IDENTITY_UP; + float angle = glm::degrees(acosf(glm::clamp(glm::dot(currentUp, _worldUpDirection), -1.0f, 1.0f))); + if (angle < EPSILON) { + return glm::quat(); + } + glm::vec3 axis; + if (angle > 179.99f) { // 180 degree rotation; must use another axis + axis = orientation * IDENTITY_RIGHT; + } else { + axis = glm::normalize(glm::cross(currentUp, _worldUpDirection)); + } + return glm::angleAxis(angle * proportion, axis); +} void Avatar::renderBody(bool lookingInMirror) { @@ -1121,7 +1136,8 @@ void Avatar::renderBody(bool lookingInMirror) { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { float distanceToCamera = glm::length(_cameraPosition - _joint[b].position); - float alpha = glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f); + float alpha = lookingInMirror ? 1.0f : glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / + (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f); // Always render other people, and render myself when beyond threshold distance if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 1ef5675d9b..b84bb981ee 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -31,15 +31,15 @@ enum DriveKeys DOWN, ROT_LEFT, ROT_RIGHT, - MAX_DRIVE_KEYS + MAX_DRIVE_KEYS }; enum AvatarMode { - AVATAR_MODE_STANDING = 0, - AVATAR_MODE_WALKING, - AVATAR_MODE_INTERACTING, - NUM_AVATAR_MODES + AVATAR_MODE_STANDING = 0, + AVATAR_MODE_WALKING, + AVATAR_MODE_INTERACTING, + NUM_AVATAR_MODES }; class Avatar : public AvatarData { @@ -62,6 +62,7 @@ public: void setDisplayingLookatVectors(bool displayingLookatVectors) { _head.setRenderLookatVectors(displayingLookatVectors);} void setGravity (glm::vec3 gravity); void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction); + void setOrientation (const glm::quat& orientation); //getters float getHeadYawRate () const { return _head.yawRate;} @@ -69,8 +70,10 @@ public: bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();} const glm::vec3& getHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].position;} const glm::vec3& getSpringyHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition;} - const glm::vec3& getJointPosition (AvatarJointID j) const { return _joint[j].springyPosition;} - const glm::vec3& getBodyUpDirection () const { return _orientation.getUp();} + const glm::vec3& getJointPosition (AvatarJointID j) const { return _joint[j].springyPosition;} + glm::vec3 getBodyRightDirection () const { return getOrientation() * IDENTITY_RIGHT; } + glm::vec3 getBodyUpDirection () const { return getOrientation() * IDENTITY_UP; } + glm::vec3 getBodyFrontDirection () const { return getOrientation() * IDENTITY_FRONT; } const glm::vec3& getVelocity () const { return _velocity;} float getSpeed () const { return _speed;} float getHeight () const { return _height;} @@ -78,6 +81,8 @@ public: float getAbsoluteHeadYaw () const; float getAbsoluteHeadPitch () const; Head& getHead () {return _head; } + glm::quat getOrientation () const; + glm::quat getWorldAlignedOrientation () const; // Set what driving keys are being pressed to control thrust levels void setDriveKeys(int key, bool val) { _driveKeys[key] = val; }; @@ -99,19 +104,15 @@ private: struct AvatarJoint { AvatarJointID parent; // which joint is this joint connected to? - glm::vec3 position; // the position at the "end" of the joint - in global space - glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the "T-pose" - glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position) - glm::vec3 springyVelocity; // used for special effects ( the velocity of the springy position) - float springBodyTightness; // how tightly the springy position tries to stay on the position - glm::quat rotation; // this will eventually replace yaw, pitch and roll (and maybe orientation) - float yaw; // the yaw Euler angle of the joint rotation off the parent - float pitch; // the pitch Euler angle of the joint rotation off the parent - float roll; // the roll Euler angle of the joint rotation off the parent - Orientation orientation; // three orthogonal normals determined by yaw, pitch, roll - float length; // the length of vector connecting the joint and its parent - float radius; // used for detecting collisions for certain physical effects - bool isCollidable; // when false, the joint position will not register a collision + glm::vec3 position; // the position at the "end" of the joint - in global space + glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the "T-pose" + glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position) + glm::vec3 springyVelocity; // used for special effects ( the velocity of the springy position) + float springBodyTightness; // how tightly the springy position tries to stay on the position + glm::quat orientation; // this will eventually replace yaw, pitch and roll (and maybe orientation) + float length; // the length of vector connecting the joint and its parent + float radius; // used for detecting collisions for certain physical effects + bool isCollidable; // when false, the joint position will not register a collision float touchForce; // if being touched, what's the degree of influence? (0 to 1) }; @@ -125,15 +126,14 @@ private: float _bodyRollDelta; glm::vec3 _movedHandOffset; glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion - AvatarJoint _joint[ NUM_AVATAR_JOINTS ]; + AvatarJoint _joint[ NUM_AVATAR_JOINTS ]; AvatarMode _mode; glm::vec3 _cameraPosition; glm::vec3 _handHoldingPosition; glm::vec3 _velocity; - glm::vec3 _thrust; + glm::vec3 _thrust; float _speed; - float _maxArmLength; - Orientation _orientation; + float _maxArmLength; glm::quat _righting; int _driveKeys[MAX_DRIVE_KEYS]; float _pelvisStandingHeight; @@ -143,6 +143,7 @@ private: AvatarTouch _avatarTouch; float _distanceToNearestAvatar; // How close is the nearest avatar? glm::vec3 _gravity; + glm::vec3 _worldUpDirection; glm::vec3 _mouseRayOrigin; glm::vec3 _mouseRayDirection; Avatar* _interactingOther; @@ -151,6 +152,7 @@ private: // private methods... glm::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat) + glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const; void renderBody(bool lookingInMirror); void initializeSkeleton(); void updateSkeleton(); diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 18f4847d33..9ca1e33b57 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -29,8 +29,6 @@ AvatarTouch::AvatarTouch() { _canReachToOtherAvatar = false; _handsCloseEnoughToGrasp = false; _hasInteractingOther = false; - _myOrientation.setToIdentity(); - _yourOrientation.setToIdentity(); for (int p=0; p AVATAR_FACING_THRESHOLD)) { // I'm facing you + glm::vec3 myFront = _myOrientation * IDENTITY_FRONT; + glm::vec3 yourFront = _yourOrientation * IDENTITY_FRONT; + + if (( glm::dot(myFront, yourFront) < -AVATAR_FACING_THRESHOLD) // we're facing each other + && ( glm::dot(myFront, directionBetweenBodies ) > AVATAR_FACING_THRESHOLD)) { // I'm facing you facingEachOther = true; } diff --git a/interface/src/AvatarTouch.h b/interface/src/AvatarTouch.h index 1361e930eb..32a0b29274 100644 --- a/interface/src/AvatarTouch.h +++ b/interface/src/AvatarTouch.h @@ -31,8 +31,8 @@ public: void setHasInteractingOther(bool hasInteractingOther) { _hasInteractingOther = hasInteractingOther;} void setMyHandPosition (glm::vec3 position ) { _myHandPosition = position;} void setYourHandPosition (glm::vec3 position ) { _yourHandPosition = position;} - void setMyOrientation (Orientation orientation ) { _myOrientation = orientation;} - void setYourOrientation (Orientation orientation ) { _yourOrientation = orientation;} + void setMyOrientation (glm::quat orientation ) { _myOrientation = orientation;} + void setYourOrientation (glm::quat orientation ) { _yourOrientation = orientation;} void setMyBodyPosition (glm::vec3 position ) { _myBodyPosition = position;} void setYourBodyPosition (glm::vec3 position ) { _yourBodyPosition = position;} void setMyHandState (int state ) { _myHandState = state;} @@ -55,8 +55,8 @@ private: glm::vec3 _yourBodyPosition; glm::vec3 _myHandPosition; glm::vec3 _yourHandPosition; - Orientation _myOrientation; - Orientation _yourOrientation; + glm::quat _myOrientation; + glm::quat _yourOrientation; glm::vec3 _vectorBetweenHands; int _myHandState; int _yourHandState; diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index fa0744bf49..984de67462 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -4,12 +4,14 @@ // // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +#include #include #include #include -// #include "Log.h" +#include "Log.h" #include "Camera.h" +#include "Util.h" const float CAMERA_MINIMUM_MODE_SHIFT_RATE = 0.5f; @@ -38,9 +40,6 @@ Camera::Camera() { _fieldOfView = 60.0f; // default _nearClip = 0.08f; // default _farClip = 50.0f * TREE_SCALE; // default - _yaw = 0.0f; - _pitch = 0.0f; - _roll = 0.0f; _upShift = 0.0f; _distance = 0.0f; _previousUpShift = 0.0f; @@ -49,13 +48,9 @@ Camera::Camera() { _newUpShift = 0.0f; _newDistance = 0.0f; _newTightness = 0.0f; - _idealYaw = 0.0f; - _idealPitch = 0.0f; - _idealRoll = 0.0f; _targetPosition = glm::vec3(0.0f, 0.0f, 0.0f); _position = glm::vec3(0.0f, 0.0f, 0.0f); _idealPosition = glm::vec3(0.0f, 0.0f, 0.0f); - _orientation.setToIdentity(); } void Camera::update(float deltaTime) { @@ -64,17 +59,6 @@ void Camera::update(float deltaTime) { // use iterative forces to push the camera towards the target position and angle updateFollowMode(deltaTime); } - - // do this AFTER making any changes to yaw pitch and roll.... - generateOrientation(); -} - -// generate the ortho-normals for the orientation based on the three Euler angles -void Camera::generateOrientation() { - _orientation.setToIdentity(); - _orientation.pitch(_pitch); - _orientation.yaw (_yaw ); - _orientation.roll (_roll ); } // use iterative forces to keep the camera at the desired position and angle @@ -104,28 +88,17 @@ void Camera::updateFollowMode(float deltaTime) { t = 1.0; } - // update Euler angles (before position!) + // update rotation (before position!) if (_needsToInitialize || OculusManager::isConnected()) { - _yaw = _idealYaw; - _pitch = _idealPitch; - _roll = _idealRoll; + _rotation = _idealRotation; } else { - // pull Euler angles towards ideal Euler angles - _yaw += (_idealYaw - _yaw ) * t; - _pitch += (_idealPitch - _pitch) * t; - _roll += (_idealRoll - _roll ) * t; + // pull rotation towards ideal + _rotation = safeMix(_rotation, _idealRotation, t); } - float radian = (_yaw / 180.0) * PIE; - - // update _position - double x = -_distance * sin(radian); - double z = -_distance * cos(radian); - double y = _upShift; - - _idealPosition = _targetPosition + glm::vec3(x, y, z); + _idealPosition = _targetPosition + _rotation * glm::vec3(0.0f, _upShift, _distance); - if (_needsToInitialize) { + if (_needsToInitialize || true) { _position = _idealPosition; _needsToInitialize = false; } else { @@ -171,10 +144,8 @@ void Camera::setMode(CameraMode m) { } -void Camera::setTargetRotation( float yaw, float pitch, float roll ) { - _idealYaw = yaw; - _idealPitch = pitch; - _idealRoll = roll; +void Camera::setTargetRotation( const glm::quat& targetRotation ) { + _idealRotation = targetRotation; } void Camera::setFieldOfView(float f) { diff --git a/interface/src/Camera.h b/interface/src/Camera.h index ae3e3ef7b2..f1eb764aab 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -30,16 +30,12 @@ public: void update( float deltaTime ); - void setYaw ( float y ) { _yaw = y; } - void setPitch ( float p ) { _pitch = p; } - void setRoll ( float r ) { _roll = r; } void setUpShift ( float u ) { _upShift = u; } void setDistance ( float d ) { _distance = d; } void setTargetPosition( glm::vec3 t ) { _targetPosition = t; } - void setTargetYaw ( float y ) { _idealYaw = y; } void setPosition ( glm::vec3 p ) { _position = p; } void setTightness ( float t ) { _tightness = t; } - void setTargetRotation( float yaw, float pitch, float roll ); + void setTargetRotation( const glm::quat& rotation ); void setMode ( CameraMode m ); void setModeShiftRate ( float r ); @@ -49,12 +45,11 @@ public: void setFarClip ( float f ); void setEyeOffsetPosition ( const glm::vec3& p); void setEyeOffsetOrientation ( const glm::quat& o); - - float getYaw () { return _yaw; } - float getPitch () { return _pitch; } - float getRoll () { return _roll; } + + glm::vec3 getTargetPosition () { return _targetPosition; } glm::vec3 getPosition () { return _position; } - Orientation getOrientation() { return _orientation; } + glm::quat getTargetRotation () { return _idealRotation; } + glm::quat getRotation () { return _rotation; } CameraMode getMode () { return _mode; } float getFieldOfView() { return _fieldOfView; } float getAspectRatio() { return _aspectRatio; } @@ -79,12 +74,8 @@ private: float _farClip; glm::vec3 _eyeOffsetPosition; glm::quat _eyeOffsetOrientation; - float _yaw; - float _pitch; - float _roll; - float _idealYaw; - float _idealPitch; - float _idealRoll; + glm::quat _rotation; + glm::quat _idealRotation; float _upShift; float _distance; float _tightness; @@ -94,12 +85,10 @@ private: float _newUpShift; float _newDistance; float _newTightness; - Orientation _orientation; float _modeShift; float _linearModeShift; float _modeShiftRate; - void generateOrientation(); void updateFollowMode( float deltaTime ); }; diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index fec4ba0529..6bb127a87e 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -71,7 +71,7 @@ glm::vec3 Environment::getGravity (const glm::vec3& position) { foreach (const ServerData& serverData, _data) { foreach (const EnvironmentData& environmentData, serverData) { glm::vec3 vector = environmentData.getAtmosphereCenter() - position; - if (glm::length(vector) < environmentData.getAtmosphereOuterRadius()) { + if (glm::length(vector) < environmentData.getAtmosphereOuterRadius() * 2.0f) { gravity += glm::normalize(vector) * environmentData.getGravity(); } } diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 762b9f16ac..547d732f3b 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -4,6 +4,8 @@ // // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +#include +#include "Avatar.h" #include "Head.h" #include "Util.h" #include @@ -62,6 +64,7 @@ Head::Head(Avatar* owningAvatar) : _audioAttack(0.0f), _returnSpringScale(1.0f), _bodyRotation(0.0f, 0.0f, 0.0f), + _lookingInMirror(false), _renderLookatVectors(false), _mohawkTriangleFan(NULL), _mohawkColors(NULL) @@ -84,13 +87,14 @@ void Head::reset() { void Head::resetHairPhysics() { + glm::vec3 up = getUpDirection(); for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { _hairTuft[t].length = HAIR_LENGTH; _hairTuft[t].thickness = HAIR_THICKNESS; - _hairTuft[t].basePosition = _position + _orientation.getUp() * _scale * 0.9f; - _hairTuft[t].midPosition = _hairTuft[t].basePosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF; - _hairTuft[t].endPosition = _hairTuft[t].midPosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF; + _hairTuft[t].basePosition = _position + up * _scale * 0.9f; + _hairTuft[t].midPosition = _hairTuft[t].basePosition + up * _hairTuft[t].length * ONE_HALF; + _hairTuft[t].endPosition = _hairTuft[t].midPosition + up * _hairTuft[t].length * ONE_HALF; _hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f); _hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f); } @@ -156,7 +160,7 @@ void Head::determineIfLookingAtSomething() { _lookingAtSomething = false; } else { glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - caclulateAverageEyePosition()); - float dot = glm::dot(targetLookatAxis, _orientation.getFront()); + float dot = glm::dot(targetLookatAxis, getFrontDirection()); if (dot < MINIMUM_EYE_ROTATION_DOT) { // too far off from center for the eyes to rotate _lookingAtSomething = false; } else { @@ -165,57 +169,48 @@ void Head::determineIfLookingAtSomething() { } } -void Head::calculateGeometry(bool lookingInMirror) { - //generate orientation directions based on Euler angles... - - float pitch = _pitch; - float yaw = _yaw; - float roll = _roll; - - if (lookingInMirror) { - yaw = -_yaw; - roll = -_roll; - } - - _orientation.setToIdentity(); - _orientation.roll (_bodyRotation.z + roll ); - _orientation.pitch(_bodyRotation.x + pitch); - _orientation.yaw (_bodyRotation.y + yaw ); +void Head::calculateGeometry() { + //generate orientation directions + glm::quat orientation = getOrientation(); + glm::vec3 right = orientation * IDENTITY_RIGHT; + glm::vec3 up = orientation * IDENTITY_UP; + glm::vec3 front = orientation * IDENTITY_FRONT; //calculate the eye positions _leftEyePosition = _position - - _orientation.getRight() * _scale * EYE_RIGHT_OFFSET - + _orientation.getUp () * _scale * EYE_UP_OFFSET - + _orientation.getFront() * _scale * EYE_FRONT_OFFSET; + - right * _scale * EYE_RIGHT_OFFSET + + up * _scale * EYE_UP_OFFSET + + front * _scale * EYE_FRONT_OFFSET; _rightEyePosition = _position - + _orientation.getRight() * _scale * EYE_RIGHT_OFFSET - + _orientation.getUp () * _scale * EYE_UP_OFFSET - + _orientation.getFront() * _scale * EYE_FRONT_OFFSET; + + right * _scale * EYE_RIGHT_OFFSET + + up * _scale * EYE_UP_OFFSET + + front * _scale * EYE_FRONT_OFFSET; //calculate the eyebrow positions _leftEyeBrowPosition = _leftEyePosition; _rightEyeBrowPosition = _rightEyePosition; //calculate the ear positions - _leftEarPosition = _position - _orientation.getRight() * _scale * EAR_RIGHT_OFFSET; - _rightEarPosition = _position + _orientation.getRight() * _scale * EAR_RIGHT_OFFSET; + _leftEarPosition = _position - right * _scale * EAR_RIGHT_OFFSET; + _rightEarPosition = _position + right * _scale * EAR_RIGHT_OFFSET; //calculate the mouth position - _mouthPosition = _position + _orientation.getUp () * _scale * MOUTH_UP_OFFSET - + _orientation.getFront() * _scale; + _mouthPosition = _position + up * _scale * MOUTH_UP_OFFSET + + front * _scale; } void Head::render(bool lookingInMirror, glm::vec3 cameraPosition, float alpha) { _renderAlpha = alpha; + _lookingInMirror = lookingInMirror; - calculateGeometry(lookingInMirror); + calculateGeometry(); glEnable(GL_DEPTH_TEST); glEnable(GL_RESCALE_NORMAL); - renderMohawk(lookingInMirror, cameraPosition); + renderMohawk(cameraPosition); renderHeadSphere(); renderEyeBalls(); renderEars(); @@ -259,7 +254,7 @@ void Head::createMohawk() { } } -void Head::renderMohawk(bool lookingInMirror, glm::vec3 cameraPosition) { +void Head::renderMohawk(glm::vec3 cameraPosition) { if (!_mohawkTriangleFan) { createMohawk(); @@ -297,8 +292,8 @@ void Head::renderMohawk(bool lookingInMirror, glm::vec3 cameraPosition) { } else { glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); - glRotatef((lookingInMirror ? (_bodyRotation.y - _yaw) : (_bodyRotation.y + _yaw)), 0, 1, 0); - glRotatef(lookingInMirror ? _roll: -_roll, 0, 0, 1); + glRotatef((_lookingInMirror ? (_bodyRotation.y - _yaw) : (_bodyRotation.y + _yaw)), 0, 1, 0); + glRotatef(_lookingInMirror ? _roll: -_roll, 0, 0, 1); glRotatef(-_pitch - _bodyRotation.x, 1, 0, 0); glBegin(GL_TRIANGLE_FAN); @@ -312,6 +307,16 @@ void Head::renderMohawk(bool lookingInMirror, glm::vec3 cameraPosition) { } } +glm::quat Head::getOrientation() const { + return glm::quat(glm::radians(_bodyRotation)) * glm::quat(glm::radians(_lookingInMirror ? + glm::vec3(_pitch, -_yaw, -_roll) : glm::vec3(_pitch, _yaw, _roll))); +} + +glm::quat Head::getWorldAlignedOrientation () const { + Avatar* owningAvatar = static_cast(_owningAvatar); + return owningAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(_lookingInMirror ? + glm::vec3(_pitch, -_yaw, -_roll) : glm::vec3(_pitch, _yaw, _roll))); +} void Head::renderHeadSphere() { glPushMatrix(); @@ -341,9 +346,14 @@ void Head::renderMouth() { float s = sqrt(_averageLoudness); - glm::vec3 r = _orientation.getRight() * _scale * (0.30f + s * 0.0014f ); - glm::vec3 u = _orientation.getUp () * _scale * (0.05f + s * 0.0040f ); - glm::vec3 f = _orientation.getFront() * _scale * 0.09f; + glm::quat orientation = getOrientation(); + glm::vec3 right = orientation * IDENTITY_RIGHT; + glm::vec3 up = orientation * IDENTITY_UP; + glm::vec3 front = orientation * IDENTITY_FRONT; + + glm::vec3 r = right * _scale * (0.30f + s * 0.0014f ); + glm::vec3 u = up * _scale * (0.05f + s * 0.0040f ); + glm::vec3 f = front * _scale * 0.09f; glm::vec3 middle = _mouthPosition; glm::vec3 leftCorner = _mouthPosition - r * 1.0f; @@ -401,11 +411,16 @@ void Head::renderEyeBrows() { glm::vec3 rightTop = _leftEyePosition; glm::vec3 leftBottom = _leftEyePosition; glm::vec3 rightBottom = _leftEyePosition; - - glm::vec3 r = _orientation.getRight() * length; - glm::vec3 u = _orientation.getUp() * height; - glm::vec3 t = _orientation.getUp() * (height + width); - glm::vec3 f = _orientation.getFront() * _scale * -0.1f; + + glm::quat orientation = getOrientation(); + glm::vec3 right = orientation * IDENTITY_RIGHT; + glm::vec3 up = orientation * IDENTITY_UP; + glm::vec3 front = orientation * IDENTITY_FRONT; + + glm::vec3 r = right * length; + glm::vec3 u = up * height; + glm::vec3 t = up * (height + width); + glm::vec3 f = front * _scale * -0.1f; for (int i = 0; i < 2; i++) { @@ -473,6 +488,8 @@ void Head::renderEyeBalls() { gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30); glPopMatrix(); + glm::vec3 front = getFrontDirection(); + // render left iris glPushMatrix(); { glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position @@ -490,13 +507,13 @@ void Head::renderEyeBalls() { } else { //rotate the eyeball to aim straight ahead - glm::vec3 rotationAxisToHeadFront = glm::cross(_orientation.getFront(), IDENTITY_UP); - float angleToHeadFront = 180.0f - angleBetween(_orientation.getFront(), IDENTITY_UP); + glm::vec3 rotationAxisToHeadFront = glm::cross(front, IDENTITY_UP); + float angleToHeadFront = 180.0f - angleBetween(front, IDENTITY_UP); glRotatef(angleToHeadFront, rotationAxisToHeadFront.x, rotationAxisToHeadFront.y, rotationAxisToHeadFront.z); //set the amount of roll (for correction after previous rotations) - float rollRotation = angleBetween(_orientation.getFront(), IDENTITY_FRONT); - float dot = glm::dot(_orientation.getFront(), -IDENTITY_RIGHT); + float rollRotation = angleBetween(front, IDENTITY_FRONT); + float dot = glm::dot(front, -IDENTITY_RIGHT); if ( dot < 0.0f ) { rollRotation = -rollRotation; } glRotatef(rollRotation, 0.0f, 1.0f, 0.0f); //roll the iris or correct roll about the lookat vector } @@ -535,13 +552,13 @@ void Head::renderEyeBalls() { } else { //rotate the eyeball to aim straight ahead - glm::vec3 rotationAxisToHeadFront = glm::cross(_orientation.getFront(), IDENTITY_UP); - float angleToHeadFront = 180.0f - angleBetween(_orientation.getFront(), IDENTITY_UP); + glm::vec3 rotationAxisToHeadFront = glm::cross(front, IDENTITY_UP); + float angleToHeadFront = 180.0f - angleBetween(front, IDENTITY_UP); glRotatef(angleToHeadFront, rotationAxisToHeadFront.x, rotationAxisToHeadFront.y, rotationAxisToHeadFront.z); //set the amount of roll (for correction after previous rotations) - float rollRotation = angleBetween(_orientation.getFront(), IDENTITY_FRONT); - float dot = glm::dot(_orientation.getFront(), -IDENTITY_RIGHT); + float rollRotation = angleBetween(front, IDENTITY_FRONT); + float dot = glm::dot(front, -IDENTITY_RIGHT); if ( dot < 0.0f ) { rollRotation = -rollRotation; } glRotatef(rollRotation, 0.0f, 1.0f, 0.0f); //roll the iris or correct roll about the lookat vector } @@ -576,6 +593,11 @@ void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosi void Head::updateHairPhysics(float deltaTime) { + glm::quat orientation = getOrientation(); + glm::vec3 right = orientation * IDENTITY_RIGHT; + glm::vec3 up = orientation * IDENTITY_UP; + glm::vec3 front = orientation * IDENTITY_FRONT; + for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { float fraction = (float)t / (float)(NUM_HAIR_TUFTS - 1); @@ -584,8 +606,8 @@ void Head::updateHairPhysics(float deltaTime) { float radian = angle * PI_OVER_180; glm::vec3 baseDirection - = _orientation.getFront() * sinf(radian) - + _orientation.getUp() * cosf(radian); + = front * sinf(radian) + + up * cosf(radian); _hairTuft[t].basePosition = _position + _scale * 0.9f * baseDirection; @@ -601,13 +623,13 @@ void Head::updateHairPhysics(float deltaTime) { if (midLength > 0.0f) { midDirection = midAxis / midLength; } else { - midDirection = _orientation.getUp(); + midDirection = up; } if (endLength > 0.0f) { endDirection = endAxis / endLength; } else { - endDirection = _orientation.getUp(); + endDirection = up; } // add spring force @@ -652,13 +674,13 @@ void Head::updateHairPhysics(float deltaTime) { if (newMidLength > 0.0f) { newMidDirection = newMidVector/newMidLength; } else { - newMidDirection = _orientation.getUp(); + newMidDirection = up; } if (newEndLength > 0.0f) { newEndDirection = newEndVector/newEndLength; } else { - newEndDirection = _orientation.getUp(); + newEndDirection = up; } _hairTuft[t].endPosition = _hairTuft[t].midPosition + newEndDirection * _hairTuft[t].length * ONE_HALF; diff --git a/interface/src/Head.h b/interface/src/Head.h index b98fa8c6b6..3c755ebd3a 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -35,7 +35,7 @@ public: void reset(); void simulate(float deltaTime, bool isMine); void render(bool lookingInMirror, glm::vec3 cameraPosition, float alpha); - void renderMohawk(bool lookingInMirror, glm::vec3 cameraPosition); + void renderMohawk(glm::vec3 cameraPosition); void setScale (float scale ) { _scale = scale; } void setPosition (glm::vec3 position ) { _position = position; } @@ -46,7 +46,14 @@ public: void setAverageLoudness(float averageLoudness ) { _averageLoudness = averageLoudness; } void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } void setRenderLookatVectors(bool onOff ) { _renderLookatVectors = onOff; } - + + glm::quat getOrientation() const; + glm::quat getWorldAlignedOrientation () const; + + glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } + glm::vec3 getUpDirection () const { return getOrientation() * IDENTITY_UP; } + glm::vec3 getFrontDirection() const { return getOrientation() * IDENTITY_FRONT; } + const bool getReturnToCenter() const { return _returnHeadToCenter; } // Do you want head to try to return to center (depends on interface detected) float getAverageLoudness() {return _averageLoudness;}; glm::vec3 caclulateAverageEyePosition() { return _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; } @@ -91,8 +98,8 @@ private: float _averageLoudness; float _audioAttack; float _returnSpringScale; //strength of return springs - Orientation _orientation; glm::vec3 _bodyRotation; + bool _lookingInMirror; bool _renderLookatVectors; HairTuft _hairTuft[NUM_HAIR_TUFTS]; glm::vec3* _mohawkTriangleFan; @@ -106,7 +113,7 @@ private: void renderEars(); void renderMouth(); void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition); - void calculateGeometry( bool lookingInMirror); + void calculateGeometry(); void determineIfLookingAtSomething(); void resetHairPhysics(); void updateHairPhysics(float deltaTime); diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 2df1196a86..41b25ea776 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "Log.h" @@ -71,6 +72,65 @@ float angleBetween(const glm::vec3& v1, const glm::vec3& v2) { return acos((glm::dot(v1, v2)) / (glm::length(v1) * glm::length(v2))) * 180.f / PI; } +// Safe version of glm::eulerAngles; uses the factorization method described in David Eberly's +// http://www.geometrictools.com/Documentation/EulerAngles.pdf (via Clyde, +// https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java) +glm::vec3 safeEulerAngles(const glm::quat& q) { + float sy = 2.0f * (q.y * q.w - q.x * q.z); + if (sy < 1.0f - EPSILON) { + if (sy > -1.0f + EPSILON) { + return glm::degrees(glm::vec3( + atan2f(q.y * q.z + q.x * q.w, 0.5f - (q.x * q.x + q.y * q.y)), + asinf(sy), + atan2f(q.x * q.y + q.z * q.w, 0.5f - (q.y * q.y + q.z * q.z)))); + + } else { + // not a unique solution; x + z = atan2(-m21, m11) + return glm::degrees(glm::vec3( + 0.0f, + PIf * -0.5f, + atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z)))); + } + } else { + // not a unique solution; x - z = atan2(-m21, m11) + return glm::degrees(glm::vec3( + 0.0f, + PIf * 0.5f, + -atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z)))); + } +} + +// Safe version of glm::mix; based on the code in Nick Bobick's article, +// http://www.gamasutra.com/features/19980703/quaternions_01.htm (via Clyde, +// https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java) +glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float proportion) { + float cosa = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w; + float ox = q2.x, oy = q2.y, oz = q2.z, ow = q2.w, s0, s1; + + // adjust signs if necessary + if (cosa < 0.0f) { + cosa = -cosa; + ox = -ox; + oy = -oy; + oz = -oz; + ow = -ow; + } + + // calculate coefficients; if the angle is too close to zero, we must fall back + // to linear interpolation + if ((1.0f - cosa) > EPSILON) { + float angle = acosf(cosa), sina = sinf(angle); + s0 = sinf((1.0f - proportion) * angle) / sina; + s1 = sinf(proportion * angle) / sina; + + } else { + s0 = 1.0f - proportion; + s1 = proportion; + } + + return glm::normalize(glm::quat(s0 * q1.w + s1 * ow, s0 * q1.x + s1 * ox, s0 * q1.y + s1 * oy, s0 * q1.z + s1 * oz)); +} + // Draw a 3D vector floating in space void drawVector(glm::vec3 * vector) { glDisable(GL_LIGHTING); diff --git a/interface/src/Util.h b/interface/src/Util.h index 3264039067..d93267f175 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -46,6 +46,10 @@ void drawVector(glm::vec3* vector); float angleBetween(const glm::vec3& v1, const glm::vec3& v2); +glm::vec3 safeEulerAngles(const glm::quat& q); + +glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float alpha); + double diffclock(timeval *clock1,timeval *clock2); void drawGroundPlaneGrid(float size); diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 061727b003..2414103467 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -59,7 +59,7 @@ void ViewFrustum::calculate() { // find the intersections of the rays through the corners with the clip planes in view space, // then transform them to world space - glm::mat4 worldMatrix = glm::translate(_position) * glm::mat4(glm::mat3(_right, _up, -_direction)) * + glm::mat4 worldMatrix = glm::translate(_position) * glm::mat4(glm::mat3(_right, _up, _direction)) * glm::translate(_eyeOffsetPosition) * glm::mat4_cast(_eyeOffsetOrientation); _farTopLeft = glm::vec3(worldMatrix * glm::vec4(topLeft * (-farClipPlane.w / glm::dot(topLeft, glm::vec3(farClipPlane))), 1.0f)); From 021dce72be4f1ac82a8d25a7a79cce00c3f8cdc7 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 09:55:34 -0700 Subject: [PATCH 43/66] Moved direction vectors to AvatarData, made them align with OpenGL view space (to avoid the 180 degree rotations). --- interface/src/Application.cpp | 10 +++--- interface/src/Avatar.cpp | 52 +++++++++++++++--------------- interface/src/Avatar.h | 7 ++-- interface/src/Head.cpp | 48 +++++++++++++-------------- interface/src/Head.h | 7 ++-- libraries/avatars/src/AvatarData.h | 5 +++ 6 files changed, 66 insertions(+), 63 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dedfe315b1..9f06562aa5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -288,22 +288,22 @@ void Application::paintGL() { if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myCamera.setTightness (100.0f); _myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation()); + _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); } else if (OculusManager::isConnected()) { _myCamera.setUpShift (0.0f); _myCamera.setDistance (0.0f); _myCamera.setTightness (100.0f); _myCamera.setTargetPosition(_myAvatar.getHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getHead().getOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); + _myCamera.setTargetRotation(_myAvatar.getHead().getOrientation()); } else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { _myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); + _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation()); } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { _myCamera.setTargetPosition(_myAvatar.getHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); + _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation()); } // important... @@ -1111,7 +1111,7 @@ void Application::initMenu() { _window->setMenuBar(menuBar); QMenu* fileMenu = menuBar->addMenu("File"); - fileMenu->addAction("Quit", this, SLOT(quit()), (Qt::Key_Q || Qt::Key_Control)); + fileMenu->addAction("Quit", this, SLOT(quit()), Qt::CTRL | Qt::Key_Q); QMenu* pairMenu = menuBar->addMenu("Pair"); pairMenu->addAction("Pair", this, SLOT(pair())); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 27e9df1679..548c20af28 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -259,9 +259,9 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } glm::quat orientation = getOrientation(); - glm::vec3 front = orientation * IDENTITY_FRONT; - glm::vec3 right = orientation * IDENTITY_RIGHT; - glm::vec3 up = orientation * IDENTITY_UP; + glm::vec3 front = orientation * AVATAR_FRONT; + glm::vec3 right = orientation * AVATAR_RIGHT; + glm::vec3 up = orientation * AVATAR_UP; // driving the avatar around should only apply if this is my avatar (as opposed to an avatar being driven remotely) if (!_owningAgent) { @@ -331,8 +331,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { const float BODY_ROLL_WHILE_TURNING = 0.2; float forwardComponentOfVelocity = glm::dot(getBodyFrontDirection(), _velocity); orientation = orientation * glm::quat(glm::radians(glm::vec3( - BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, - -BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta))); + -BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, + BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta))); // these forces keep the body upright... float tiltDecay = BODY_UPRIGHT_FORCE * deltaTime; @@ -476,14 +476,14 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { glm::quat orientation = getOrientation(); // reset hand and arm positions according to hand movement - glm::vec3 right = orientation * IDENTITY_RIGHT; - glm::vec3 up = orientation * IDENTITY_UP; - glm::vec3 front = orientation * IDENTITY_FRONT; + glm::vec3 right = orientation * AVATAR_RIGHT; + glm::vec3 up = orientation * AVATAR_UP; + glm::vec3 front = orientation * AVATAR_FRONT; glm::vec3 transformedHandMovement = right * _movedHandOffset.x * 2.0f + up * -_movedHandOffset.y * 2.0f - + front * -_movedHandOffset.y * 2.0f; + + front * -_movedHandOffset.z * 2.0f; _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement; @@ -884,32 +884,32 @@ void Avatar::initializeSkeleton() { // specify the default pose position _joint[ AVATAR_JOINT_PELVIS ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.0 ); - _joint[ AVATAR_JOINT_TORSO ].defaultPosePosition = glm::vec3( 0.0, 0.09, 0.01 ); - _joint[ AVATAR_JOINT_CHEST ].defaultPosePosition = glm::vec3( 0.0, 0.09, 0.01 ); - _joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.14, -0.01 ); + _joint[ AVATAR_JOINT_TORSO ].defaultPosePosition = glm::vec3( 0.0, 0.09, -0.01 ); + _joint[ AVATAR_JOINT_CHEST ].defaultPosePosition = glm::vec3( 0.0, 0.09, -0.01 ); + _joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.14, 0.01 ); _joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.04, 0.00 ); - _joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3( 0.06, 0.04, -0.01 ); - _joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( 0.05, 0.0, -0.01 ); + _joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3( -0.06, 0.04, 0.01 ); + _joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.05, 0.0, 0.01 ); _joint[ AVATAR_JOINT_LEFT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.16, 0.0 ); _joint[ AVATAR_JOINT_LEFT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.117, 0.0 ); _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); - _joint[ AVATAR_JOINT_RIGHT_COLLAR ].defaultPosePosition = glm::vec3( -0.06, 0.04, -0.01 ); - _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( -0.05, 0.0, -0.01 ); + _joint[ AVATAR_JOINT_RIGHT_COLLAR ].defaultPosePosition = glm::vec3( 0.06, 0.04, 0.01 ); + _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( 0.05, 0.0, 0.01 ); _joint[ AVATAR_JOINT_RIGHT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.16, 0.0 ); _joint[ AVATAR_JOINT_RIGHT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.117, 0.0 ); _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); - _joint[ AVATAR_JOINT_LEFT_HIP ].defaultPosePosition = glm::vec3( 0.05, 0.0, -0.02 ); - _joint[ AVATAR_JOINT_LEFT_KNEE ].defaultPosePosition = glm::vec3( -0.01, -0.25, 0.03 ); - _joint[ AVATAR_JOINT_LEFT_HEEL ].defaultPosePosition = glm::vec3( -0.01, -0.22, -0.08 ); - _joint[ AVATAR_JOINT_LEFT_TOES ].defaultPosePosition = glm::vec3( 0.00, -0.03, 0.05 ); + _joint[ AVATAR_JOINT_LEFT_HIP ].defaultPosePosition = glm::vec3( -0.05, 0.0, 0.02 ); + _joint[ AVATAR_JOINT_LEFT_KNEE ].defaultPosePosition = glm::vec3( 0.01, -0.25, -0.03 ); + _joint[ AVATAR_JOINT_LEFT_HEEL ].defaultPosePosition = glm::vec3( 0.01, -0.22, 0.08 ); + _joint[ AVATAR_JOINT_LEFT_TOES ].defaultPosePosition = glm::vec3( 0.00, -0.03, -0.05 ); - _joint[ AVATAR_JOINT_RIGHT_HIP ].defaultPosePosition = glm::vec3( -0.05, 0.0, -0.02 ); - _joint[ AVATAR_JOINT_RIGHT_KNEE ].defaultPosePosition = glm::vec3( 0.01, -0.25, 0.03 ); - _joint[ AVATAR_JOINT_RIGHT_HEEL ].defaultPosePosition = glm::vec3( 0.01, -0.22, -0.08 ); - _joint[ AVATAR_JOINT_RIGHT_TOES ].defaultPosePosition = glm::vec3( 0.00, -0.03, 0.05 ); + _joint[ AVATAR_JOINT_RIGHT_HIP ].defaultPosePosition = glm::vec3( 0.05, 0.0, 0.02 ); + _joint[ AVATAR_JOINT_RIGHT_KNEE ].defaultPosePosition = glm::vec3( -0.01, -0.25, -0.03 ); + _joint[ AVATAR_JOINT_RIGHT_HEEL ].defaultPosePosition = glm::vec3( -0.01, -0.22, 0.08 ); + _joint[ AVATAR_JOINT_RIGHT_TOES ].defaultPosePosition = glm::vec3( 0.00, -0.03, -0.05 ); // specify the radii of the joints _joint[ AVATAR_JOINT_PELVIS ].radius = 0.07; @@ -1120,14 +1120,14 @@ void Avatar::updateArmIKAndConstraints(float deltaTime) { glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { glm::quat orientation = getOrientation(); - glm::vec3 currentUp = orientation * IDENTITY_UP; + glm::vec3 currentUp = orientation * AVATAR_UP; float angle = glm::degrees(acosf(glm::clamp(glm::dot(currentUp, _worldUpDirection), -1.0f, 1.0f))); if (angle < EPSILON) { return glm::quat(); } glm::vec3 axis; if (angle > 179.99f) { // 180 degree rotation; must use another axis - axis = orientation * IDENTITY_RIGHT; + axis = orientation * AVATAR_RIGHT; } else { axis = glm::normalize(glm::cross(currentUp, _worldUpDirection)); } diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index b84bb981ee..56e1a3d65a 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -11,7 +11,6 @@ #include #include #include -#include #include "world.h" #include "AvatarTouch.h" #include "InterfaceConfig.h" @@ -71,9 +70,9 @@ public: const glm::vec3& getHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].position;} const glm::vec3& getSpringyHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition;} const glm::vec3& getJointPosition (AvatarJointID j) const { return _joint[j].springyPosition;} - glm::vec3 getBodyRightDirection () const { return getOrientation() * IDENTITY_RIGHT; } - glm::vec3 getBodyUpDirection () const { return getOrientation() * IDENTITY_UP; } - glm::vec3 getBodyFrontDirection () const { return getOrientation() * IDENTITY_FRONT; } + glm::vec3 getBodyRightDirection () const { return getOrientation() * AVATAR_RIGHT; } + glm::vec3 getBodyUpDirection () const { return getOrientation() * AVATAR_UP; } + glm::vec3 getBodyFrontDirection () const { return getOrientation() * AVATAR_FRONT; } const glm::vec3& getVelocity () const { return _velocity;} float getSpeed () const { return _speed;} float getHeight () const { return _height;} diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index c04ddfb9ed..d1ee699dc8 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -172,9 +172,9 @@ void Head::determineIfLookingAtSomething() { void Head::calculateGeometry() { //generate orientation directions glm::quat orientation = getOrientation(); - glm::vec3 right = orientation * IDENTITY_RIGHT; - glm::vec3 up = orientation * IDENTITY_UP; - glm::vec3 front = orientation * IDENTITY_FRONT; + glm::vec3 right = orientation * AVATAR_RIGHT; + glm::vec3 up = orientation * AVATAR_UP; + glm::vec3 front = orientation * AVATAR_FRONT; //calculate the eye positions _leftEyePosition = _position @@ -347,9 +347,9 @@ void Head::renderMouth() { float s = sqrt(_averageLoudness); glm::quat orientation = getOrientation(); - glm::vec3 right = orientation * IDENTITY_RIGHT; - glm::vec3 up = orientation * IDENTITY_UP; - glm::vec3 front = orientation * IDENTITY_FRONT; + glm::vec3 right = orientation * AVATAR_RIGHT; + glm::vec3 up = orientation * AVATAR_UP; + glm::vec3 front = orientation * AVATAR_FRONT; glm::vec3 r = right * _scale * (0.30f + s * 0.0014f ); glm::vec3 u = up * _scale * (0.05f + s * 0.0040f ); @@ -415,9 +415,9 @@ void Head::renderEyeBrows() { glm::vec3 rightBottom = _leftEyePosition; glm::quat orientation = getOrientation(); - glm::vec3 right = orientation * IDENTITY_RIGHT; - glm::vec3 up = orientation * IDENTITY_UP; - glm::vec3 front = orientation * IDENTITY_FRONT; + glm::vec3 right = orientation * AVATAR_RIGHT; + glm::vec3 up = orientation * AVATAR_UP; + glm::vec3 front = orientation * AVATAR_FRONT; glm::vec3 r = right * length; glm::vec3 u = up * height; @@ -502,20 +502,20 @@ void Head::renderEyeBalls() { //rotate the eyeball to aim towards the lookat position glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - _leftEyePosition); // the lookat direction - glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP); - float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP); + glm::vec3 rotationAxis = glm::cross(targetLookatAxis, AVATAR_UP); + float angle = 180.0f - angleBetween(targetLookatAxis, AVATAR_UP); glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); glRotatef(180.0, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations } else { //rotate the eyeball to aim straight ahead - glm::vec3 rotationAxisToHeadFront = glm::cross(front, IDENTITY_UP); - float angleToHeadFront = 180.0f - angleBetween(front, IDENTITY_UP); + glm::vec3 rotationAxisToHeadFront = glm::cross(front, AVATAR_UP); + float angleToHeadFront = 180.0f - angleBetween(front, AVATAR_UP); glRotatef(angleToHeadFront, rotationAxisToHeadFront.x, rotationAxisToHeadFront.y, rotationAxisToHeadFront.z); //set the amount of roll (for correction after previous rotations) - float rollRotation = angleBetween(front, IDENTITY_FRONT); - float dot = glm::dot(front, -IDENTITY_RIGHT); + float rollRotation = angleBetween(front, AVATAR_FRONT); + float dot = glm::dot(front, -AVATAR_RIGHT); if ( dot < 0.0f ) { rollRotation = -rollRotation; } glRotatef(rollRotation, 0.0f, 1.0f, 0.0f); //roll the iris or correct roll about the lookat vector } @@ -546,21 +546,21 @@ void Head::renderEyeBalls() { //rotate the eyeball to aim towards the lookat position glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - _rightEyePosition); - glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP); - float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP); + glm::vec3 rotationAxis = glm::cross(targetLookatAxis, AVATAR_UP); + float angle = 180.0f - angleBetween(targetLookatAxis, AVATAR_UP); glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); glRotatef(180.0f, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations } else { //rotate the eyeball to aim straight ahead - glm::vec3 rotationAxisToHeadFront = glm::cross(front, IDENTITY_UP); - float angleToHeadFront = 180.0f - angleBetween(front, IDENTITY_UP); + glm::vec3 rotationAxisToHeadFront = glm::cross(front, AVATAR_UP); + float angleToHeadFront = 180.0f - angleBetween(front, AVATAR_UP); glRotatef(angleToHeadFront, rotationAxisToHeadFront.x, rotationAxisToHeadFront.y, rotationAxisToHeadFront.z); //set the amount of roll (for correction after previous rotations) - float rollRotation = angleBetween(front, IDENTITY_FRONT); - float dot = glm::dot(front, -IDENTITY_RIGHT); + float rollRotation = angleBetween(front, AVATAR_FRONT); + float dot = glm::dot(front, -AVATAR_RIGHT); if ( dot < 0.0f ) { rollRotation = -rollRotation; } glRotatef(rollRotation, 0.0f, 1.0f, 0.0f); //roll the iris or correct roll about the lookat vector } @@ -596,9 +596,9 @@ void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosi void Head::updateHairPhysics(float deltaTime) { glm::quat orientation = getOrientation(); - glm::vec3 right = orientation * IDENTITY_RIGHT; - glm::vec3 up = orientation * IDENTITY_UP; - glm::vec3 front = orientation * IDENTITY_FRONT; + glm::vec3 right = orientation * AVATAR_RIGHT; + glm::vec3 up = orientation * AVATAR_UP; + glm::vec3 front = orientation * AVATAR_FRONT; for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { diff --git a/interface/src/Head.h b/interface/src/Head.h index 3c755ebd3a..f49e127caf 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -14,7 +14,6 @@ #include "world.h" #include "InterfaceConfig.h" #include "SerialInterface.h" -#include "Orientation.h" #include enum eyeContactTargets @@ -50,9 +49,9 @@ public: glm::quat getOrientation() const; glm::quat getWorldAlignedOrientation () const; - glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } - glm::vec3 getUpDirection () const { return getOrientation() * IDENTITY_UP; } - glm::vec3 getFrontDirection() const { return getOrientation() * IDENTITY_FRONT; } + glm::vec3 getRightDirection() const { return getOrientation() * AVATAR_RIGHT; } + glm::vec3 getUpDirection () const { return getOrientation() * AVATAR_UP; } + glm::vec3 getFrontDirection() const { return getOrientation() * AVATAR_FRONT; } const bool getReturnToCenter() const { return _returnHeadToCenter; } // Do you want head to try to return to center (depends on interface detected) float getAverageLoudness() {return _averageLoudness;}; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 18bbacf810..49a31a7e6a 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -20,6 +20,11 @@ const int WANT_RESIN_AT_BIT = 0; const int WANT_COLOR_AT_BIT = 1; const int WANT_DELTA_AT_BIT = 2; +// this is where the coordinate system is represented +const glm::vec3 AVATAR_RIGHT = glm::vec3(1.0f, 0.0f, 0.0f); +const glm::vec3 AVATAR_UP = glm::vec3(0.0f, 1.0f, 0.0f); +const glm::vec3 AVATAR_FRONT = glm::vec3(0.0f, 0.0f, -1.0f); + enum KeyState { NO_KEY_DOWN, From b502321b573b901b75fdfc9bfd20665b6dc069ae Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 10:00:52 -0700 Subject: [PATCH 44/66] Moved gravity influence multiplier into constant, reduced. --- interface/src/Environment.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index 6bb127a87e..f762aaeed1 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -71,7 +71,8 @@ glm::vec3 Environment::getGravity (const glm::vec3& position) { foreach (const ServerData& serverData, _data) { foreach (const EnvironmentData& environmentData, serverData) { glm::vec3 vector = environmentData.getAtmosphereCenter() - position; - if (glm::length(vector) < environmentData.getAtmosphereOuterRadius() * 2.0f) { + const float GRAVITY_RADIUS_MULTIPLIER = 1.5f; + if (glm::length(vector) < environmentData.getAtmosphereOuterRadius() * GRAVITY_RADIUS_MULTIPLIER) { gravity += glm::normalize(vector) * environmentData.getGravity(); } } From fff9d1c37201042f73d9ba8f81bc660ab4d14509 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 10:23:19 -0700 Subject: [PATCH 45/66] Formatting. --- interface/src/Avatar.cpp | 95 +++++++++++++++++------------------ interface/src/Avatar.h | 47 +++++++++-------- interface/src/AvatarTouch.cpp | 4 +- interface/src/AvatarTouch.h | 4 +- interface/src/Camera.cpp | 2 +- 5 files changed, 76 insertions(+), 76 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 548c20af28..8b8b190003 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -77,7 +77,6 @@ Avatar::Avatar(Agent* owningAgent) : _bodyYawDelta(0.0f), _bodyRollDelta(0.0f), _movedHandOffset(0.0f, 0.0f, 0.0f), - _rotation(0.0f, 0.0f, 0.0f, 0.0f), _mode(AVATAR_MODE_STANDING), _cameraPosition(0.0f, 0.0f, 0.0f), _handHoldingPosition(0.0f, 0.0f, 0.0f), @@ -327,11 +326,11 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _speed = glm::length(_velocity); //pitch and roll the body as a function of forward speed and turning delta - const float BODY_PITCH_WHILE_WALKING = 20.0; + const float BODY_PITCH_WHILE_WALKING = -20.0; const float BODY_ROLL_WHILE_TURNING = 0.2; float forwardComponentOfVelocity = glm::dot(getBodyFrontDirection(), _velocity); orientation = orientation * glm::quat(glm::radians(glm::vec3( - -BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, + BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta))); // these forces keep the body upright... @@ -857,59 +856,59 @@ void Avatar::initializeSkeleton() { } // specify the parental hierarchy - _joint[ AVATAR_JOINT_PELVIS ].parent = AVATAR_JOINT_NULL; + _joint[ AVATAR_JOINT_PELVIS ].parent = AVATAR_JOINT_NULL; _joint[ AVATAR_JOINT_TORSO ].parent = AVATAR_JOINT_PELVIS; - _joint[ AVATAR_JOINT_CHEST ].parent = AVATAR_JOINT_TORSO; - _joint[ AVATAR_JOINT_NECK_BASE ].parent = AVATAR_JOINT_CHEST; + _joint[ AVATAR_JOINT_CHEST ].parent = AVATAR_JOINT_TORSO; + _joint[ AVATAR_JOINT_NECK_BASE ].parent = AVATAR_JOINT_CHEST; _joint[ AVATAR_JOINT_HEAD_BASE ].parent = AVATAR_JOINT_NECK_BASE; _joint[ AVATAR_JOINT_HEAD_TOP ].parent = AVATAR_JOINT_HEAD_BASE; _joint[ AVATAR_JOINT_LEFT_COLLAR ].parent = AVATAR_JOINT_CHEST; _joint[ AVATAR_JOINT_LEFT_SHOULDER ].parent = AVATAR_JOINT_LEFT_COLLAR; - _joint[ AVATAR_JOINT_LEFT_ELBOW ].parent = AVATAR_JOINT_LEFT_SHOULDER; - _joint[ AVATAR_JOINT_LEFT_WRIST ].parent = AVATAR_JOINT_LEFT_ELBOW; + _joint[ AVATAR_JOINT_LEFT_ELBOW ].parent = AVATAR_JOINT_LEFT_SHOULDER; + _joint[ AVATAR_JOINT_LEFT_WRIST ].parent = AVATAR_JOINT_LEFT_ELBOW; _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].parent = AVATAR_JOINT_LEFT_WRIST; _joint[ AVATAR_JOINT_RIGHT_COLLAR ].parent = AVATAR_JOINT_CHEST; - _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].parent = AVATAR_JOINT_RIGHT_COLLAR; + _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].parent = AVATAR_JOINT_RIGHT_COLLAR; _joint[ AVATAR_JOINT_RIGHT_ELBOW ].parent = AVATAR_JOINT_RIGHT_SHOULDER; _joint[ AVATAR_JOINT_RIGHT_WRIST ].parent = AVATAR_JOINT_RIGHT_ELBOW; _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].parent = AVATAR_JOINT_RIGHT_WRIST; - _joint[ AVATAR_JOINT_LEFT_HIP ].parent = AVATAR_JOINT_PELVIS; - _joint[ AVATAR_JOINT_LEFT_KNEE ].parent = AVATAR_JOINT_LEFT_HIP; - _joint[ AVATAR_JOINT_LEFT_HEEL ].parent = AVATAR_JOINT_LEFT_KNEE; - _joint[ AVATAR_JOINT_LEFT_TOES ].parent = AVATAR_JOINT_LEFT_HEEL; - _joint[ AVATAR_JOINT_RIGHT_HIP ].parent = AVATAR_JOINT_PELVIS; - _joint[ AVATAR_JOINT_RIGHT_KNEE ].parent = AVATAR_JOINT_RIGHT_HIP; - _joint[ AVATAR_JOINT_RIGHT_HEEL ].parent = AVATAR_JOINT_RIGHT_KNEE; - _joint[ AVATAR_JOINT_RIGHT_TOES ].parent = AVATAR_JOINT_RIGHT_HEEL; + _joint[ AVATAR_JOINT_LEFT_HIP ].parent = AVATAR_JOINT_PELVIS; + _joint[ AVATAR_JOINT_LEFT_KNEE ].parent = AVATAR_JOINT_LEFT_HIP; + _joint[ AVATAR_JOINT_LEFT_HEEL ].parent = AVATAR_JOINT_LEFT_KNEE; + _joint[ AVATAR_JOINT_LEFT_TOES ].parent = AVATAR_JOINT_LEFT_HEEL; + _joint[ AVATAR_JOINT_RIGHT_HIP ].parent = AVATAR_JOINT_PELVIS; + _joint[ AVATAR_JOINT_RIGHT_KNEE ].parent = AVATAR_JOINT_RIGHT_HIP; + _joint[ AVATAR_JOINT_RIGHT_HEEL ].parent = AVATAR_JOINT_RIGHT_KNEE; + _joint[ AVATAR_JOINT_RIGHT_TOES ].parent = AVATAR_JOINT_RIGHT_HEEL; // specify the default pose position - _joint[ AVATAR_JOINT_PELVIS ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.0 ); + _joint[ AVATAR_JOINT_PELVIS ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.0 ); _joint[ AVATAR_JOINT_TORSO ].defaultPosePosition = glm::vec3( 0.0, 0.09, -0.01 ); - _joint[ AVATAR_JOINT_CHEST ].defaultPosePosition = glm::vec3( 0.0, 0.09, -0.01 ); - _joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.14, 0.01 ); - _joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.04, 0.00 ); + _joint[ AVATAR_JOINT_CHEST ].defaultPosePosition = glm::vec3( 0.0, 0.09, -0.01 ); + _joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.14, 0.01 ); + _joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.04, 0.00 ); - _joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3( -0.06, 0.04, 0.01 ); - _joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.05, 0.0, 0.01 ); - _joint[ AVATAR_JOINT_LEFT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.16, 0.0 ); - _joint[ AVATAR_JOINT_LEFT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.117, 0.0 ); - _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); + _joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3( -0.06, 0.04, 0.01 ); + _joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.05, 0.0, 0.01 ); + _joint[ AVATAR_JOINT_LEFT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.16, 0.0 ); + _joint[ AVATAR_JOINT_LEFT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.117, 0.0 ); + _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); - _joint[ AVATAR_JOINT_RIGHT_COLLAR ].defaultPosePosition = glm::vec3( 0.06, 0.04, 0.01 ); - _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( 0.05, 0.0, 0.01 ); - _joint[ AVATAR_JOINT_RIGHT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.16, 0.0 ); + _joint[ AVATAR_JOINT_RIGHT_COLLAR ].defaultPosePosition = glm::vec3( 0.06, 0.04, 0.01 ); + _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( 0.05, 0.0, 0.01 ); + _joint[ AVATAR_JOINT_RIGHT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.16, 0.0 ); _joint[ AVATAR_JOINT_RIGHT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.117, 0.0 ); - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); + _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); - _joint[ AVATAR_JOINT_LEFT_HIP ].defaultPosePosition = glm::vec3( -0.05, 0.0, 0.02 ); - _joint[ AVATAR_JOINT_LEFT_KNEE ].defaultPosePosition = glm::vec3( 0.01, -0.25, -0.03 ); - _joint[ AVATAR_JOINT_LEFT_HEEL ].defaultPosePosition = glm::vec3( 0.01, -0.22, 0.08 ); - _joint[ AVATAR_JOINT_LEFT_TOES ].defaultPosePosition = glm::vec3( 0.00, -0.03, -0.05 ); + _joint[ AVATAR_JOINT_LEFT_HIP ].defaultPosePosition = glm::vec3( -0.05, 0.0, 0.02 ); + _joint[ AVATAR_JOINT_LEFT_KNEE ].defaultPosePosition = glm::vec3( 0.01, -0.25, -0.03 ); + _joint[ AVATAR_JOINT_LEFT_HEEL ].defaultPosePosition = glm::vec3( 0.01, -0.22, 0.08 ); + _joint[ AVATAR_JOINT_LEFT_TOES ].defaultPosePosition = glm::vec3( 0.00, -0.03, -0.05 ); - _joint[ AVATAR_JOINT_RIGHT_HIP ].defaultPosePosition = glm::vec3( 0.05, 0.0, 0.02 ); - _joint[ AVATAR_JOINT_RIGHT_KNEE ].defaultPosePosition = glm::vec3( -0.01, -0.25, -0.03 ); - _joint[ AVATAR_JOINT_RIGHT_HEEL ].defaultPosePosition = glm::vec3( -0.01, -0.22, 0.08 ); - _joint[ AVATAR_JOINT_RIGHT_TOES ].defaultPosePosition = glm::vec3( 0.00, -0.03, -0.05 ); + _joint[ AVATAR_JOINT_RIGHT_HIP ].defaultPosePosition = glm::vec3( 0.05, 0.0, 0.02 ); + _joint[ AVATAR_JOINT_RIGHT_KNEE ].defaultPosePosition = glm::vec3( -0.01, -0.25, -0.03 ); + _joint[ AVATAR_JOINT_RIGHT_HEEL ].defaultPosePosition = glm::vec3( -0.01, -0.22, 0.08 ); + _joint[ AVATAR_JOINT_RIGHT_TOES ].defaultPosePosition = glm::vec3( 0.00, -0.03, -0.05 ); // specify the radii of the joints _joint[ AVATAR_JOINT_PELVIS ].radius = 0.07; @@ -920,25 +919,25 @@ void Avatar::initializeSkeleton() { _joint[ AVATAR_JOINT_LEFT_COLLAR ].radius = 0.04; _joint[ AVATAR_JOINT_LEFT_SHOULDER ].radius = 0.03; - _joint[ AVATAR_JOINT_LEFT_ELBOW ].radius = 0.02; + _joint[ AVATAR_JOINT_LEFT_ELBOW ].radius = 0.02; _joint[ AVATAR_JOINT_LEFT_WRIST ].radius = 0.02; _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].radius = 0.01; _joint[ AVATAR_JOINT_RIGHT_COLLAR ].radius = 0.04; - _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].radius = 0.03; + _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].radius = 0.03; _joint[ AVATAR_JOINT_RIGHT_ELBOW ].radius = 0.02; _joint[ AVATAR_JOINT_RIGHT_WRIST ].radius = 0.02; _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].radius = 0.01; - _joint[ AVATAR_JOINT_LEFT_HIP ].radius = 0.04; - _joint[ AVATAR_JOINT_LEFT_KNEE ].radius = 0.025; - _joint[ AVATAR_JOINT_LEFT_HEEL ].radius = 0.025; - _joint[ AVATAR_JOINT_LEFT_TOES ].radius = 0.025; + _joint[ AVATAR_JOINT_LEFT_HIP ].radius = 0.04; + _joint[ AVATAR_JOINT_LEFT_KNEE ].radius = 0.025; + _joint[ AVATAR_JOINT_LEFT_HEEL ].radius = 0.025; + _joint[ AVATAR_JOINT_LEFT_TOES ].radius = 0.025; - _joint[ AVATAR_JOINT_RIGHT_HIP ].radius = 0.04; - _joint[ AVATAR_JOINT_RIGHT_KNEE ].radius = 0.025; - _joint[ AVATAR_JOINT_RIGHT_HEEL ].radius = 0.025; - _joint[ AVATAR_JOINT_RIGHT_TOES ].radius = 0.025; + _joint[ AVATAR_JOINT_RIGHT_HIP ].radius = 0.04; + _joint[ AVATAR_JOINT_RIGHT_KNEE ].radius = 0.025; + _joint[ AVATAR_JOINT_RIGHT_HEEL ].radius = 0.025; + _joint[ AVATAR_JOINT_RIGHT_TOES ].radius = 0.025; // to aid in hand-shaking and hand-holding, the right hand is not collidable _joint[ AVATAR_JOINT_RIGHT_ELBOW ].isCollidable = false; diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 56e1a3d65a..262051655e 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -64,23 +64,23 @@ public: void setOrientation (const glm::quat& orientation); //getters - float getHeadYawRate () const { return _head.yawRate;} - float getBodyYaw () const { return _bodyYaw;} - bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();} - const glm::vec3& getHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].position;} - const glm::vec3& getSpringyHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition;} - const glm::vec3& getJointPosition (AvatarJointID j) const { return _joint[j].springyPosition;} - glm::vec3 getBodyRightDirection () const { return getOrientation() * AVATAR_RIGHT; } - glm::vec3 getBodyUpDirection () const { return getOrientation() * AVATAR_UP; } - glm::vec3 getBodyFrontDirection () const { return getOrientation() * AVATAR_FRONT; } - const glm::vec3& getVelocity () const { return _velocity;} - float getSpeed () const { return _speed;} - float getHeight () const { return _height;} - AvatarMode getMode () const { return _mode;} - float getAbsoluteHeadYaw () const; - float getAbsoluteHeadPitch () const; - Head& getHead () {return _head; } - glm::quat getOrientation () const; + float getHeadYawRate () const { return _head.yawRate;} + float getBodyYaw () const { return _bodyYaw;} + bool getIsNearInteractingOther () const { return _avatarTouch.getAbleToReachOtherAvatar();} + const glm::vec3& getHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].position;} + const glm::vec3& getSpringyHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition;} + const glm::vec3& getJointPosition (AvatarJointID j) const { return _joint[j].springyPosition;} + glm::vec3 getBodyRightDirection () const { return getOrientation() * AVATAR_RIGHT; } + glm::vec3 getBodyUpDirection () const { return getOrientation() * AVATAR_UP; } + glm::vec3 getBodyFrontDirection () const { return getOrientation() * AVATAR_FRONT; } + const glm::vec3& getVelocity () const { return _velocity;} + float getSpeed () const { return _speed;} + float getHeight () const { return _height;} + AvatarMode getMode () const { return _mode;} + float getAbsoluteHeadYaw () const; + float getAbsoluteHeadPitch () const; + Head& getHead () { return _head; } + glm::quat getOrientation () const; glm::quat getWorldAlignedOrientation () const; // Set what driving keys are being pressed to control thrust levels @@ -103,13 +103,13 @@ private: struct AvatarJoint { AvatarJointID parent; // which joint is this joint connected to? - glm::vec3 position; // the position at the "end" of the joint - in global space - glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the "T-pose" - glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position) - glm::vec3 springyVelocity; // used for special effects ( the velocity of the springy position) - float springBodyTightness; // how tightly the springy position tries to stay on the position + glm::vec3 position; // the position at the "end" of the joint - in global space + glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the "T-pose" + glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position) + glm::vec3 springyVelocity; // used for special effects ( the velocity of the springy position) + float springBodyTightness; // how tightly the springy position tries to stay on the position glm::quat orientation; // this will eventually replace yaw, pitch and roll (and maybe orientation) - float length; // the length of vector connecting the joint and its parent + float length; // the length of vector connecting the joint and its parent float radius; // used for detecting collisions for certain physical effects bool isCollidable; // when false, the joint position will not register a collision float touchForce; // if being touched, what's the degree of influence? (0 to 1) @@ -124,7 +124,6 @@ private: float _bodyYawDelta; float _bodyRollDelta; glm::vec3 _movedHandOffset; - glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion AvatarJoint _joint[ NUM_AVATAR_JOINTS ]; AvatarMode _mode; glm::vec3 _cameraPosition; diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 58da2c3241..2415d030c8 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -47,8 +47,8 @@ void AvatarTouch::simulate (float deltaTime) { bool facingEachOther = false; - glm::vec3 myFront = _myOrientation * IDENTITY_FRONT; - glm::vec3 yourFront = _yourOrientation * IDENTITY_FRONT; + glm::vec3 myFront = _myOrientation * AVATAR_FRONT; + glm::vec3 yourFront = _yourOrientation * AVATAR_FRONT; if (( glm::dot(myFront, yourFront) < -AVATAR_FACING_THRESHOLD) // we're facing each other && ( glm::dot(myFront, directionBetweenBodies ) > AVATAR_FACING_THRESHOLD)) { // I'm facing you diff --git a/interface/src/AvatarTouch.h b/interface/src/AvatarTouch.h index 32a0b29274..da550432eb 100644 --- a/interface/src/AvatarTouch.h +++ b/interface/src/AvatarTouch.h @@ -9,7 +9,9 @@ #define __interface__AvatarTouch__ #include -#include "Orientation.h" +#include + +#include enum AvatarHandState { diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 984de67462..0850006086 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -98,7 +98,7 @@ void Camera::updateFollowMode(float deltaTime) { _idealPosition = _targetPosition + _rotation * glm::vec3(0.0f, _upShift, _distance); - if (_needsToInitialize || true) { + if (_needsToInitialize) { _position = _idealPosition; _needsToInitialize = false; } else { From 3330b2023221c075ebd3a90f8381e302ee768185 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 10:33:45 -0700 Subject: [PATCH 46/66] More reformatting. --- interface/src/Camera.cpp | 6 ++--- interface/src/Camera.h | 55 ++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 0850006086..21e60c0cc5 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -90,10 +90,10 @@ void Camera::updateFollowMode(float deltaTime) { // update rotation (before position!) if (_needsToInitialize || OculusManager::isConnected()) { - _rotation = _idealRotation; + _rotation = _targetRotation; } else { // pull rotation towards ideal - _rotation = safeMix(_rotation, _idealRotation, t); + _rotation = safeMix(_rotation, _targetRotation, t); } _idealPosition = _targetPosition + _rotation * glm::vec3(0.0f, _upShift, _distance); @@ -145,7 +145,7 @@ void Camera::setMode(CameraMode m) { void Camera::setTargetRotation( const glm::quat& targetRotation ) { - _idealRotation = targetRotation; + _targetRotation = targetRotation; } void Camera::setFieldOfView(float f) { diff --git a/interface/src/Camera.h b/interface/src/Camera.h index f1eb764aab..4d56774326 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -30,35 +30,36 @@ public: void update( float deltaTime ); - void setUpShift ( float u ) { _upShift = u; } - void setDistance ( float d ) { _distance = d; } - void setTargetPosition( glm::vec3 t ) { _targetPosition = t; } - void setPosition ( glm::vec3 p ) { _position = p; } - void setTightness ( float t ) { _tightness = t; } + void setUpShift ( float u ) { _upShift = u; } + void setDistance ( float d ) { _distance = d; } + void setTargetPosition( const glm::vec3& t ) { _targetPosition = t; } + void setPosition ( const glm::vec3& p ) { _position = p; } + void setTightness ( float t ) { _tightness = t; } void setTargetRotation( const glm::quat& rotation ); - void setMode ( CameraMode m ); - void setModeShiftRate ( float r ); - void setFieldOfView ( float f ); - void setAspectRatio ( float a ); - void setNearClip ( float n ); - void setFarClip ( float f ); - void setEyeOffsetPosition ( const glm::vec3& p); - void setEyeOffsetOrientation ( const glm::quat& o); + void setMode ( CameraMode m ); + void setModeShiftRate ( float r ); + void setFieldOfView ( float f ); + void setAspectRatio ( float a ); + void setNearClip ( float n ); + void setFarClip ( float f ); + void setEyeOffsetPosition ( const glm::vec3& p ); + void setEyeOffsetOrientation( const glm::quat& o ); - glm::vec3 getTargetPosition () { return _targetPosition; } - glm::vec3 getPosition () { return _position; } - glm::quat getTargetRotation () { return _idealRotation; } - glm::quat getRotation () { return _rotation; } - CameraMode getMode () { return _mode; } - float getFieldOfView() { return _fieldOfView; } - float getAspectRatio() { return _aspectRatio; } - float getNearClip () { return _nearClip; } - float getFarClip () { return _farClip; } - glm::vec3 getEyeOffsetPosition () { return _eyeOffsetPosition; } - glm::quat getEyeOffsetOrientation () { return _eyeOffsetOrientation; } - bool getFrustumNeedsReshape(); // call to find out if the view frustum needs to be reshaped - void setFrustumWasReshaped(); // call this after reshaping the view frustum. + const glm::vec3& getTargetPosition () { return _targetPosition; } + const glm::vec3& getPosition () { return _position; } + const glm::quat& getTargetRotation () { return _targetRotation; } + const glm::quat& getRotation () { return _rotation; } + CameraMode getMode () { return _mode; } + float getFieldOfView () { return _fieldOfView; } + float getAspectRatio () { return _aspectRatio; } + float getNearClip () { return _nearClip; } + float getFarClip () { return _farClip; } + const glm::vec3& getEyeOffsetPosition () { return _eyeOffsetPosition; } + const glm::quat& getEyeOffsetOrientation () { return _eyeOffsetOrientation; } + + bool getFrustumNeedsReshape(); // call to find out if the view frustum needs to be reshaped + void setFrustumWasReshaped(); // call this after reshaping the view frustum. private: @@ -75,7 +76,7 @@ private: glm::vec3 _eyeOffsetPosition; glm::quat _eyeOffsetOrientation; glm::quat _rotation; - glm::quat _idealRotation; + glm::quat _targetRotation; float _upShift; float _distance; float _tightness; From 100d10dc9eed3e811963fd3ad92b03d7e5d540dc Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 11:08:33 -0700 Subject: [PATCH 47/66] Offset camera fix, cleaner frustum transformation. --- interface/src/Application.cpp | 9 +++++---- libraries/voxels/src/ViewFrustum.cpp | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9f06562aa5..3def951b14 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -338,6 +338,7 @@ void Application::paintGL() { _viewFrustumOffsetPitch, _viewFrustumOffsetYaw, _viewFrustumOffsetRoll)))); _viewFrustumOffsetCamera.setUpShift (_viewFrustumOffsetUp ); _viewFrustumOffsetCamera.setDistance (_viewFrustumOffsetDistance); + _viewFrustumOffsetCamera.initialize(); // force immediate snap to ideal position and orientation _viewFrustumOffsetCamera.update(1.f/_fps); whichCamera = _viewFrustumOffsetCamera; } @@ -1381,9 +1382,9 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { float farClip = camera.getFarClip(); glm::quat rotation = camera.getRotation(); - glm::vec3 direction = rotation * IDENTITY_FRONT; - glm::vec3 up = rotation * IDENTITY_UP; - glm::vec3 right = rotation * IDENTITY_RIGHT; + glm::vec3 direction = rotation * AVATAR_FRONT; + glm::vec3 up = rotation * AVATAR_UP; + glm::vec3 right = rotation * AVATAR_RIGHT; /* printf("position.x=%f, position.y=%f, position.z=%f\n", position.x, position.y, position.z); @@ -1398,7 +1399,7 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { // Set the viewFrustum up with the correct position and orientation of the camera viewFrustum.setPosition(position); - viewFrustum.setOrientation(direction,up,-right); + viewFrustum.setOrientation(direction,up,right); // Also make sure it's got the correct lens details from the camera viewFrustum.setFieldOfView(fov); diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 2414103467..061727b003 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -59,7 +59,7 @@ void ViewFrustum::calculate() { // find the intersections of the rays through the corners with the clip planes in view space, // then transform them to world space - glm::mat4 worldMatrix = glm::translate(_position) * glm::mat4(glm::mat3(_right, _up, _direction)) * + glm::mat4 worldMatrix = glm::translate(_position) * glm::mat4(glm::mat3(_right, _up, -_direction)) * glm::translate(_eyeOffsetPosition) * glm::mat4_cast(_eyeOffsetOrientation); _farTopLeft = glm::vec3(worldMatrix * glm::vec4(topLeft * (-farClipPlane.w / glm::dot(topLeft, glm::vec3(farClipPlane))), 1.0f)); From 342e19aa4153fdf3939f1b6d61513db7ca6a554a Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 12:12:30 -0700 Subject: [PATCH 48/66] Save/restore the pitch and roll as well as the yaw. --- interface/src/Avatar.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 8b8b190003..cff577d4b5 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1250,7 +1250,7 @@ void Avatar::writeAvatarDataToFile() { FILE* avatarFile = fopen(AVATAR_DATA_FILENAME, "w"); if (avatarFile) { - fprintf(avatarFile, "%f,%f,%f %f", _position.x, _position.y, _position.z, _bodyYaw); + fprintf(avatarFile, "%f,%f,%f %f,%f,%f", _position.x, _position.y, _position.z, _bodyYaw, _bodyPitch, _bodyRoll); fclose(avatarFile); } } @@ -1260,13 +1260,17 @@ void Avatar::readAvatarDataFromFile() { if (avatarFile) { glm::vec3 readPosition; - float readYaw; - fscanf(avatarFile, "%f,%f,%f %f", &readPosition.x, &readPosition.y, &readPosition.z, &readYaw); + float readYaw, readPitch, readRoll; + fscanf(avatarFile, "%f,%f,%f %f,%f,%f", &readPosition.x, &readPosition.y, &readPosition.z, + &readYaw, &readPitch, &readRoll); // make sure these values are sane - if (!isnan(readPosition.x) && !isnan(readPosition.y) && !isnan(readPosition.z) && !isnan(readYaw)) { + 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); } From 28531fcae006391e7b0295bee85bde194876b3e1 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 12:33:05 -0700 Subject: [PATCH 49/66] Added --local option to avatar-mixer for testing. Only update velocity, acceleration, angular velocity, etc., for local avatar. --- avatar-mixer/src/main.cpp | 8 ++ interface/src/Avatar.cpp | 156 +++++++++++++++++++------------------- 2 files changed, 85 insertions(+), 79 deletions(-) diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index 89861ddcc8..f6d78fd8c5 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -55,6 +55,14 @@ int main(int argc, const char* argv[]) { AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT); setvbuf(stdout, NULL, _IOLBF, 0); + // Handle Local Domain testing with the --local command line + const char* local = "--local"; + if (cmdOptionExists(argc, argv, local)) { + printf("Local Domain MODE!\n"); + int ip = getLocalAddress(); + sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); + } + agentList->linkedDataCreateCallback = attachAvatarDataToAgent; agentList->startDomainServerCheckInThread(); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index cff577d4b5..7aaee8d62e 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -304,96 +304,94 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { up; } } - } - - // update body yaw by body yaw delta - if (!_owningAgent) { + + // update body yaw by body yaw delta orientation = orientation * glm::quat(glm::radians( glm::vec3(_bodyPitchDelta, _bodyYawDelta, _bodyRollDelta) * deltaTime)); - } - - // decay body rotation momentum - float bodySpinMomentum = 1.0 - BODY_SPIN_FRICTION * deltaTime; - if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; } - _bodyPitchDelta *= bodySpinMomentum; - _bodyYawDelta *= bodySpinMomentum; - _bodyRollDelta *= bodySpinMomentum; + + // decay body rotation momentum + float bodySpinMomentum = 1.0 - BODY_SPIN_FRICTION * deltaTime; + if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; } + _bodyPitchDelta *= bodySpinMomentum; + _bodyYawDelta *= bodySpinMomentum; + _bodyRollDelta *= bodySpinMomentum; + + // add thrust to velocity + _velocity += _thrust * deltaTime; - // add thrust to velocity - _velocity += _thrust * deltaTime; - - // calculate speed - _speed = glm::length(_velocity); - - //pitch and roll the body as a function of forward speed and turning delta - const float BODY_PITCH_WHILE_WALKING = -20.0; - const float BODY_ROLL_WHILE_TURNING = 0.2; - float forwardComponentOfVelocity = glm::dot(getBodyFrontDirection(), _velocity); - orientation = orientation * glm::quat(glm::radians(glm::vec3( - BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, - BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta))); - - // these forces keep the body upright... - float tiltDecay = BODY_UPRIGHT_FORCE * deltaTime; - if (tiltDecay > 1.0f) {tiltDecay = 1.0f;} + // calculate speed + _speed = glm::length(_velocity); + + //pitch and roll the body as a function of forward speed and turning delta + const float BODY_PITCH_WHILE_WALKING = -20.0; + const float BODY_ROLL_WHILE_TURNING = 0.2; + float forwardComponentOfVelocity = glm::dot(getBodyFrontDirection(), _velocity); + orientation = orientation * glm::quat(glm::radians(glm::vec3( + BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, + BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta))); + + // these forces keep the body upright... + float tiltDecay = BODY_UPRIGHT_FORCE * deltaTime; + if (tiltDecay > 1.0f) {tiltDecay = 1.0f;} - // update the euler angles - setOrientation(orientation); + // update the euler angles + setOrientation(orientation); - //the following will be used to make the avatar upright no matter what gravity is - setOrientation(computeRotationFromBodyToWorldUp(tiltDecay) * orientation); + //the following will be used to make the avatar upright no matter what gravity is + setOrientation(computeRotationFromBodyToWorldUp(tiltDecay) * orientation); - // update position by velocity - _position += _velocity * deltaTime; + // update position by velocity + _position += _velocity * deltaTime; - // decay velocity - float decay = 1.0 - VELOCITY_DECAY * deltaTime; - if ( decay < 0.0 ) { - _velocity = glm::vec3( 0.0f, 0.0f, 0.0f ); - } else { - _velocity *= decay; - } - - // If another avatar is near, dampen velocity as a function of closeness - if (!_owningAgent && (_distanceToNearestAvatar < PERIPERSONAL_RADIUS)) { - float closeness = 1.0f - (_distanceToNearestAvatar / PERIPERSONAL_RADIUS); - float drag = 1.0f - closeness * AVATAR_BRAKING_STRENGTH * deltaTime; - if ( drag > 0.0f ) { - _velocity *= drag; - } else { + // decay velocity + float decay = 1.0 - VELOCITY_DECAY * deltaTime; + if ( decay < 0.0 ) { _velocity = glm::vec3( 0.0f, 0.0f, 0.0f ); + } else { + _velocity *= decay; + } + + // If another avatar is near, dampen velocity as a function of closeness + if (_distanceToNearestAvatar < PERIPERSONAL_RADIUS) { + float closeness = 1.0f - (_distanceToNearestAvatar / PERIPERSONAL_RADIUS); + float drag = 1.0f - closeness * AVATAR_BRAKING_STRENGTH * deltaTime; + if ( drag > 0.0f ) { + _velocity *= drag; + } else { + _velocity = glm::vec3( 0.0f, 0.0f, 0.0f ); + } + } + + // Compute instantaneous acceleration + float acceleration = glm::distance(getVelocity(), oldVelocity) / deltaTime; + const float ACCELERATION_PITCH_DECAY = 0.4f; + const float ACCELERATION_YAW_DECAY = 0.4f; + + const float OCULUS_ACCELERATION_PULL_THRESHOLD = 1.0f; + const int OCULUS_YAW_OFFSET_THRESHOLD = 10; + + // Decay HeadPitch as a function of acceleration, so that you look straight ahead when + // you start moving, but don't do this with an HMD like the Oculus. + if (!OculusManager::isConnected()) { + _head.setPitch(_head.getPitch() * (1.f - acceleration * ACCELERATION_PITCH_DECAY * deltaTime)); + _head.setYaw(_head.getYaw() * (1.f - acceleration * ACCELERATION_YAW_DECAY * deltaTime)); + } else if (fabsf(acceleration) > OCULUS_ACCELERATION_PULL_THRESHOLD + && fabs(_head.getYaw()) > OCULUS_YAW_OFFSET_THRESHOLD) { + // if we're wearing the oculus + // and this acceleration is above the pull threshold + // and the head yaw if off the body by more than OCULUS_YAW_OFFSET_THRESHOLD + + // match the body yaw to the oculus yaw + _bodyYaw = getAbsoluteHeadYaw(); + + // set the head yaw to zero for this draw + _head.setYaw(0); + + // correct the oculus yaw offset + OculusManager::updateYawOffset(); } } - // Compute instantaneous acceleration - float acceleration = glm::distance(getVelocity(), oldVelocity) / deltaTime; - const float ACCELERATION_PITCH_DECAY = 0.4f; - const float ACCELERATION_YAW_DECAY = 0.4f; - - const float OCULUS_ACCELERATION_PULL_THRESHOLD = 1.0f; - const int OCULUS_YAW_OFFSET_THRESHOLD = 10; - - // Decay HeadPitch as a function of acceleration, so that you look straight ahead when - // you start moving, but don't do this with an HMD like the Oculus. - if (!OculusManager::isConnected()) { - _head.setPitch(_head.getPitch() * (1.f - acceleration * ACCELERATION_PITCH_DECAY * deltaTime)); - _head.setYaw(_head.getYaw() * (1.f - acceleration * ACCELERATION_YAW_DECAY * deltaTime)); - } else if (fabsf(acceleration) > OCULUS_ACCELERATION_PULL_THRESHOLD - && fabs(_head.getYaw()) > OCULUS_YAW_OFFSET_THRESHOLD) { - // if we're wearing the oculus - // and this acceleration is above the pull threshold - // and the head yaw if off the body by more than OCULUS_YAW_OFFSET_THRESHOLD - - // match the body yaw to the oculus yaw - _bodyYaw = getAbsoluteHeadYaw(); - - // set the head yaw to zero for this draw - _head.setYaw(0); - - // correct the oculus yaw offset - OculusManager::updateYawOffset(); - } - //apply the head lean values to the springy position... if (USING_HEAD_LEAN) { if (fabs(_head.getLeanSideways() + _head.getLeanForward()) > 0.0f) { From bcd3833898057d4d8db13c87e7300be2a4bdcb2a Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 13:46:53 -0700 Subject: [PATCH 50/66] Align chat with full camera rotation (not just yaw). --- interface/src/Application.cpp | 4 ++-- interface/src/Application.h | 1 + interface/src/Avatar.cpp | 20 ++++++++------------ interface/src/Avatar.h | 2 +- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3def951b14..e023cce81f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1667,13 +1667,13 @@ void Application::displaySide(Camera& whichCamera) { for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) { Avatar *avatar = (Avatar *)agent->getLinkedData(); - avatar->render(false, _myCamera.getPosition()); + avatar->render(false); } } agentList->unlock(); // Render my own Avatar - _myAvatar.render(_lookingInMirror->isChecked(), _myCamera.getPosition()); + _myAvatar.render(_lookingInMirror->isChecked()); _myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked()); } diff --git a/interface/src/Application.h b/interface/src/Application.h index f611a803b9..64959f1274 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -63,6 +63,7 @@ public: void wheelEvent(QWheelEvent* event); Avatar* getAvatar() { return &_myAvatar; } + Camera* getCamera() { return &_myCamera; } VoxelSystem* getVoxels() { return &_voxels; } Environment* getEnvironment() { return &_environment; } bool shouldEchoAudio() { return _echoAudioMode->isChecked(); } diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 7aaee8d62e..8f6ac7c991 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -758,9 +758,9 @@ void Avatar::setGravity(glm::vec3 gravity) { } } -void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { +void Avatar::render(bool lookingInMirror) { - _cameraPosition = cameraPosition; + _cameraPosition = Application::getInstance()->getCamera()->getPosition(); if (!_owningAgent && usingBigSphereCollisionTest) { // show TEST big sphere @@ -799,18 +799,14 @@ void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { } glPushMatrix(); - // extract the view direction from the modelview matrix: transform (0, 0, 1) by the - // transpose of the modelview to get its direction in world space, then use the X/Z - // components to determine the angle - float modelview[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, modelview); - - glTranslatef(_joint[AVATAR_JOINT_HEAD_BASE].springyPosition.x, - _joint[AVATAR_JOINT_HEAD_BASE].springyPosition.y + chatMessageHeight, - _joint[AVATAR_JOINT_HEAD_BASE].springyPosition.z); - glRotatef(atan2(-modelview[2], -modelview[10]) * 180 / PI, 0, 1, 0); + glm::vec3 chatPosition = _joint[AVATAR_JOINT_HEAD_BASE].springyPosition + getBodyUpDirection() * chatMessageHeight; + glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z); + glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation(); + glm::vec3 chatAxis = glm::axis(chatRotation); + glRotatef(glm::angle(chatRotation), chatAxis.x, chatAxis.y, chatAxis.z); glColor3f(0, 0.8, 0); + glRotatef(180, 0, 1, 0); glRotatef(180, 0, 0, 1); glScalef(chatMessageScale, chatMessageScale, 1.0f); diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 262051655e..db8176898a 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -51,7 +51,7 @@ public: void updateHeadFromGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity); void updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight); void addBodyYaw(float y) {_bodyYaw += y;}; - void render(bool lookingInMirror, glm::vec3 cameraPosition); + void render(bool lookingInMirror); //setters void setMousePressed (bool mousePressed ) { _mousePressed = mousePressed;} From 0a3dbcd675a1aec9bb7d1fdb695ab3c01a2e67d6 Mon Sep 17 00:00:00 2001 From: Geenz Date: Thu, 30 May 2013 17:00:32 -0400 Subject: [PATCH 51/66] Removed unused readYaw variable. --- interface/src/Avatar.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 05dbeb8fe1..371bd59660 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1249,7 +1249,6 @@ void Avatar::writeAvatarDataToFile() { void Avatar::readAvatarDataFromFile() { glm::vec3 readPosition; glm::vec3 readRotation; - float readYaw; Application::getInstance()->getSettingVec3("avatarPos", readPosition, glm::vec3(6.1f, 0, 1.4f)); Application::getInstance()->getSettingVec3("avatarRotation", readRotation, glm::vec3(0, 0, 0)); From f447230d26b28be3495424d7bf6366291d8032f2 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 14:14:01 -0700 Subject: [PATCH 52/66] Use body orientation, not head orientation, for mirror mode. --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e023cce81f..1e9e119777 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -288,7 +288,7 @@ void Application::paintGL() { if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myCamera.setTightness (100.0f); _myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); + _myCamera.setTargetRotation(_myAvatar.getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); } else if (OculusManager::isConnected()) { _myCamera.setUpShift (0.0f); From e2ec8245b0752b8b52cb2b05b8eb4f39ca072e09 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 14:56:12 -0700 Subject: [PATCH 53/66] Rather than adding Euler angles, compose quaternions for gyros. --- interface/src/Application.cpp | 2 +- interface/src/Avatar.cpp | 10 +++++----- interface/src/Avatar.h | 2 +- interface/src/Head.cpp | 7 +++++++ interface/src/Head.h | 1 + 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1e9e119777..262bf6625a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1274,7 +1274,7 @@ void Application::init() { void Application::updateAvatar(float deltaTime) { // Update my avatar's head position from gyros - _myAvatar.updateHeadFromGyros(deltaTime, &_serialPort, &_gravity); + _myAvatar.updateHeadFromGyros(deltaTime, &_serialPort); // Grab latest readings from the gyros float measuredPitchRate = _serialPort.getLastPitchRate(); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 8f6ac7c991..9e41c32273 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -124,7 +124,7 @@ void Avatar::reset() { } // Update avatar head rotation with sensor data -void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterface, glm::vec3* gravity) { +void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterface) { const float AMPLIFY_PITCH = 2.f; const float AMPLIFY_YAW = 2.f; const float AMPLIFY_ROLL = 2.f; @@ -134,10 +134,10 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa float measuredRollRate = serialInterface->getLastRollRate(); // Update avatar head position based on measured gyro rates - - _head.addPitch(measuredPitchRate * AMPLIFY_PITCH * deltaTime); - _head.addYaw (measuredYawRate * AMPLIFY_YAW * deltaTime); - _head.addRoll (measuredRollRate * AMPLIFY_ROLL * deltaTime); + _head.setOrientation(_head.getOrientation() * glm::quat(glm::radians(glm::vec3( + measuredPitchRate * AMPLIFY_PITCH * deltaTime, + measuredYawRate * AMPLIFY_YAW * deltaTime, + measuredRollRate * AMPLIFY_ROLL * deltaTime)))); // Update head lean distance based on accelerometer data glm::vec3 headRotationRates(_head.getPitch(), _head.getYaw(), _head.getRoll()); diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index db8176898a..d272514ed1 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -48,7 +48,7 @@ public: void reset(); void simulate(float deltaTime, Transmitter* transmitter); - void updateHeadFromGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity); + void updateHeadFromGyros(float frametime, SerialInterface * serialInterface); void updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight); void addBodyYaw(float y) {_bodyYaw += y;}; void render(bool lookingInMirror); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index d1ee699dc8..187fcc3e03 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -307,6 +307,13 @@ void Head::renderMohawk(glm::vec3 cameraPosition) { } } +void Head::setOrientation(const glm::quat& orientation) { + glm::vec3 eulerAngles = safeEulerAngles(glm::inverse(glm::quat(glm::radians(_bodyRotation))) * orientation); + _pitch = eulerAngles.x; + _yaw = eulerAngles.y; + _roll = eulerAngles.z; +} + glm::quat Head::getOrientation() const { return glm::quat(glm::radians(_bodyRotation)) * glm::quat(glm::radians(_lookingInMirror ? glm::vec3(_pitch, -_yaw, -_roll) : glm::vec3(_pitch, _yaw, _roll))); diff --git a/interface/src/Head.h b/interface/src/Head.h index f49e127caf..36da1b082f 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -45,6 +45,7 @@ public: void setAverageLoudness(float averageLoudness ) { _averageLoudness = averageLoudness; } void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } void setRenderLookatVectors(bool onOff ) { _renderLookatVectors = onOff; } + void setOrientation(const glm::quat& orientation); glm::quat getOrientation() const; glm::quat getWorldAlignedOrientation () const; From 3f6cf08b970969373e1513220c88f37b0fb365a7 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 15:15:12 -0700 Subject: [PATCH 54/66] Removed remaining Orientation bits (and class itself), enforce limits on head yaw/pitch/roll. --- interface/src/Camera.h | 1 - interface/src/Head.cpp | 6 +- interface/src/Util.cpp | 131 +------------------------- interface/src/Util.h | 40 +------- libraries/avatars/src/Orientation.cpp | 121 ------------------------ libraries/avatars/src/Orientation.h | 55 ----------- 6 files changed, 10 insertions(+), 344 deletions(-) delete mode 100755 libraries/avatars/src/Orientation.cpp delete mode 100644 libraries/avatars/src/Orientation.h diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 4d56774326..1f36d33f58 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -8,7 +8,6 @@ #ifndef __interface__camera__ #define __interface__camera__ -#include "Orientation.h" #include #include diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 187fcc3e03..b53519328b 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -309,9 +309,9 @@ void Head::renderMohawk(glm::vec3 cameraPosition) { void Head::setOrientation(const glm::quat& orientation) { glm::vec3 eulerAngles = safeEulerAngles(glm::inverse(glm::quat(glm::radians(_bodyRotation))) * orientation); - _pitch = eulerAngles.x; - _yaw = eulerAngles.y; - _roll = eulerAngles.z; + setPitch(eulerAngles.x); + setYaw(eulerAngles.y); + setRoll(eulerAngles.z); } glm::quat Head::getOrientation() const { diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 41b25ea776..05dfc50502 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -12,8 +12,8 @@ #include #include -#include #include +#include #include #include "Log.h" @@ -393,10 +393,10 @@ void renderCircle(glm::vec3 position, float radius, glm::vec3 surfaceNormal, int } -void renderOrientationDirections(glm::vec3 position, Orientation orientation, float size) { - glm::vec3 pRight = position + orientation.getRight() * size; - glm::vec3 pUp = position + orientation.getUp () * size; - glm::vec3 pFront = position + orientation.getFront() * size; +void renderOrientationDirections(glm::vec3 position, const glm::quat& orientation, float size) { + glm::vec3 pRight = position + orientation * AVATAR_RIGHT * size; + glm::vec3 pUp = position + orientation * AVATAR_UP * size; + glm::vec3 pFront = position + orientation * AVATAR_FRONT * size; glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_LINE_STRIP); @@ -424,126 +424,5 @@ bool closeEnoughForGovernmentWork(float a, float b) { } -void testOrientationClass() { - printLog("\n----------\ntestOrientationClass()\n----------\n\n"); - - oTestCase tests[] = { - // - inputs ------------, outputs -------------------- ------------------- ---------------------------- - // -- front -------------------, -- up -------------, -- right ------------------- - // ( yaw , pitch, roll , front.x , front.y , front.z , up.x , up.y , up.z , right.x , right.y , right.z ) - - // simple yaw tests - oTestCase( 0.f , 0.f , 0.f , 0.f , 0.f , 1.0f , 0.f , 1.0f , 0.f , -1.0f , 0.f , 0.f ), - oTestCase(45.0f , 0.f , 0.f , 0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , 0.707107f), - oTestCase( 90.0f, 0.f , 0.f , 1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , 1.0f ), - oTestCase(135.0f, 0.f , 0.f , 0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , 0.707107f), - oTestCase(180.0f, 0.f , 0.f , 0.f , 0.f , -1.0f , 0.f , 1.0f , 0.f , 1.0f , 0.f , 0.f ), - oTestCase(225.0f, 0.f , 0.f , -0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , -0.707107f), - oTestCase(270.0f, 0.f , 0.f , -1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , -1.0f ), - oTestCase(315.0f, 0.f , 0.f , -0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , -0.707107f), - oTestCase(-45.0f, 0.f , 0.f , -0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , -0.707107f), - oTestCase(-90.0f, 0.f , 0.f , -1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , -1.0f ), - oTestCase(-135.0f,0.f , 0.f , -0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , -0.707107f), - oTestCase(-180.0f,0.f , 0.f , 0.f , 0.f , -1.0f , 0.f , 1.0f , 0.f , 1.0f , 0.f , 0.f ), - oTestCase(-225.0f,0.f , 0.f , 0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , 0.707107f), - oTestCase(-270.0f,0.f , 0.f , 1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , 1.0f ), - oTestCase(-315.0f,0.f , 0.f , 0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , 0.707107f), - - // simple pitch tests - oTestCase( 0.f , 0.f , 0.f , 0.f, 0.f , 1.0f , 0.f , 1.0f , 0.f , -1.0f , 0.f , 0.f ), - oTestCase( 0.f ,45.0f , 0.f , 0.f, 0.707107f , 0.707107f, 0.f ,0.707107f, -0.707107f, -1.0f , 0.f , 0.f ), - oTestCase( 0.f ,90.f , 0.f , 0.f, 1.0f , 0.0f , 0.f ,0.0f , -1.0f , -1.0f , 0.f , 0.f ), - oTestCase( 0.f ,135.0f, 0.f , 0.f, 0.707107f , -0.707107f, 0.f ,-0.707107f, -0.707107f, -1.0f , 0.f , 0.f ), - oTestCase( 0.f ,180.f , 0.f , 0.f, 0.0f ,-1.0f , 0.f ,-1.0f , 0.f , -1.0f , 0.f , 0.f ), - oTestCase( 0.f ,225.0f, 0.f , 0.f,-0.707107f , -0.707107f, 0.f ,-0.707107f, 0.707107f, -1.0f , 0.f , 0.f ), - oTestCase( 0.f ,270.f , 0.f , 0.f,-1.0f , 0.0f , 0.f ,0.0f , 1.0f , -1.0f , 0.f , 0.f ), - oTestCase( 0.f ,315.0f, 0.f , 0.f,-0.707107f , 0.707107f, 0.f , 0.707107f, 0.707107f, -1.0f , 0.f , 0.f ), - - // simple roll tests - oTestCase( 0.f , 0.f , 0.f , 0.f , 0.f , 1.0f , 0.f , 1.0f ,0.0f , -1.0f , 0.f , 0.0f ), - oTestCase( 0.f , 0.f ,45.0f , 0.f , 0.f , 1.0f , 0.707107f , 0.707107f ,0.0f , -0.707107f, 0.707107f, 0.0f ), - oTestCase( 0.f , 0.f ,90.f , 0.f , 0.f , 1.0f , 1.0f , 0.0f ,0.0f , 0.0f , 1.0f , 0.0f ), - oTestCase( 0.f , 0.f ,135.0f , 0.f , 0.f , 1.0f , 0.707107f , -0.707107f,0.0f , 0.707107f , 0.707107f, 0.0f ), - oTestCase( 0.f , 0.f ,180.f , 0.f , 0.f , 1.0f , 0.0f , -1.0f ,0.0f , 1.0f , 0.0f , 0.0f ), - oTestCase( 0.f , 0.f ,225.0f , 0.f , 0.f , 1.0f , -0.707107f, -0.707107f,0.0f , 0.707107f ,-0.707107f, 0.0f ), - oTestCase( 0.f , 0.f ,270.f , 0.f , 0.f , 1.0f , -1.0f , 0.0f ,0.0f , 0.0f , -1.0f , 0.0f ), - oTestCase( 0.f , 0.f ,315.0f , 0.f , 0.f , 1.0f , -0.707107f, 0.707107f ,0.0f , -0.707107f,-0.707107f, 0.0f ), - - // yaw combo tests - oTestCase( 90.f , 90.f , 0.f , 0.f , 1.0f , 0.0f , -1.0f , 0.0f , 0.f , 0.0f , 0.f , 1.0f ), - oTestCase( 90.f , 0.f , 90.f , 1.0f , 0.0f, 0.f , 0.0f , 0.0f , -1.f , 0.0f , 1.0f , 0.0f ), - }; - - int failedCount = 0; - int totalTests = sizeof(tests)/sizeof(oTestCase); - - for (int i=0; i < totalTests; i++) { - - bool passed = true; // I'm an optimist! - - float yaw = tests[i].yaw; - float pitch = tests[i].pitch; - float roll = tests[i].roll; - - Orientation o1; - o1.setToIdentity(); - o1.yaw(yaw); - o1.pitch(pitch); - o1.roll(roll); - - glm::vec3 front = o1.getFront(); - glm::vec3 up = o1.getUp(); - glm::vec3 right = o1.getRight(); - - printLog("\n-----\nTest: %d - yaw=%f , pitch=%f , roll=%f \n",i+1,yaw,pitch,roll); - - printLog("\nFRONT\n"); - printLog(" + received: front.x=%f, front.y=%f, front.z=%f\n",front.x,front.y,front.z); - - if (closeEnoughForGovernmentWork(front.x, tests[i].frontX) - && closeEnoughForGovernmentWork(front.y, tests[i].frontY) - && closeEnoughForGovernmentWork(front.z, tests[i].frontZ)) { - printLog(" front vector PASSES!\n"); - } else { - printLog(" expected: front.x=%f, front.y=%f, front.z=%f\n",tests[i].frontX,tests[i].frontY,tests[i].frontZ); - printLog(" front vector FAILED! \n"); - passed = false; - } - - printLog("\nUP\n"); - printLog(" + received: up.x=%f, up.y=%f, up.z=%f\n",up.x,up.y,up.z); - if (closeEnoughForGovernmentWork(up.x, tests[i].upX) - && closeEnoughForGovernmentWork(up.y, tests[i].upY) - && closeEnoughForGovernmentWork(up.z, tests[i].upZ)) { - printLog(" up vector PASSES!\n"); - } else { - printLog(" expected: up.x=%f, up.y=%f, up.z=%f\n",tests[i].upX,tests[i].upY,tests[i].upZ); - printLog(" up vector FAILED!\n"); - passed = false; - } - - - printLog("\nRIGHT\n"); - printLog(" + received: right.x=%f, right.y=%f, right.z=%f\n",right.x,right.y,right.z); - if (closeEnoughForGovernmentWork(right.x, tests[i].rightX) - && closeEnoughForGovernmentWork(right.y, tests[i].rightY) - && closeEnoughForGovernmentWork(right.z, tests[i].rightZ)) { - printLog(" right vector PASSES!\n"); - } else { - printLog(" expected: right.x=%f, right.y=%f, right.z=%f\n",tests[i].rightX,tests[i].rightY,tests[i].rightZ); - printLog(" right vector FAILED!\n"); - passed = false; - } - - if (!passed) { - printLog("\n-----\nTest: %d - FAILED! \n----------\n\n",i+1); - failedCount++; - } - } - printLog("\n-----\nTotal Failed: %d out of %d \n----------\n\n",failedCount,totalTests); - printLog("\n----------DONE----------\n\n"); -} - - diff --git a/interface/src/Util.h b/interface/src/Util.h index d93267f175..0823ac405b 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -16,8 +16,7 @@ #endif #include - -#include +#include // the standard sans serif font family #define SANS_FONT_FAMILY "Helvetica" @@ -56,44 +55,9 @@ void drawGroundPlaneGrid(float size); void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, float darkness); -void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ); +void renderOrientationDirections( glm::vec3 position, const glm::quat& orientation, float size ); void renderSphereOutline(glm::vec3 position, float radius, int numSides, glm::vec3 cameraPosition); void renderCircle(glm::vec3 position, float radius, glm::vec3 surfaceNormal, int numSides ); - -class oTestCase { -public: - float yaw; - float pitch; - float roll; - - float frontX; - float frontY; - float frontZ; - - float upX; - float upY; - float upZ; - - float rightX; - float rightY; - float rightZ; - - oTestCase( - float yaw, float pitch, float roll, - float frontX, float frontY, float frontZ, - float upX, float upY, float upZ, - float rightX, float rightY, float rightZ - ) : - yaw(yaw),pitch(pitch),roll(roll), - frontX(frontX),frontY(frontY),frontZ(frontZ), - upX(upX),upY(upY),upZ(upZ), - rightX(rightX),rightY(rightY),rightZ(rightZ) - {}; -}; - - -void testOrientationClass(); - #endif diff --git a/libraries/avatars/src/Orientation.cpp b/libraries/avatars/src/Orientation.cpp deleted file mode 100755 index cae0f70201..0000000000 --- a/libraries/avatars/src/Orientation.cpp +++ /dev/null @@ -1,121 +0,0 @@ -//----------------------------------------------------------- -// -// Created by Jeffrey Ventrella -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// -//----------------------------------------------------------- - -#include "Orientation.h" -#include "SharedUtil.h" - -static const bool USING_QUATERNIONS = true; - -Orientation::Orientation() { - setToIdentity(); -} - -void Orientation::setToIdentity() { - - quat = glm::quat(); - right = glm::vec3(IDENTITY_RIGHT); - up = glm::vec3(IDENTITY_UP ); - front = glm::vec3(IDENTITY_FRONT); -} - -void Orientation::set(Orientation o) { - - quat = o.quat; - right = o.right; - up = o.up; - front = o.front; -} - -void Orientation::yaw(float angle) { - - float radian = angle * PI_OVER_180; - - if (USING_QUATERNIONS) { - rotateAndGenerateDirections(glm::quat(glm::vec3(0.0f, -radian, 0.0f))); - } else { - float s = sin(radian); - float c = cos(radian); - - glm::vec3 cosineFront = front * c; - glm::vec3 cosineRight = right * c; - glm::vec3 sineFront = front * s; - glm::vec3 sineRight = right * s; - - front = cosineFront - sineRight; - right = cosineRight + sineFront; - } -} - -void Orientation::pitch(float angle) { - - float radian = angle * PI_OVER_180; - - if (USING_QUATERNIONS) { - rotateAndGenerateDirections(glm::quat(glm::vec3(radian, 0.0f, 0.0f))); - } else { - float s = sin(radian); - float c = cos(radian); - - glm::vec3 cosineUp = up * c; - glm::vec3 cosineFront = front * c; - glm::vec3 sineUp = up * s; - glm::vec3 sineFront = front * s; - - up = cosineUp - sineFront; - front = cosineFront + sineUp; - } -} - -void Orientation::roll(float angle) { - - float radian = angle * PI_OVER_180; - - if (USING_QUATERNIONS) { - rotateAndGenerateDirections(glm::quat(glm::vec3(0.0f, 0.0f, radian))); - } else { - float s = sin(radian); - float c = cos(radian); - - glm::vec3 cosineUp = up * c; - glm::vec3 cosineRight = right * c; - glm::vec3 sineUp = up * s; - glm::vec3 sineRight = right * s; - - up = cosineUp - sineRight; - right = cosineRight + sineUp; - } -} - -void Orientation::rotate(float pitch_change, float yaw_change, float roll_change) { - pitch(pitch_change); - yaw (yaw_change); - roll (roll_change); -} - -void Orientation::rotate(glm::vec3 eulerAngles) { - -//this needs to be optimized! - pitch(eulerAngles.x); - yaw (eulerAngles.y); - roll (eulerAngles.z); -} - -void Orientation::rotate( glm::quat rotation ) { - rotateAndGenerateDirections(rotation); -} - - -void Orientation::rotateAndGenerateDirections(glm::quat rotation) { - - quat = quat * rotation; - - glm::mat4 rotationMatrix = glm::mat4_cast(quat); - - right = glm::vec3(glm::vec4(IDENTITY_RIGHT, 0.0f) * rotationMatrix); - up = glm::vec3(glm::vec4(IDENTITY_UP, 0.0f) * rotationMatrix); - front = glm::vec3(glm::vec4(IDENTITY_FRONT, 0.0f) * rotationMatrix); -} diff --git a/libraries/avatars/src/Orientation.h b/libraries/avatars/src/Orientation.h deleted file mode 100644 index 56209db934..0000000000 --- a/libraries/avatars/src/Orientation.h +++ /dev/null @@ -1,55 +0,0 @@ -//----------------------------------------------------------- -// -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// -//----------------------------------------------------------- - -#ifndef __interface__orientation__ -#define __interface__orientation__ - -#include -#include -#include - -// this is where the coordinate system is represented -const glm::vec3 IDENTITY_RIGHT = glm::vec3(-1.0f, 0.0f, 0.0f); -const glm::vec3 IDENTITY_UP = glm::vec3( 0.0f, 1.0f, 0.0f); -const glm::vec3 IDENTITY_FRONT = glm::vec3( 0.0f, 0.0f, 1.0f); - -class Orientation -{ -public: - Orientation(); - - void set(Orientation); - void setToIdentity(); - - void pitch(float pitch_change); - void yaw (float yaw_change); - void roll (float roll_change); - - void rotate(float pitch, float yaw, float roll); - void rotate(glm::vec3 EulerAngles); - void rotate(glm::quat quaternion); - - const glm::quat& getQuat() const {return quat;} - - const glm::vec3& getRight() const {return right;} - const glm::vec3& getUp () const {return up; } - const glm::vec3& getFront() const {return front;} - - const glm::vec3& getIdentityRight() const {return IDENTITY_RIGHT;} - const glm::vec3& getIdentityUp () const {return IDENTITY_UP;} - const glm::vec3& getIdentityFront() const {return IDENTITY_FRONT;} - -private: - - glm::quat quat; - glm::vec3 right; - glm::vec3 up; - glm::vec3 front; - - void rotateAndGenerateDirections(glm::quat rotation); -}; - -#endif From 826ef33d4b6842d6078f01fd2192b4adbf82238e Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 15:20:20 -0700 Subject: [PATCH 55/66] Reverse angles for mirror mode. --- interface/src/Head.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index b53519328b..19863f6fa4 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -309,9 +309,15 @@ void Head::renderMohawk(glm::vec3 cameraPosition) { void Head::setOrientation(const glm::quat& orientation) { glm::vec3 eulerAngles = safeEulerAngles(glm::inverse(glm::quat(glm::radians(_bodyRotation))) * orientation); - setPitch(eulerAngles.x); - setYaw(eulerAngles.y); - setRoll(eulerAngles.z); + if (_lookingInMirror) { + setPitch(eulerAngles.x); + setYaw(eulerAngles.y); + setRoll(eulerAngles.z); + } else { + setPitch(eulerAngles.x); + setYaw(-eulerAngles.y); + setRoll(-eulerAngles.z); + } } glm::quat Head::getOrientation() const { From 780b049f4b15798fb13e72a8c56fd79b8ea3adb4 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 15:21:54 -0700 Subject: [PATCH 56/66] I got these backwards. --- interface/src/Head.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 19863f6fa4..ffc518abcf 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -310,13 +310,13 @@ void Head::renderMohawk(glm::vec3 cameraPosition) { void Head::setOrientation(const glm::quat& orientation) { glm::vec3 eulerAngles = safeEulerAngles(glm::inverse(glm::quat(glm::radians(_bodyRotation))) * orientation); if (_lookingInMirror) { - setPitch(eulerAngles.x); - setYaw(eulerAngles.y); - setRoll(eulerAngles.z); - } else { setPitch(eulerAngles.x); setYaw(-eulerAngles.y); setRoll(-eulerAngles.z); + } else { + setPitch(eulerAngles.x); + setYaw(eulerAngles.y); + setRoll(eulerAngles.z); } } From 47bf5a2b773846602e395ca0ab5772b22c00757d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 15:43:07 -0700 Subject: [PATCH 57/66] Have the Head control how orientations are added. --- interface/src/Avatar.cpp | 4 ++-- interface/src/Head.cpp | 8 ++++++++ interface/src/Head.h | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 9e41c32273..d1537b2145 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -134,10 +134,10 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa float measuredRollRate = serialInterface->getLastRollRate(); // Update avatar head position based on measured gyro rates - _head.setOrientation(_head.getOrientation() * glm::quat(glm::radians(glm::vec3( + _head.addOrientation( measuredPitchRate * AMPLIFY_PITCH * deltaTime, measuredYawRate * AMPLIFY_YAW * deltaTime, - measuredRollRate * AMPLIFY_ROLL * deltaTime)))); + measuredRollRate * AMPLIFY_ROLL * deltaTime); // Update head lean distance based on accelerometer data glm::vec3 headRotationRates(_head.getPitch(), _head.getYaw(), _head.getRoll()); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index ffc518abcf..ff1fd12b78 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -307,6 +307,14 @@ void Head::renderMohawk(glm::vec3 cameraPosition) { } } +void Head::addOrientation(float pitch, float yaw, float roll) { + if (_lookingInMirror) { + yaw = -yaw; + roll = -roll; + } + setOrientation(getOrientation() * glm::quat(glm::radians(glm::vec3(pitch, yaw, roll)))); +} + void Head::setOrientation(const glm::quat& orientation) { glm::vec3 eulerAngles = safeEulerAngles(glm::inverse(glm::quat(glm::radians(_bodyRotation))) * orientation); if (_lookingInMirror) { diff --git a/interface/src/Head.h b/interface/src/Head.h index 36da1b082f..265bab51f1 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -47,6 +47,8 @@ public: void setRenderLookatVectors(bool onOff ) { _renderLookatVectors = onOff; } void setOrientation(const glm::quat& orientation); + void addOrientation(float pitch, float yaw, float roll); + glm::quat getOrientation() const; glm::quat getWorldAlignedOrientation () const; From 9213cfd0c23bfd9b9fb26f2db9cd25d1a272a875 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 15:48:00 -0700 Subject: [PATCH 58/66] Revert to simply adding the Eulers. --- interface/src/Avatar.cpp | 7 +++---- interface/src/Head.cpp | 21 --------------------- interface/src/Head.h | 3 --- 3 files changed, 3 insertions(+), 28 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index d1537b2145..370e3b0107 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -134,10 +134,9 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa float measuredRollRate = serialInterface->getLastRollRate(); // Update avatar head position based on measured gyro rates - _head.addOrientation( - measuredPitchRate * AMPLIFY_PITCH * deltaTime, - measuredYawRate * AMPLIFY_YAW * deltaTime, - measuredRollRate * AMPLIFY_ROLL * deltaTime); + _head.addPitch(measuredPitchRate * AMPLIFY_PITCH * deltaTime); + _head.addYaw(measuredYawRate * AMPLIFY_YAW * deltaTime); + _head.addRoll(measuredRollRate * AMPLIFY_ROLL * deltaTime); // Update head lean distance based on accelerometer data glm::vec3 headRotationRates(_head.getPitch(), _head.getYaw(), _head.getRoll()); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index ff1fd12b78..d1ee699dc8 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -307,27 +307,6 @@ void Head::renderMohawk(glm::vec3 cameraPosition) { } } -void Head::addOrientation(float pitch, float yaw, float roll) { - if (_lookingInMirror) { - yaw = -yaw; - roll = -roll; - } - setOrientation(getOrientation() * glm::quat(glm::radians(glm::vec3(pitch, yaw, roll)))); -} - -void Head::setOrientation(const glm::quat& orientation) { - glm::vec3 eulerAngles = safeEulerAngles(glm::inverse(glm::quat(glm::radians(_bodyRotation))) * orientation); - if (_lookingInMirror) { - setPitch(eulerAngles.x); - setYaw(-eulerAngles.y); - setRoll(-eulerAngles.z); - } else { - setPitch(eulerAngles.x); - setYaw(eulerAngles.y); - setRoll(eulerAngles.z); - } -} - glm::quat Head::getOrientation() const { return glm::quat(glm::radians(_bodyRotation)) * glm::quat(glm::radians(_lookingInMirror ? glm::vec3(_pitch, -_yaw, -_roll) : glm::vec3(_pitch, _yaw, _roll))); diff --git a/interface/src/Head.h b/interface/src/Head.h index 265bab51f1..f49e127caf 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -45,9 +45,6 @@ public: void setAverageLoudness(float averageLoudness ) { _averageLoudness = averageLoudness; } void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } void setRenderLookatVectors(bool onOff ) { _renderLookatVectors = onOff; } - void setOrientation(const glm::quat& orientation); - - void addOrientation(float pitch, float yaw, float roll); glm::quat getOrientation() const; glm::quat getWorldAlignedOrientation () const; From 86ae9dbe7c009662f5ed60bfddf367083899cdea Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 15:51:31 -0700 Subject: [PATCH 59/66] Merged. --- avatar-mixer/src/main.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index 97c431b408..caa9f609ce 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -51,19 +51,8 @@ void attachAvatarDataToAgent(Agent* newAgent) { } } -bool wantLocalDomain = false; - int main(int argc, const char* argv[]) { - // Handle Local Domain testing with the --local command line - const char* local = "--local"; - ::wantLocalDomain = cmdOptionExists(argc, argv,local); - if (::wantLocalDomain) { - printf("Local Domain MODE!\n"); - int ip = getLocalAddress(); - sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); - } - AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT); setvbuf(stdout, NULL, _IOLBF, 0); From f009177aa75f79a38a094087dfd65613eee8ea52 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 30 May 2013 16:19:07 -0700 Subject: [PATCH 60/66] Added check for lost transmitter --- interface/src/Application.cpp | 2 ++ interface/src/Avatar.cpp | 1 + interface/src/Transmitter.cpp | 25 ++++++++++++++++++++++--- interface/src/Transmitter.h | 2 ++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1e9e119777..72f5fc1a5c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -877,6 +877,8 @@ void Application::idle() { _serialPort.readData(deltaTime); } + // Update transmitter + // Sample hardware, update view frustum if needed, and send avatar data to mixer/agents updateAvatar(deltaTime); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 8f6ac7c991..b2e60641a5 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -279,6 +279,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // Add thrusts from Transmitter if (transmitter) { + transmitter->checkForLostTransmitter(); glm::vec3 rotation = transmitter->getEstimatedRotation(); const float TRANSMITTER_MIN_RATE = 1.f; const float TRANSMITTER_MIN_YAW_RATE = 4.f; diff --git a/interface/src/Transmitter.cpp b/interface/src/Transmitter.cpp index 5f6def92f7..d44227982f 100644 --- a/interface/src/Transmitter.cpp +++ b/interface/src/Transmitter.cpp @@ -20,11 +20,25 @@ Transmitter::Transmitter() : _isConnected(false), _lastRotationRate(0,0,0), _lastAcceleration(0,0,0), - _estimatedRotation(0,0,0) + _estimatedRotation(0,0,0), + _lastReceivedPacket(NULL) { } +void Transmitter::checkForLostTransmitter() { + // If we are in motion, check for loss of transmitter packets + if (glm::length(_estimatedRotation) > 0.f) { + timeval now; + gettimeofday(&now, NULL); + const int TIME_TO_ASSUME_LOST_MSECS = 2000; + int msecsSinceLast = diffclock(_lastReceivedPacket, &now); + if (msecsSinceLast > TIME_TO_ASSUME_LOST_MSECS) { + resetLevels(); + printLog("Transmitter signal lost.\n"); + } + } +} void Transmitter::resetLevels() { _lastRotationRate *= 0.f; _estimatedRotation *= 0.f; @@ -34,6 +48,11 @@ void Transmitter::processIncomingData(unsigned char* packetData, int numBytes) { const int PACKET_HEADER_SIZE = 1; // Packet's first byte is 'T' const int ROTATION_MARKER_SIZE = 1; // 'R' = Rotation (clockwise about x,y,z) const int ACCELERATION_MARKER_SIZE = 1; // 'A' = Acceleration (x,y,z) + if (!_lastReceivedPacket) { + _lastReceivedPacket = new timeval; + } + gettimeofday(_lastReceivedPacket, NULL); + if (numBytes == PACKET_HEADER_SIZE + ROTATION_MARKER_SIZE + ACCELERATION_MARKER_SIZE + sizeof(_lastRotationRate) + sizeof(_lastAcceleration) + sizeof(_touchState.x) + sizeof(_touchState.y) + sizeof(_touchState.state)) { @@ -69,12 +88,12 @@ void Transmitter::processIncomingData(unsigned char* packetData, int numBytes) { _estimatedRotation.y *= (1.f - DECAY_RATE * DELTA_TIME); if (!_isConnected) { - printf("Transmitter V2 Connected.\n"); + printLog("Transmitter Connected.\n"); _isConnected = true; _estimatedRotation *= 0.0; } } else { - printf("Transmitter V2 packet read error, %d bytes.\n", numBytes); + printLog("Transmitter packet read error, %d bytes.\n", numBytes); } } diff --git a/interface/src/Transmitter.h b/interface/src/Transmitter.h index 0db0762ab1..95d80249e8 100644 --- a/interface/src/Transmitter.h +++ b/interface/src/Transmitter.h @@ -26,6 +26,7 @@ class Transmitter public: Transmitter(); void render(); + void checkForLostTransmitter(); void resetLevels(); void renderLevels(int width, int height); bool isConnected() { return _isConnected; }; @@ -41,6 +42,7 @@ private: glm::vec3 _lastAcceleration; glm::vec3 _estimatedRotation; TouchState _touchState; + timeval* _lastReceivedPacket; #endif /* defined(__hifi__Transmitter__) */ }; From 6f552b4a00495969c39026afe36494e1dd80ddf7 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 16:26:15 -0700 Subject: [PATCH 61/66] Playing around with using the gyro acceleration to drive the eye offset. --- interface/src/Application.cpp | 7 +++++++ interface/src/Application.h | 1 + 2 files changed, 8 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 262bf6625a..e7b6ee1d80 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1294,6 +1294,10 @@ void Application::updateAvatar(float deltaTime) { _headMouseY = max(_headMouseY, 0); _headMouseY = min(_headMouseY, _glWidget->height()); + _eyeOffsetVelocity += _serialPort.getLastAcceleration() * deltaTime; + _myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + _eyeOffsetVelocity * deltaTime); + resizeGL(_glWidget->width(), _glWidget->height()); + if (OculusManager::isConnected()) { float yaw, pitch, roll; OculusManager::getEulerAngles(yaw, pitch, roll); @@ -2086,6 +2090,9 @@ void Application::resetSensors() { QCursor::setPos(_headMouseX, _headMouseY); _myAvatar.reset(); _myTransmitter.resetLevels(); + _myCamera.setEyeOffsetPosition(glm::vec3(0.0f, 0.0f, 0.0f)); + _eyeOffsetVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + resizeGL(_glWidget->width(), _glWidget->height()); } static void setShortcutsEnabled(QWidget* widget, bool enabled) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 64959f1274..540ce1796e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -206,6 +206,7 @@ private: Camera _myCamera; // My view onto the world Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode + glm::vec3 _eyeOffsetVelocity; Environment _environment; From ffb3cf53aaf053063c26d6c2a2c58e03610e890e Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 16:34:59 -0700 Subject: [PATCH 62/66] Added "Gyro Eye Offset" menu option to drive the eye offset from the gyros. --- interface/src/Application.cpp | 15 ++++++++++----- interface/src/Application.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e7b6ee1d80..140d47dc3c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -299,11 +299,13 @@ void Application::paintGL() { } else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { _myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation()); + _myCamera.setTargetRotation(_gyroEyeOffset->isChecked() ? _myAvatar.getWorldAlignedOrientation() : + _myAvatar.getHead().getWorldAlignedOrientation()); } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { _myCamera.setTargetPosition(_myAvatar.getHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation()); + _myCamera.setTargetRotation(_gyroEyeOffset->isChecked() ? _myAvatar.getWorldAlignedOrientation() : + _myAvatar.getHead().getWorldAlignedOrientation()); } // important... @@ -1124,6 +1126,7 @@ void Application::initMenu() { optionsMenu->addAction("Noise", this, SLOT(setNoise(bool)), Qt::Key_N)->setCheckable(true); (_gyroLook = optionsMenu->addAction("Gyro Look"))->setCheckable(true); _gyroLook->setChecked(true); + (_gyroEyeOffset = optionsMenu->addAction("Gyro Eye Offset"))->setCheckable(true); (_mouseLook = optionsMenu->addAction("Mouse Look"))->setCheckable(true); _mouseLook->setChecked(false); (_showHeadMouse = optionsMenu->addAction("Head Mouse"))->setCheckable(true); @@ -1294,9 +1297,11 @@ void Application::updateAvatar(float deltaTime) { _headMouseY = max(_headMouseY, 0); _headMouseY = min(_headMouseY, _glWidget->height()); - _eyeOffsetVelocity += _serialPort.getLastAcceleration() * deltaTime; - _myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + _eyeOffsetVelocity * deltaTime); - resizeGL(_glWidget->width(), _glWidget->height()); + if (_gyroEyeOffset->isChecked()) { + _eyeOffsetVelocity += _serialPort.getLastAcceleration() * deltaTime; + _myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + _eyeOffsetVelocity * deltaTime); + resizeGL(_glWidget->width(), _glWidget->height()); + } if (OculusManager::isConnected()) { float yaw, pitch, roll; diff --git a/interface/src/Application.h b/interface/src/Application.h index 540ce1796e..d4caeca329 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -143,6 +143,7 @@ private: QAction* _lookingInMirror; // Are we currently rendering one's own head as if in mirror? QAction* _echoAudioMode; // Are we asking the mixer to echo back our audio? QAction* _gyroLook; // Whether to allow the gyro data from head to move your view + QAction* _gyroEyeOffset; // Whether to allow the gyro data to move your eye offset QAction* _mouseLook; // Whether the have the mouse near edge of screen move your view QAction* _showHeadMouse; // Whether the have the mouse near edge of screen move your view QAction* _transmitterDrives; // Whether to have Transmitter data move/steer the Avatar From fefa74135c27e929a7353b0cca162bc581cfcc8c Mon Sep 17 00:00:00 2001 From: Geenz Date: Thu, 30 May 2013 19:47:25 -0400 Subject: [PATCH 63/66] Moved to function overloads instead of unique function names. --- interface/src/Application.cpp | 72 +++++++++++++++++------------------ interface/src/Application.h | 12 +++--- interface/src/Avatar.cpp | 8 ++-- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7bb9879e06..c3ff499a83 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -792,7 +792,7 @@ void Application::saveSettingsFile() { fclose(settingsFile); } -bool Application::getSettingBool(const char* setting, bool& value, const bool defaultSetting) const { +bool Application::getSetting(const char* setting, bool& value, const bool defaultSetting) const { std::map::const_iterator iter = _settingsTable.find(setting); if (iter != _settingsTable.end()) { @@ -817,7 +817,7 @@ bool Application::getSettingBool(const char* setting, bool& value, const bool de return true; } -bool Application::getSettingFloat(const char* setting, float& value, const float defaultSetting) const { +bool Application::getSetting(const char* setting, float& value, const float defaultSetting) const { std::map::const_iterator iter = _settingsTable.find(setting); if (iter != _settingsTable.end()) { @@ -846,7 +846,7 @@ bool Application::getSettingFloat(const char* setting, float& value, const float return true; } -bool Application::getSettingVec3(const char* setting, glm::vec3& value, const glm::vec3& defaultSetting) const { +bool Application::getSetting(const char* setting, glm::vec3& value, const glm::vec3& defaultSetting) const { std::map::const_iterator iter = _settingsTable.find(setting); if (iter != _settingsTable.end()) { @@ -877,19 +877,19 @@ bool Application::getSettingVec3(const char* setting, glm::vec3& value, const gl const short MAX_SETTINGS_LENGTH = 128; -void Application::setSettingBool(const char* setting, const bool value) { +void Application::setSetting(const char* setting, const bool value) { char settingValues[MAX_SETTINGS_LENGTH]; sprintf(settingValues, "%d", value); _settingsTable[setting] = settingValues; } -void Application::setSettingFloat(const char* setting, const float value) { +void Application::setSetting(const char* setting, const float value) { char settingValues[MAX_SETTINGS_LENGTH]; sprintf(settingValues, "%f", value); _settingsTable[setting] = settingValues; } -void Application::setSettingVec3(const char* setting, const glm::vec3& value) { +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; @@ -2361,35 +2361,35 @@ void Application::saveSettings() // This should probably be moved to a map stored in memory at some point to cache settings. _myAvatar.writeAvatarDataToFile(); - setSettingBool("_gyroLook", _gyroLook->isChecked()); + setSetting("_gyroLook", _gyroLook->isChecked()); - setSettingBool("_mouseLook", _mouseLook->isChecked()); + setSetting("_mouseLook", _mouseLook->isChecked()); - setSettingBool("_transmitterDrives", _transmitterDrives->isChecked()); + setSetting("_transmitterDrives", _transmitterDrives->isChecked()); - setSettingBool("_renderVoxels", _renderVoxels->isChecked()); + setSetting("_renderVoxels", _renderVoxels->isChecked()); - setSettingBool("_renderVoxelTextures", _renderVoxelTextures->isChecked()); + setSetting("_renderVoxelTextures", _renderVoxelTextures->isChecked()); - setSettingBool("_renderStarsOn", _renderStarsOn->isChecked()); + setSetting("_renderStarsOn", _renderStarsOn->isChecked()); - setSettingBool("_renderAtmosphereOn", _renderAtmosphereOn->isChecked()); + setSetting("_renderAtmosphereOn", _renderAtmosphereOn->isChecked()); - setSettingBool("_renderAvatarsOn", _renderAvatarsOn->isChecked()); + setSetting("_renderAvatarsOn", _renderAvatarsOn->isChecked()); - setSettingBool("_renderStatsOn", _renderStatsOn->isChecked()); + setSetting("_renderStatsOn", _renderStatsOn->isChecked()); - setSettingBool("_renderFrameTimerOn", _renderFrameTimerOn->isChecked()); + setSetting("_renderFrameTimerOn", _renderFrameTimerOn->isChecked()); - setSettingBool("_renderLookatOn", _renderLookatOn->isChecked()); + setSetting("_renderLookatOn", _renderLookatOn->isChecked()); - setSettingBool("_logOn", _logOn->isChecked()); + setSetting("_logOn", _logOn->isChecked()); - setSettingBool("_frustumOn", _frustumOn->isChecked()); + setSetting("_frustumOn", _frustumOn->isChecked()); - setSettingBool("_viewFrustumFromOffset", _viewFrustumFromOffset->isChecked()); + setSetting("_viewFrustumFromOffset", _viewFrustumFromOffset->isChecked()); - setSettingBool("_cameraFrustum", _cameraFrustum->isChecked()); + setSetting("_cameraFrustum", _cameraFrustum->isChecked()); saveSettingsFile(); } @@ -2400,49 +2400,49 @@ void Application::readSettings() _myAvatar.readAvatarDataFromFile(); bool settingState; - getSettingBool("_gyroLook", settingState, _gyroLook->isChecked()); + getSetting("_gyroLook", settingState, _gyroLook->isChecked()); _gyroLook->setChecked(settingState); - getSettingBool("_mouseLook", settingState, _mouseLook->isChecked()); + getSetting("_mouseLook", settingState, _mouseLook->isChecked()); _mouseLook->setChecked(settingState); - getSettingBool("_transmitterDrives", settingState, _transmitterDrives->isChecked()); + getSetting("_transmitterDrives", settingState, _transmitterDrives->isChecked()); _transmitterDrives->setChecked(settingState); - getSettingBool("_renderVoxels", settingState, _renderVoxels->isChecked()); + getSetting("_renderVoxels", settingState, _renderVoxels->isChecked()); _renderVoxels->setChecked(settingState); - getSettingBool("_renderVoxelTextures", settingState, _renderVoxelTextures->isChecked()); + getSetting("_renderVoxelTextures", settingState, _renderVoxelTextures->isChecked()); _renderVoxelTextures->setChecked(settingState); - getSettingBool("_renderStarsOn", settingState, _renderStarsOn->isChecked()); + getSetting("_renderStarsOn", settingState, _renderStarsOn->isChecked()); _renderStarsOn->setChecked(settingState); - getSettingBool("_renderAtmosphereOn", settingState, _renderAtmosphereOn->isChecked()); + getSetting("_renderAtmosphereOn", settingState, _renderAtmosphereOn->isChecked()); _renderAtmosphereOn->setChecked(settingState); - getSettingBool("_renderAvatarsOn", settingState, _renderAvatarsOn->isChecked()); + getSetting("_renderAvatarsOn", settingState, _renderAvatarsOn->isChecked()); _renderAvatarsOn->setChecked(settingState); - getSettingBool("_renderStatsOn", settingState, _renderStatsOn->isChecked()); + getSetting("_renderStatsOn", settingState, _renderStatsOn->isChecked()); _renderStatsOn->setChecked(settingState); - getSettingBool("_renderFrameTimerOn", settingState, _renderFrameTimerOn->isChecked()); + getSetting("_renderFrameTimerOn", settingState, _renderFrameTimerOn->isChecked()); _renderFrameTimerOn->setChecked(settingState); - getSettingBool("_renderLookatOn", settingState, _renderLookatOn->isChecked()); + getSetting("_renderLookatOn", settingState, _renderLookatOn->isChecked()); _renderLookatOn->setChecked(settingState); - getSettingBool("_logOn", settingState, _logOn->isChecked()); + getSetting("_logOn", settingState, _logOn->isChecked()); _logOn->setChecked(settingState); - getSettingBool("_frustumOn", settingState, _frustumOn->isChecked()); + getSetting("_frustumOn", settingState, _frustumOn->isChecked()); _frustumOn->setChecked(settingState); - getSettingBool("_viewFrustumFromOffset", settingState, _viewFrustumFromOffset->isChecked()); + getSetting("_viewFrustumFromOffset", settingState, _viewFrustumFromOffset->isChecked()); _viewFrustumFromOffset->setChecked(settingState); - getSettingBool("_cameraFrustum", settingState, _cameraFrustum->isChecked()); + getSetting("_cameraFrustum", settingState, _cameraFrustum->isChecked()); _cameraFrustum->setChecked(settingState); } diff --git a/interface/src/Application.h b/interface/src/Application.h index f173db9ccb..42daf39f3b 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -75,7 +75,7 @@ public: @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 getSettingBool(const char* setting, bool &value, const bool defaultSetting = false) const; + bool getSetting(const char* setting, bool &value, const bool defaultSetting = false) const; /*! @fn getSettingFloat @@ -84,7 +84,7 @@ public: @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 getSettingFloat(const char* setting, float &value, const float defaultSetting = 0.0f) const; + bool getSetting(const char* setting, float &value, const float defaultSetting = 0.0f) const; /*! @fn getSettingVec3 @@ -93,7 +93,7 @@ public: @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 getSettingVec3(const char* setting, glm::vec3 &value, const glm::vec3& defaultSetting = glm::vec3(0.0f, 0.0f, 0.0f)) const; + bool getSetting(const char* setting, glm::vec3 &value, const glm::vec3& defaultSetting = glm::vec3(0.0f, 0.0f, 0.0f)) const; /*! @fn setSettingBool @@ -101,7 +101,7 @@ public: @param settingName The desired setting to populate a value for. @param boolSetting The value to set. */ - void setSettingBool(const char* setting, const bool value); + void setSetting(const char* setting, const bool value); /*! @fn setSettingFloat @@ -109,7 +109,7 @@ public: @param settingName The desired setting to populate a value for. @param floatSetting The value to set. */ - void setSettingFloat(const char* setting, const float value); + void setSetting(const char* setting, const float value); /*! @fn setSettingVec3 @@ -117,7 +117,7 @@ public: @param settingName The desired setting to populate a value for. @param vecSetting The value to set. */ - void setSettingVec3(const char* setting, const glm::vec3& value); + void setSetting(const char* setting, const glm::vec3& value); private slots: diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 371bd59660..8d58b0dcd2 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1242,16 +1242,16 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity } void Avatar::writeAvatarDataToFile() { - Application::getInstance()->setSettingVec3("avatarPos", _position); - Application::getInstance()->setSettingVec3("avatarRotation", glm::vec3(_bodyYaw, _bodyPitch, _bodyRoll)); + Application::getInstance()->setSetting("avatarPos", _position); + Application::getInstance()->setSetting("avatarRotation", glm::vec3(_bodyYaw, _bodyPitch, _bodyRoll)); } void Avatar::readAvatarDataFromFile() { glm::vec3 readPosition; glm::vec3 readRotation; - Application::getInstance()->getSettingVec3("avatarPos", readPosition, glm::vec3(6.1f, 0, 1.4f)); - Application::getInstance()->getSettingVec3("avatarRotation", readRotation, glm::vec3(0, 0, 0)); + Application::getInstance()->getSetting("avatarPos", readPosition, glm::vec3(6.1f, 0, 1.4f)); + Application::getInstance()->getSetting("avatarRotation", readRotation, glm::vec3(0, 0, 0)); _bodyYaw = readRotation.x; _bodyPitch = readRotation.y; From ed904b58eb510e5c7314905c35e6fbb4eac7edb9 Mon Sep 17 00:00:00 2001 From: Geenz Date: Thu, 30 May 2013 19:50:01 -0400 Subject: [PATCH 64/66] Fixed spacing issues per the coding standard. --- interface/src/Application.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c3ff499a83..90475d0ed1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -735,9 +735,9 @@ void Application::readSettingsFile() { while (fgets(line, LINE_MAX, settingsFile) != NULL) { if (strcmp(line, " \n") > 0) { - char *token = NULL; - char *settingLine = NULL; - char *toFree = NULL; + char* token = NULL; + char* settingLine = NULL; + char* toFree = NULL; settingLine = strdup(line); From cb1e1cc3ddb86484dc069c47d067e6f8a7655a44 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 16:51:08 -0700 Subject: [PATCH 65/66] Not going down that path. --- interface/src/Application.cpp | 16 ++-------------- interface/src/Application.h | 2 -- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 140d47dc3c..262bf6625a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -299,13 +299,11 @@ void Application::paintGL() { } else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { _myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition()); - _myCamera.setTargetRotation(_gyroEyeOffset->isChecked() ? _myAvatar.getWorldAlignedOrientation() : - _myAvatar.getHead().getWorldAlignedOrientation()); + _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation()); } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { _myCamera.setTargetPosition(_myAvatar.getHeadPosition()); - _myCamera.setTargetRotation(_gyroEyeOffset->isChecked() ? _myAvatar.getWorldAlignedOrientation() : - _myAvatar.getHead().getWorldAlignedOrientation()); + _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation()); } // important... @@ -1126,7 +1124,6 @@ void Application::initMenu() { optionsMenu->addAction("Noise", this, SLOT(setNoise(bool)), Qt::Key_N)->setCheckable(true); (_gyroLook = optionsMenu->addAction("Gyro Look"))->setCheckable(true); _gyroLook->setChecked(true); - (_gyroEyeOffset = optionsMenu->addAction("Gyro Eye Offset"))->setCheckable(true); (_mouseLook = optionsMenu->addAction("Mouse Look"))->setCheckable(true); _mouseLook->setChecked(false); (_showHeadMouse = optionsMenu->addAction("Head Mouse"))->setCheckable(true); @@ -1297,12 +1294,6 @@ void Application::updateAvatar(float deltaTime) { _headMouseY = max(_headMouseY, 0); _headMouseY = min(_headMouseY, _glWidget->height()); - if (_gyroEyeOffset->isChecked()) { - _eyeOffsetVelocity += _serialPort.getLastAcceleration() * deltaTime; - _myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + _eyeOffsetVelocity * deltaTime); - resizeGL(_glWidget->width(), _glWidget->height()); - } - if (OculusManager::isConnected()) { float yaw, pitch, roll; OculusManager::getEulerAngles(yaw, pitch, roll); @@ -2095,9 +2086,6 @@ void Application::resetSensors() { QCursor::setPos(_headMouseX, _headMouseY); _myAvatar.reset(); _myTransmitter.resetLevels(); - _myCamera.setEyeOffsetPosition(glm::vec3(0.0f, 0.0f, 0.0f)); - _eyeOffsetVelocity = glm::vec3(0.0f, 0.0f, 0.0f); - resizeGL(_glWidget->width(), _glWidget->height()); } static void setShortcutsEnabled(QWidget* widget, bool enabled) { diff --git a/interface/src/Application.h b/interface/src/Application.h index d4caeca329..64959f1274 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -143,7 +143,6 @@ private: QAction* _lookingInMirror; // Are we currently rendering one's own head as if in mirror? QAction* _echoAudioMode; // Are we asking the mixer to echo back our audio? QAction* _gyroLook; // Whether to allow the gyro data from head to move your view - QAction* _gyroEyeOffset; // Whether to allow the gyro data to move your eye offset QAction* _mouseLook; // Whether the have the mouse near edge of screen move your view QAction* _showHeadMouse; // Whether the have the mouse near edge of screen move your view QAction* _transmitterDrives; // Whether to have Transmitter data move/steer the Avatar @@ -207,7 +206,6 @@ private: Camera _myCamera; // My view onto the world Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode - glm::vec3 _eyeOffsetVelocity; Environment _environment; From 224e5d666dc005927d3931510a3c752e686fed9b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 30 May 2013 17:12:18 -0700 Subject: [PATCH 66/66] Fix for segmentation fault when the settings file doesn't exist. --- interface/src/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 68f4e7bf19..4dd3dba178 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -774,9 +774,9 @@ void Application::readSettingsFile() { } } } - } - fclose(settingsFile); + fclose(settingsFile); + } } void Application::saveSettingsFile() {