From 17a5e6a700cd0cbd7046949040cd21650ffcb610 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 27 May 2013 12:37:42 -0400 Subject: [PATCH 01/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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 c33d2ee25ef5a62f48ed6955f914ac6002513e77 Mon Sep 17 00:00:00 2001 From: Geenz Date: Wed, 29 May 2013 16:46:47 -0400 Subject: [PATCH 07/51] 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 66c7da6552004fdc60ab30f034e7f95895dbaa4d Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 15:24:37 -0700 Subject: [PATCH 08/51] simplify avatar proximity check for 1p transition --- interface/src/Avatar.cpp | 5 ++--- interface/src/AvatarTouch.cpp | 5 +++-- interface/src/Head.cpp | 5 ++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 68fd9b1c8e..8d3f3c27ac 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1096,10 +1096,9 @@ void Avatar::updateArmIKAndConstraints(float deltaTime) { } // set elbow position - glm::vec3 newElbowPosition = _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; - newElbowPosition += armVector * ONE_HALF; + glm::vec3 newElbowPosition = _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position + armVector * ONE_HALF; - glm::vec3 perpendicular = glm::cross(_orientation.getFront(), armVector); + glm::vec3 perpendicular = glm::cross( _orientation.getRight(), armVector); newElbowPosition += perpendicular * (1.0f - (_maxArmLength / distance)) * ONE_HALF; _joint[ AVATAR_JOINT_RIGHT_ELBOW ].position = newElbowPosition; diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 93899c8400..e7703a3f00 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -54,8 +54,9 @@ void AvatarTouch::simulate (float deltaTime) { facingEachOther = true; } - if ((distanceBetweenBodies < _reachableRadius) - && (facingEachOther)) { + if (distanceBetweenBodies < _reachableRadius) + //&& (facingEachOther)) + { _canReachToOtherAvatar = true; _vectorBetweenHands = _yourHandPosition - _myHandPosition; diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 6f7f330010..a68e36d53b 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -18,7 +18,6 @@ const float EYE_RIGHT_OFFSET = 0.27f; const float EYE_UP_OFFSET = 0.36f; const float EYE_FRONT_OFFSET = 0.8f; const float EAR_RIGHT_OFFSET = 1.0; -//const float MOUTH_FRONT_OFFSET = 0.9f; const float MOUTH_UP_OFFSET = -0.3f; const float HEAD_MOTION_DECAY = 0.1; const float MINIMUM_EYE_ROTATION_DOT = 0.5f; // based on a dot product: 1.0 is straight ahead, 0.0 is 90 degrees off @@ -281,7 +280,7 @@ void Head::renderMohawk(bool lookingInMirror, glm::vec3 cameraPosition) { glm::vec3 mid2 = _hairTuft[t].midPosition + midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; glColor3f(_mohawkColors[t].x, _mohawkColors[t].y, _mohawkColors[t].z); - + glBegin(GL_TRIANGLES); glVertex3f(base1.x, base1.y, base1.z ); glVertex3f(base2.x, base2.y, base2.z ); @@ -354,7 +353,7 @@ 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; + float constrainedRadius = _scale + 0.002f; middle = _position + glm::normalize(middle - _position) * constrainedRadius; leftCorner = _position + glm::normalize(leftCorner - _position) * constrainedRadius; rightCorner = _position + glm::normalize(rightCorner - _position) * constrainedRadius; From 5750adf6fd1d977395568d2985348f2c3179f02e Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 15:53:47 -0700 Subject: [PATCH 09/51] test --- interface/src/AvatarTouch.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index e7703a3f00..b7d8fffcbb 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -53,6 +53,8 @@ void AvatarTouch::simulate (float deltaTime) { && ( glm::dot(_myOrientation.getFront(), directionBetweenBodies ) > AVATAR_FACING_THRESHOLD)) { // I'm facing you facingEachOther = true; } + + ///udhfhduf if (distanceBetweenBodies < _reachableRadius) //&& (facingEachOther)) From 63434da23cf7f3968e47a231f3cc7a35ba59358e Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 16:14:55 -0700 Subject: [PATCH 10/51] testing avatar touch --- interface/src/Application.cpp | 41 +++++++++++++++++++++-------------- interface/src/Avatar.cpp | 15 ++++++++----- interface/src/AvatarTouch.cpp | 2 -- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f307efa470..95b4d88b33 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -50,6 +50,8 @@ using namespace std; +const bool TESTING_AVATAR_TOUCH = true; + // Starfield information static char STAR_FILE[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt"; static char STAR_CACHE_FILE[] = "cachedStars.txt"; @@ -915,29 +917,36 @@ void Application::idle() { _myAvatar.simulate(deltaTime, NULL); } - if (_myCamera.getMode() != CAMERA_MODE_MIRROR && !OculusManager::isConnected()) { - if (_manualFirstPerson) { - if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) { - _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); - _myCamera.setModeShiftRate(1.0f); - } - } else { - - if (_myAvatar.getIsNearInteractingOther()) { - if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { + if ( TESTING_AVATAR_TOUCH) { + if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { + _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); + _myCamera.setModeShiftRate(1.0f); + } + } else { + if (_myCamera.getMode() != CAMERA_MODE_MIRROR && !OculusManager::isConnected()) { + if (_manualFirstPerson) { + if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) { _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); _myCamera.setModeShiftRate(1.0f); } - } - else { - if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { - _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); - _myCamera.setModeShiftRate(1.0f); + } else { + + if (_myAvatar.getIsNearInteractingOther()) { + if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { + _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + _myCamera.setModeShiftRate(1.0f); + } + } + else { + if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { + _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); + _myCamera.setModeShiftRate(1.0f); + } } } } } - + // Update audio stats for procedural sounds #ifndef _WIN32 _audio.setLastAcceleration(_myAvatar.getThrust()); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 8d3f3c27ac..6e37d5807f 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -37,11 +37,11 @@ const float YOUR_HAND_HOLDING_PULL = 1.0; const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f; const float BODY_SPRING_FORCE = 300.0f; const float BODY_SPRING_DECAY = 16.0f; -const float COLLISION_RADIUS_SCALAR = 1.8; -const float COLLISION_BALL_FORCE = 1.0; -const float COLLISION_BODY_FORCE = 6.0; -const float COLLISION_BALL_FRICTION = 60.0; -const float COLLISION_BODY_FRICTION = 0.5; +const float COLLISION_RADIUS_SCALAR = 1.8; //pertains to avatar-to-avatar collisions +const float COLLISION_BALL_FORCE = 1.0; //pertains to avatar-to-avatar collisions +const float COLLISION_BODY_FORCE = 6.0; //pertains to avatar-to-avatar collisions +const float COLLISION_BALL_FRICTION = 60.0; //pertains to avatar-to-avatar collisions +const float COLLISION_BODY_FRICTION = 0.5; //pertains to avatar-to-avatar collisions const float HEAD_ROTATION_SCALE = 0.70; const float HEAD_ROLL_SCALE = 0.40; const float HEAD_MAX_PITCH = 45; @@ -689,6 +689,8 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime for (int o=b+1; o_joint[o].isCollidable) { + /* + glm::vec3 vectorBetweenJoints(_joint[b].springyPosition - otherAvatar->_joint[o].springyPosition); float distanceBetweenJoints = glm::length(vectorBetweenJoints); @@ -718,12 +720,13 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime }// check for collision } // to avoid divide by zero + */ + } // o loop } // collidable } // b loop } // collidable - //apply forces and frictions on the bodies of both avatars _velocity += bodyPushForce; otherAvatar->_velocity -= bodyPushForce; diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index b7d8fffcbb..a6b4a168cb 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -54,8 +54,6 @@ void AvatarTouch::simulate (float deltaTime) { facingEachOther = true; } - ///udhfhduf - if (distanceBetweenBodies < _reachableRadius) //&& (facingEachOther)) { From 4c7d75b39e97e7f00ff52f692e594b875a1724f8 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 16:52:48 -0700 Subject: [PATCH 11/51] testing avatar touch --- interface/src/Avatar.cpp | 36 +++++++++++++++++++++++++++--------- interface/src/Head.cpp | 2 +- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 6e37d5807f..c7dfeb2834 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -37,11 +37,22 @@ const float YOUR_HAND_HOLDING_PULL = 1.0; const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f; const float BODY_SPRING_FORCE = 300.0f; const float BODY_SPRING_DECAY = 16.0f; + +/* const float COLLISION_RADIUS_SCALAR = 1.8; //pertains to avatar-to-avatar collisions const float COLLISION_BALL_FORCE = 1.0; //pertains to avatar-to-avatar collisions const float COLLISION_BODY_FORCE = 6.0; //pertains to avatar-to-avatar collisions const float COLLISION_BALL_FRICTION = 60.0; //pertains to avatar-to-avatar collisions const float COLLISION_BODY_FRICTION = 0.5; //pertains to avatar-to-avatar collisions +*/ + +const float COLLISION_RADIUS_SCALAR = 1.2; //pertains to avatar-to-avatar collisions +const float COLLISION_BALL_FORCE = 20.0; //pertains to avatar-to-avatar collisions +const float COLLISION_BODY_FORCE = 6.0; //pertains to avatar-to-avatar collisions +const float COLLISION_BALL_FRICTION = 60.0; //pertains to avatar-to-avatar collisions +const float COLLISION_BODY_FRICTION = 0.5; //pertains to avatar-to-avatar collisions + + const float HEAD_ROTATION_SCALE = 0.70; const float HEAD_ROLL_SCALE = 0.40; const float HEAD_MAX_PITCH = 45; @@ -50,7 +61,7 @@ const float HEAD_MAX_YAW = 85; 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 JOINT_TOUCH_RANGE = 0.01f; const float ANGULAR_RIGHTING_SPEED = 45.0f; const float FLOATING_HEIGHT = 0.13f; const bool USING_HEAD_LEAN = false; @@ -452,8 +463,10 @@ void Avatar::checkForMouseRayTouching() { glm::vec3 directionToBodySphere = glm::normalize(_joint[b].springyPosition - _mouseRayOrigin); float dot = glm::dot(directionToBodySphere, _mouseRayDirection); - if (dot > (1.0f - JOINT_TOUCH_RANGE)) { - _joint[b].touchForce = (dot - (1.0f - JOINT_TOUCH_RANGE)) / JOINT_TOUCH_RANGE; + float range = _joint[b].radius * JOINT_TOUCH_RANGE; + + if (dot > (1.0f - range)) { + _joint[b].touchForce = (dot - (1.0f - range)) / range; } else { _joint[b].touchForce = 0.0; } @@ -689,8 +702,6 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime for (int o=b+1; o_joint[o].isCollidable) { - /* - glm::vec3 vectorBetweenJoints(_joint[b].springyPosition - otherAvatar->_joint[o].springyPosition); float distanceBetweenJoints = glm::length(vectorBetweenJoints); @@ -703,13 +714,21 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime // push balls away from each other and apply friction glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * deltaTime; - + + /* float ballMomentum = 1.0 - COLLISION_BALL_FRICTION * deltaTime; if (ballMomentum < 0.0) { ballMomentum = 0.0;} - + */ + _joint[b].springyVelocity += ballPushForce; otherAvatar->_joint[o].springyVelocity -= ballPushForce; + + float shift = distanceBetweenJoints - combinedRadius * COLLISION_RADIUS_SCALAR; + _joint[b].springyPosition += directionVector * shift; + otherAvatar->_joint[o].springyPosition -= directionVector * shift; + + /* _joint[b].springyVelocity *= ballMomentum; otherAvatar->_joint[o].springyVelocity *= ballMomentum; @@ -717,11 +736,10 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime bodyPushForce += directionVector * COLLISION_BODY_FORCE * deltaTime; bodyMomentum -= COLLISION_BODY_FRICTION * deltaTime; if (bodyMomentum < 0.0) { bodyMomentum = 0.0;} + */ }// check for collision } // to avoid divide by zero - */ - } // o loop } // collidable } // b loop diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index a68e36d53b..cdc11b4506 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -361,7 +361,7 @@ void Head::renderMouth() { rightTop = _position + glm::normalize(rightTop - _position) * constrainedRadius; leftBottom = _position + glm::normalize(leftBottom - _position) * constrainedRadius; rightBottom = _position + glm::normalize(rightBottom - _position) * constrainedRadius; - + glColor3f(0.2f, 0.0f, 0.0f); glBegin(GL_TRIANGLES); From 88ff0ea7aa5038b34b12515184f56ea741430a14 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 16:54:15 -0700 Subject: [PATCH 12/51] merge --- 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 cdc11b4506..28d7a23b2f 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -353,7 +353,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.002f; + 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 d839312cd6a594091980b4d10639ad6c07cfb23e Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 17:28:44 -0700 Subject: [PATCH 13/51] testing avatar touch --- interface/src/Avatar.cpp | 42 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index c7dfeb2834..99862cfc98 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -38,21 +38,12 @@ const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f; const float BODY_SPRING_FORCE = 300.0f; const float BODY_SPRING_DECAY = 16.0f; -/* -const float COLLISION_RADIUS_SCALAR = 1.8; //pertains to avatar-to-avatar collisions -const float COLLISION_BALL_FORCE = 1.0; //pertains to avatar-to-avatar collisions -const float COLLISION_BODY_FORCE = 6.0; //pertains to avatar-to-avatar collisions -const float COLLISION_BALL_FRICTION = 60.0; //pertains to avatar-to-avatar collisions -const float COLLISION_BODY_FRICTION = 0.5; //pertains to avatar-to-avatar collisions -*/ - const float COLLISION_RADIUS_SCALAR = 1.2; //pertains to avatar-to-avatar collisions -const float COLLISION_BALL_FORCE = 20.0; //pertains to avatar-to-avatar collisions -const float COLLISION_BODY_FORCE = 6.0; //pertains to avatar-to-avatar collisions +const float COLLISION_BALL_FORCE = 200.0; //pertains to avatar-to-avatar collisions +const float COLLISION_BODY_FORCE = 30.0; //pertains to avatar-to-avatar collisions const float COLLISION_BALL_FRICTION = 60.0; //pertains to avatar-to-avatar collisions const float COLLISION_BODY_FRICTION = 0.5; //pertains to avatar-to-avatar collisions - const float HEAD_ROTATION_SCALE = 0.70; const float HEAD_ROLL_SCALE = 0.40; const float HEAD_MAX_PITCH = 45; @@ -713,7 +704,11 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime glm::vec3 directionVector = vectorBetweenJoints / distanceBetweenJoints; // push balls away from each other and apply friction - glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * deltaTime; + + float penetration = 1.0f - (distanceBetweenJoints / (combinedRadius * COLLISION_RADIUS_SCALAR)); + + glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * penetration * deltaTime; + bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime; /* float ballMomentum = 1.0 - COLLISION_BALL_FRICTION * deltaTime; @@ -722,21 +717,26 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime _joint[b].springyVelocity += ballPushForce; otherAvatar->_joint[o].springyVelocity -= ballPushForce; + + /* float shift = distanceBetweenJoints - combinedRadius * COLLISION_RADIUS_SCALAR; - _joint[b].springyPosition += directionVector * shift; - otherAvatar->_joint[o].springyPosition -= directionVector * shift; + _joint[b].springyPosition += directionVector * 2.0f * deltaTime; + otherAvatar->_joint[o].springyPosition -= directionVector * 2.0f * deltaTime; + */ + /* _joint[b].springyVelocity *= ballMomentum; otherAvatar->_joint[o].springyVelocity *= ballMomentum; + */ // accumulate forces and frictions to apply to the velocities of avatar bodies - bodyPushForce += directionVector * COLLISION_BODY_FORCE * deltaTime; - bodyMomentum -= COLLISION_BODY_FRICTION * deltaTime; - if (bodyMomentum < 0.0) { bodyMomentum = 0.0;} - */ + //bodyPushForce += directionVector * COLLISION_BODY_FORCE * deltaTime; + //bodyMomentum -= COLLISION_BODY_FRICTION * deltaTime; + //if (bodyMomentum < 0.0) { bodyMomentum = 0.0;} + }// check for collision } // to avoid divide by zero @@ -747,9 +747,9 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime //apply forces and frictions on the bodies of both avatars _velocity += bodyPushForce; - otherAvatar->_velocity -= bodyPushForce; - _velocity *= bodyMomentum; - otherAvatar->_velocity *= bodyMomentum; +//otherAvatar->_velocity -= bodyPushForce; + // _velocity *= bodyMomentum; + //otherAvatar->_velocity *= bodyMomentum; } From d6855b643078e5888daa6fbe002979161281ca64 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 29 May 2013 19:05:33 -0700 Subject: [PATCH 14/51] 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 15/51] 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 16/51] 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 17/51] 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 18/51] 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 19/51] 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 1eac57dd0c5f7a8bced6f2e51093ae885edd4ca7 Mon Sep 17 00:00:00 2001 From: Geenz Date: Thu, 30 May 2013 15:02:11 -0400 Subject: [PATCH 20/51] #19351 - Atmosphere shaders should be handled per-pixel instead of per-vertex. --- .../resources/shaders/SkyFromAtmosphere.frag | 154 +++++++++++----- .../resources/shaders/SkyFromAtmosphere.vert | 165 +++++++----------- interface/resources/shaders/SkyFromSpace.frag | 161 ++++++++++++----- interface/resources/shaders/SkyFromSpace.vert | 150 +++++----------- 4 files changed, 325 insertions(+), 305 deletions(-) diff --git a/interface/resources/shaders/SkyFromAtmosphere.frag b/interface/resources/shaders/SkyFromAtmosphere.frag index 37d26ba40a..c7fedd4e4a 100644 --- a/interface/resources/shaders/SkyFromAtmosphere.frag +++ b/interface/resources/shaders/SkyFromAtmosphere.frag @@ -1,48 +1,106 @@ -#version 120 - -// -// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html: -// -// NVIDIA Statement on the Software -// -// The source code provided is freely distributable, so long as the NVIDIA header remains unaltered and user modifications are -// detailed. -// -// No Warranty -// -// THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA ON THE ENCLOSED CD-ROM ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL -// WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// -// Limitation of Liability -// -// NVIDIA SHALL NOT BE LIABLE TO ANY USER, DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR -// UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT -// OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY -// LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH -// OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS. -// - -// -// Atmospheric scattering fragment shader -// -// Author: Sean O'Neil -// -// Copyright (c) 2004 Sean O'Neil -// - -uniform vec3 v3LightPos; -uniform float g; -uniform float g2; - -varying vec3 v3Direction; - - -void main (void) -{ - float fCos = dot(v3LightPos, v3Direction) / length(v3Direction); - float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5); - gl_FragColor = gl_Color + fMiePhase * gl_SecondaryColor; - gl_FragColor.a = gl_FragColor.b; -} +#version 120 + +// +// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html: +// +// NVIDIA Statement on the Software +// +// The source code provided is freely distributable, so long as the NVIDIA header remains unaltered and user modifications are +// detailed. +// +// No Warranty +// +// THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA ON THE ENCLOSED CD-ROM ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL +// WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +// Limitation of Liability +// +// NVIDIA SHALL NOT BE LIABLE TO ANY USER, DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR +// UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT +// OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY +// LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH +// OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS. +// + +// +// Atmospheric scattering fragment shader +// +// Author: Sean O'Neil +// +// Copyright (c) 2004 Sean O'Neil +// + +uniform vec3 v3CameraPos; // The camera's current position +uniform vec3 v3InvWavelength; // 1 / pow(wavelength, 4) for the red, green, and blue channels +uniform float fInnerRadius; // The inner (planetary) radius +uniform float fKrESun; // Kr * ESun +uniform float fKmESun; // Km * ESun +uniform float fKr4PI; // Kr * 4 * PI +uniform float fKm4PI; // Km * 4 * PI +uniform float fScale; // 1 / (fOuterRadius - fInnerRadius) +uniform float fScaleDepth; // The scale depth (i.e. the altitude at which the atmosphere's average density is found) +uniform float fScaleOverScaleDepth; // fScale / fScaleDepth + +const int nSamples = 2; +const float fSamples = 2.0; + +uniform vec3 v3LightPos; +uniform float g; +uniform float g2; + +varying vec3 position; + +float scale(float fCos) +{ + float x = 1.0 - fCos; + return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25)))); +} + +void main (void) +{ + // Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere) + vec3 v3Pos = position; + vec3 v3Ray = v3Pos - v3CameraPos; + float fFar = length(v3Ray); + v3Ray /= fFar; + + // Calculate the ray's starting position, then calculate its scattering offset + vec3 v3Start = v3CameraPos; + float fHeight = length(v3Start); + float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight)); + float fStartAngle = dot(v3Ray, v3Start) / fHeight; + float fStartOffset = fDepth * scale(fStartAngle); + + // Initialize the scattering loop variables + //gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0); + float fSampleLength = fFar / fSamples; + float fScaledLength = fSampleLength * fScale; + vec3 v3SampleRay = v3Ray * fSampleLength; + vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5; + + // Now loop through the sample rays + vec3 v3FrontColor = vec3(0.0, 0.0, 0.0); + for(int i=0; i Date: Thu, 30 May 2013 12:12:30 -0700 Subject: [PATCH 21/51] 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 22/51] 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 23/51] 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 24/51] 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 25/51] 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 26/51] 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 27/51] 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 28/51] 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 29/51] 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 30/51] 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 31/51] 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 32/51] 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 33/51] 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 34/51] 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 35/51] 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 36/51] 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 37/51] 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 38/51] 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 39/51] 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() { From 98759c3ba16fef0e98f422acdb93315743a639fe Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 31 May 2013 10:27:25 -0700 Subject: [PATCH 40/51] Include to address a build error experienced by Clement. --- libraries/shared/src/SharedUtil.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 8da9d7beca..d117bac39f 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -10,6 +10,7 @@ #define __hifi__SharedUtil__ #include +#include #include #ifdef _WIN32 From 108ce62d1a05a419e3efbe815776352ba21c8b4c Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 31 May 2013 11:51:03 -0700 Subject: [PATCH 41/51] committing latest skeleton-separation changes (more to come as Andrzej and I work on it more) --- interface/src/Avatar.cpp | 395 ++++++++++--------------------------- interface/src/Avatar.h | 11 +- interface/src/Camera.cpp | 2 +- interface/src/Skeleton.cpp | 214 +++++++++++++++++++- interface/src/Skeleton.h | 38 +++- 5 files changed, 360 insertions(+), 300 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 99862cfc98..7e5ce36387 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -107,7 +107,11 @@ Avatar::Avatar(Agent* owningAgent) : _driveKeys[i] = false; } - initializeSkeleton(); + _skeleton.initialize(); + + _maxArmLength = _skeleton.getArmLength(); + _pelvisStandingHeight = _skeleton.getPelvisStandingHeight(); + _pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight(); _avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS); @@ -218,10 +222,20 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // update balls if (_balls) { _balls->simulate(deltaTime); } - // if other avatar, update head position from network data - + // create orientation directions based on yaw/pitch/roll... + _orientation.setToIdentity(); + _orientation.yaw (_bodyYaw ); + _orientation.pitch(_bodyPitch); + _orientation.roll (_bodyRoll ); + _orientation.rotate(_righting); + // update avatar skeleton - updateSkeleton(); + _skeleton.update(deltaTime, _orientation, _position); + + // if this is not my avatar, then hand position comes from transmitted data + if (_owningAgent) { + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition; + } //detect and respond to collisions with other avatars... if (!_owningAgent) { @@ -405,22 +419,22 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _orientation.getRight() * _head.getLeanSideways() + _orientation.getFront() * _head.getLeanForward(); - _joint[ AVATAR_JOINT_TORSO ].springyPosition += headLean * 0.1f; - _joint[ AVATAR_JOINT_CHEST ].springyPosition += headLean * 0.4f; - _joint[ AVATAR_JOINT_NECK_BASE ].springyPosition += headLean * 0.7f; - _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition += headLean * 1.0f; + _skeleton.joint[ AVATAR_JOINT_TORSO ].springyPosition += headLean * 0.1f; + _skeleton.joint[ AVATAR_JOINT_CHEST ].springyPosition += headLean * 0.4f; + _skeleton.joint[ AVATAR_JOINT_NECK_BASE ].springyPosition += headLean * 0.7f; + _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition += headLean * 1.0f; - _joint[ AVATAR_JOINT_LEFT_COLLAR ].springyPosition += headLean * 0.6f; - _joint[ AVATAR_JOINT_LEFT_SHOULDER ].springyPosition += headLean * 0.6f; - _joint[ AVATAR_JOINT_LEFT_ELBOW ].springyPosition += headLean * 0.2f; - _joint[ AVATAR_JOINT_LEFT_WRIST ].springyPosition += headLean * 0.1f; - _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].springyPosition += headLean * 0.0f; + _skeleton.joint[ AVATAR_JOINT_LEFT_COLLAR ].springyPosition += headLean * 0.6f; + _skeleton.joint[ AVATAR_JOINT_LEFT_SHOULDER ].springyPosition += headLean * 0.6f; + _skeleton.joint[ AVATAR_JOINT_LEFT_ELBOW ].springyPosition += headLean * 0.2f; + _skeleton.joint[ AVATAR_JOINT_LEFT_WRIST ].springyPosition += headLean * 0.1f; + _skeleton.joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].springyPosition += headLean * 0.0f; - _joint[ AVATAR_JOINT_RIGHT_COLLAR ].springyPosition += headLean * 0.6f; - _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].springyPosition += headLean * 0.6f; - _joint[ AVATAR_JOINT_RIGHT_ELBOW ].springyPosition += headLean * 0.2f; - _joint[ AVATAR_JOINT_RIGHT_WRIST ].springyPosition += headLean * 0.1f; - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition += headLean * 0.0f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_COLLAR ].springyPosition += headLean * 0.6f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].springyPosition += headLean * 0.6f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_ELBOW ].springyPosition += headLean * 0.2f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_WRIST ].springyPosition += headLean * 0.1f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition += headLean * 0.0f; } } @@ -434,8 +448,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } _head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); - _head.setPosition(_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition); - _head.setScale (_joint[ AVATAR_JOINT_HEAD_BASE ].radius); + _head.setPosition(_skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition); + _head.setScale (_skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].radius); _head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2])); _head.simulate(deltaTime, !_owningAgent); @@ -451,15 +465,15 @@ void Avatar::checkForMouseRayTouching() { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 directionToBodySphere = glm::normalize(_joint[b].springyPosition - _mouseRayOrigin); + glm::vec3 directionToBodySphere = glm::normalize(_skeleton.joint[b].springyPosition - _mouseRayOrigin); float dot = glm::dot(directionToBodySphere, _mouseRayDirection); - float range = _joint[b].radius * JOINT_TOUCH_RANGE; + float range = _skeleton.joint[b].radius * JOINT_TOUCH_RANGE; if (dot > (1.0f - range)) { - _joint[b].touchForce = (dot - (1.0f - range)) / range; + _skeleton.joint[b].touchForce = (dot - (1.0f - range)) / range; } else { - _joint[b].touchForce = 0.0; + _skeleton.joint[b].touchForce = 0.0; } } } @@ -477,7 +491,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { + _orientation.getUp() * -_movedHandOffset.y * 2.0f + _orientation.getFront() * -_movedHandOffset.y * 2.0f; - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement; + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement; if (!_owningAgent) { _avatarTouch.setMyBodyPosition(_position); @@ -516,7 +530,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { _avatarTouch.setHasInteractingOther(true); _avatarTouch.setYourBodyPosition(_interactingOther->_position); _avatarTouch.setYourOrientation (_interactingOther->_orientation); - _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); + _avatarTouch.setYourHandPosition(_interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); _avatarTouch.setYourHandState (_interactingOther->_handState); //if hand-holding is initiated by either avatar, turn on hand-holding... @@ -531,8 +545,8 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { glm::vec3 vectorFromMyHandToYourHand ( - _interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position + _interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position ); float distanceBetweenOurHands = glm::length(vectorFromMyHandToYourHand); @@ -554,10 +568,10 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { //if holding hands, apply the appropriate forces if (_avatarTouch.getHoldingHands()) { - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += ( - _interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position + _interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position + - _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position ) * 0.5f; if (distanceBetweenOurHands > 0.3) { @@ -577,7 +591,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { //Set right hand position and state to be transmitted, and also tell AvatarTouch about it if (!_owningAgent) { - setHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); + setHandPosition(_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); if (_mousePressed) { _handState = HAND_STATE_GRASPING; @@ -586,7 +600,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { } _avatarTouch.setMyHandState(_handState); - _avatarTouch.setMyHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); + _avatarTouch.setMyHandPosition(_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); } } @@ -598,9 +612,9 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere); if (distanceToBigSphere < myBodyApproximateBoundingRadius + radius) { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 vectorFromJointToBigSphereCenter(_joint[b].springyPosition - position); + glm::vec3 vectorFromJointToBigSphereCenter(_skeleton.joint[b].springyPosition - position); float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter); - float combinedRadius = _joint[b].radius + radius; + float combinedRadius = _skeleton.joint[b].radius + radius; if (distanceToBigSphereCenter < combinedRadius) { jointCollision = true; @@ -610,9 +624,9 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius); glm::vec3 collisionForce = vectorFromJointToBigSphereCenter * penetration; - _joint[b].springyVelocity += collisionForce * 0.0f * deltaTime; + _skeleton.joint[b].springyVelocity += collisionForce * 0.0f * deltaTime; _velocity += collisionForce * 40.0f * deltaTime; - _joint[b].springyPosition = position + directionVector * combinedRadius; + _skeleton.joint[b].springyPosition = position + directionVector * combinedRadius; } } } @@ -669,7 +683,7 @@ void Avatar::updateAvatarCollisions(float deltaTime) { } // test other avatar hand position for proximity - glm::vec3 v(_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position); + glm::vec3 v(_skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position); v -= otherAvatar->getPosition(); float distance = glm::length(v); @@ -688,16 +702,16 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime // loop through the joints of each avatar to check for every possible collision for (int b=1; b_joint[o].isCollidable) { + if (otherAvatar->_skeleton.joint[o].isCollidable) { - glm::vec3 vectorBetweenJoints(_joint[b].springyPosition - otherAvatar->_joint[o].springyPosition); + glm::vec3 vectorBetweenJoints(_skeleton.joint[b].springyPosition - otherAvatar->_skeleton.joint[o].springyPosition); float distanceBetweenJoints = glm::length(vectorBetweenJoints); if (distanceBetweenJoints > 0.0) { // to avoid divide by zero - float combinedRadius = _joint[b].radius + otherAvatar->_joint[o].radius; + float combinedRadius = _skeleton.joint[b].radius + otherAvatar->_skeleton.joint[o].radius; // check for collision if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) { @@ -715,21 +729,21 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime if (ballMomentum < 0.0) { ballMomentum = 0.0;} */ - _joint[b].springyVelocity += ballPushForce; - otherAvatar->_joint[o].springyVelocity -= ballPushForce; + _skeleton.joint[b].springyVelocity += ballPushForce; + otherAvatar->_skeleton.joint[o].springyVelocity -= ballPushForce; /* float shift = distanceBetweenJoints - combinedRadius * COLLISION_RADIUS_SCALAR; - _joint[b].springyPosition += directionVector * 2.0f * deltaTime; - otherAvatar->_joint[o].springyPosition -= directionVector * 2.0f * deltaTime; + _skeleton.joint[b].springyPosition += directionVector * 2.0f * deltaTime; + otherAvatar->_skeleton.joint[o].springyPosition -= directionVector * 2.0f * deltaTime; */ /* - _joint[b].springyVelocity *= ballMomentum; - otherAvatar->_joint[o].springyVelocity *= ballMomentum; + _skeleton.joint[b].springyVelocity *= ballMomentum; + otherAvatar->_skeleton.joint[o].springyVelocity *= ballMomentum; */ // accumulate forces and frictions to apply to the velocities of avatar bodies @@ -810,9 +824,9 @@ void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { 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); + glTranslatef(_skeleton.joint[AVATAR_JOINT_HEAD_BASE].springyPosition.x, + _skeleton.joint[AVATAR_JOINT_HEAD_BASE].springyPosition.y + chatMessageHeight, + _skeleton.joint[AVATAR_JOINT_HEAD_BASE].springyPosition.z); glRotatef(atan2(-modelview[2], -modelview[10]) * 180 / PI, 0, 1, 0); glColor3f(0, 0.8, 0); @@ -842,219 +856,20 @@ void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { } } -void Avatar::initializeSkeleton() { - - for (int b=0; b BEYOND_BODY_SPRING_RANGE) { - initializeBodySprings(); + if (glm::length(_position - _skeleton.joint[AVATAR_JOINT_PELVIS].springyPosition) > BEYOND_BODY_SPRING_RANGE) { + _skeleton.initializeBodySprings(); } for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 springVector(_joint[b].springyPosition); + glm::vec3 springVector(_skeleton.joint[b].springyPosition); - if (_joint[b].parent == AVATAR_JOINT_NULL) { + if (_skeleton.joint[b].parent == AVATAR_JOINT_NULL) { springVector -= _position; } else { - springVector -= _joint[ _joint[b].parent ].springyPosition; + springVector -= _skeleton.joint[ _skeleton.joint[b].parent ].springyPosition; } float length = glm::length(springVector); @@ -1062,44 +877,44 @@ void Avatar::updateBodySprings(float deltaTime) { if (length > 0.0f) { // to avoid divide by zero glm::vec3 springDirection = springVector / length; - float force = (length - _joint[b].length) * BODY_SPRING_FORCE * deltaTime; + float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime; - _joint[b].springyVelocity -= springDirection * force; + _skeleton.joint[b].springyVelocity -= springDirection * force; - if (_joint[b].parent != AVATAR_JOINT_NULL) { - _joint[_joint[b].parent].springyVelocity += springDirection * force; + if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) { + _skeleton.joint[_skeleton.joint[b].parent].springyVelocity += springDirection * force; } } // 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; + _skeleton.joint[b].springyVelocity += (_skeleton.joint[b].position - _skeleton.joint[b].springyPosition) * _skeleton.joint[b].springBodyTightness * deltaTime; // apply decay float decay = 1.0 - BODY_SPRING_DECAY * deltaTime; if (decay > 0.0) { - _joint[b].springyVelocity *= decay; + _skeleton.joint[b].springyVelocity *= decay; } else { - _joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + _skeleton.joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f); } /* //apply forces from touch... - if (_joint[b].touchForce > 0.0) { - _joint[b].springyVelocity += _mouseRayDirection * _joint[b].touchForce * 0.7f; + if (_skeleton.joint[b].touchForce > 0.0) { + _skeleton.joint[b].springyVelocity += _mouseRayDirection * _skeleton.joint[b].touchForce * 0.7f; } */ //update position by velocity... - _joint[b].springyPosition += _joint[b].springyVelocity * deltaTime; + _skeleton.joint[b].springyPosition += _skeleton.joint[b].springyVelocity * deltaTime; } } void Avatar::updateArmIKAndConstraints(float deltaTime) { // determine the arm vector - glm::vec3 armVector = _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position; - armVector -= _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; + glm::vec3 armVector = _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position; + armVector -= _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; // test to see if right hand is being dragged beyond maximum arm length float distance = glm::length(armVector); @@ -1107,28 +922,28 @@ void Avatar::updateArmIKAndConstraints(float deltaTime) { // don't let right hand get dragged beyond maximum arm length... if (distance > _maxArmLength) { // reset right hand to be constrained to maximum arm length - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; glm::vec3 armNormal = armVector / distance; armVector = armNormal * _maxArmLength; distance = _maxArmLength; - glm::vec3 constrainedPosition = _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; + glm::vec3 constrainedPosition = _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; constrainedPosition += armVector; - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = constrainedPosition; + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = constrainedPosition; } // set elbow position - glm::vec3 newElbowPosition = _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position + armVector * ONE_HALF; + glm::vec3 newElbowPosition = _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position + armVector * ONE_HALF; glm::vec3 perpendicular = glm::cross( _orientation.getRight(), armVector); newElbowPosition += perpendicular * (1.0f - (_maxArmLength / distance)) * ONE_HALF; - _joint[ AVATAR_JOINT_RIGHT_ELBOW ].position = newElbowPosition; + _skeleton.joint[ AVATAR_JOINT_RIGHT_ELBOW ].position = newElbowPosition; // set wrist position - glm::vec3 vv(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); - vv -= _joint[ AVATAR_JOINT_RIGHT_ELBOW ].position; - glm::vec3 newWristPosition = _joint[ AVATAR_JOINT_RIGHT_ELBOW ].position + vv * 0.7f; - _joint[ AVATAR_JOINT_RIGHT_WRIST ].position = newWristPosition; + glm::vec3 vv(_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); + vv -= _skeleton.joint[ AVATAR_JOINT_RIGHT_ELBOW ].position; + glm::vec3 newWristPosition = _skeleton.joint[ AVATAR_JOINT_RIGHT_ELBOW ].position + vv * 0.7f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_WRIST ].position = newWristPosition; } @@ -1139,7 +954,7 @@ void Avatar::renderBody(bool lookingInMirror) { // 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 distanceToCamera = glm::length(_cameraPosition - _skeleton.joint[b].position); float alpha = glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f); @@ -1160,26 +975,26 @@ void Avatar::renderBody(bool lookingInMirror) { if (_owningAgent || b == AVATAR_JOINT_RIGHT_ELBOW || b == AVATAR_JOINT_RIGHT_WRIST || b == AVATAR_JOINT_RIGHT_FINGERTIPS ) { - glColor3f(SKIN_COLOR[0] + _joint[b].touchForce * 0.3f, - SKIN_COLOR[1] - _joint[b].touchForce * 0.2f, - SKIN_COLOR[2] - _joint[b].touchForce * 0.1f); + glColor3f(SKIN_COLOR[0] + _skeleton.joint[b].touchForce * 0.3f, + SKIN_COLOR[1] - _skeleton.joint[b].touchForce * 0.2f, + SKIN_COLOR[2] - _skeleton.joint[b].touchForce * 0.1f); } else { - 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, + glColor4f(SKIN_COLOR[0] + _skeleton.joint[b].touchForce * 0.3f, + SKIN_COLOR[1] - _skeleton.joint[b].touchForce * 0.2f, + SKIN_COLOR[2] - _skeleton.joint[b].touchForce * 0.1f, alpha); } 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); + glTranslatef(_skeleton.joint[b].springyPosition.x, _skeleton.joint[b].springyPosition.y, _skeleton.joint[b].springyPosition.z); + glutSolidSphere(_skeleton.joint[b].radius, 20.0f, 20.0f); glPopMatrix(); } // Render the cone connecting this joint to its parent - if (_joint[b].parent != AVATAR_JOINT_NULL) { + if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) { if ((b != AVATAR_JOINT_HEAD_TOP ) && (b != AVATAR_JOINT_HEAD_BASE ) && (b != AVATAR_JOINT_PELVIS ) @@ -1191,15 +1006,15 @@ void Avatar::renderBody(bool lookingInMirror) { && (b != AVATAR_JOINT_RIGHT_SHOULDER)) { glColor3fv(DARK_SKIN_COLOR); - float r1 = _joint[_joint[b].parent ].radius * 0.8; - float r2 = _joint[b ].radius * 0.8; + float r1 = _skeleton.joint[_skeleton.joint[b].parent ].radius * 0.8; + float r2 = _skeleton.joint[b ].radius * 0.8; if (b == AVATAR_JOINT_HEAD_BASE) { r1 *= 0.5f; } renderJointConnectingCone ( - _joint[_joint[b].parent ].springyPosition, - _joint[b ].springyPosition, r2, r2 + _skeleton.joint[_skeleton.joint[b].parent ].springyPosition, + _skeleton.joint[b ].springyPosition, r2, r2 ); } } diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 1ef5675d9b..0518561322 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -67,9 +67,9 @@ public: 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;} + const glm::vec3& getHeadPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].position;} + const glm::vec3& getSpringyHeadPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition;} + const glm::vec3& getJointPosition (AvatarJointID j) const { return _skeleton.joint[j].springyPosition;} const glm::vec3& getBodyUpDirection () const { return _orientation.getUp();} const glm::vec3& getVelocity () const { return _velocity;} float getSpeed () const { return _speed;} @@ -96,6 +96,7 @@ private: Avatar(const Avatar&); Avatar& operator= (const Avatar&); +/* struct AvatarJoint { AvatarJointID parent; // which joint is this joint connected to? @@ -114,6 +115,7 @@ private: 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) }; +*/ Head _head; Skeleton _skeleton; @@ -125,7 +127,7 @@ 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; @@ -153,7 +155,6 @@ private: glm::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat) void renderBody(bool lookingInMirror); void initializeSkeleton(); - void updateSkeleton(); void initializeBodySprings(); void updateBodySprings( float deltaTime ); void calculateBoneLengths(); diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index fa0744bf49..8290e2b418 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -30,7 +30,7 @@ Camera::Camera() { _needsToInitialize = true; _frustumNeedsReshape = true; - _modeShift = 0.0f; + _modeShift = 1.0f; _modeShiftRate = 1.0f; _linearModeShift = 0.0f; _mode = CAMERA_MODE_THIRD_PERSON; diff --git a/interface/src/Skeleton.cpp b/interface/src/Skeleton.cpp index 49e8dea053..37f37516ea 100644 --- a/interface/src/Skeleton.cpp +++ b/interface/src/Skeleton.cpp @@ -6,15 +6,225 @@ #include "Skeleton.h" +const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f; +const float FLOATING_HEIGHT = 0.13f; + +float test = 0.0f; + +/* +float testYaw = 0.0f; +float testPitch = 0.0f; +float testRoll = 0.0f; +*/ + Skeleton::Skeleton() { } void Skeleton::initialize() { + + for (int b=0; b +#include +#include + enum AvatarJointID { AVATAR_JOINT_NULL = -1, @@ -45,10 +49,40 @@ public: Skeleton(); void initialize(); - void simulate(float deltaTime); + void initializeBodySprings(); + void update(float deltaTime, Orientation orientation, glm::vec3 position); void render(); + float getArmLength(); + float getHeight(); + float getPelvisStandingHeight(); + float getPelvisFloatingHeight(); + + 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 + float touchForce; // if being touched, what's the degree of influence? (0 to 1) + }; + + AvatarJoint joint[ NUM_AVATAR_JOINTS ]; + private: -}; + + void calculateBoneLengths(); + + }; #endif From 2a9a3139b21cb475decab7e568af9b03b471c001 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 31 May 2013 14:02:20 -0700 Subject: [PATCH 42/51] Added smooth gravity field so we can fly to planets and land on them, static friction to stop drifting, thrust tweaks. --- interface/src/Avatar.cpp | 30 ++++++++++++++++++++---------- interface/src/Environment.cpp | 26 +++++++++++++++++++------- interface/src/world.h | 2 +- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 3a4162d296..4dd95d6a16 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -25,13 +25,9 @@ using namespace std; const bool BALLS_ON = false; const bool USING_AVATAR_GRAVITY = true; -const float GRAVITY_SCALE = 10.0f; -const float BOUNCE = 0.3f; -const float THRUST_MAG = 1200.0; +const glm::vec3 DEFAULT_UP_DIRECTION (0.0f, 1.0f, 0.0f); const float YAW_MAG = 500.0; const float BODY_SPIN_FRICTION = 5.0; -const float BODY_UPRIGHT_FORCE = 10.0; -const float VELOCITY_DECAY = 5.0; const float MY_HAND_HOLDING_PULL = 0.2; const float YOUR_HAND_HOLDING_PULL = 1.0; const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f; @@ -88,7 +84,7 @@ Avatar::Avatar(Agent* owningAgent) : _pelvisFloatingHeight(0.0f), _distanceToNearestAvatar(std::numeric_limits::max()), _gravity(0.0f, -1.0f, 0.0f), - _worldUpDirection(0.0f, 1.0f, 0.0), + _worldUpDirection(DEFAULT_UP_DIRECTION), _mouseRayOrigin(0.0f, 0.0f, 0.0f), _mouseRayDirection(0.0f, 0.0f, 0.0f), _interactingOther(NULL), @@ -238,8 +234,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // apply gravity and collision with the ground/floor if (!_owningAgent && USING_AVATAR_GRAVITY) { - _velocity += _gravity * (GRAVITY_SCALE * deltaTime); - + _velocity += _gravity * (GRAVITY_EARTH * deltaTime); updateCollisionWithEnvironment(); } @@ -262,6 +257,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { 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) + const float THRUST_MAG = 600.0f; + if (!_owningAgent) { _thrust = glm::vec3(0.0f, 0.0f, 0.0f); @@ -330,7 +327,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta))); - // these forces keep the body upright... + // these forces keep the body upright... + const float BODY_UPRIGHT_FORCE = 10.0; float tiltDecay = BODY_UPRIGHT_FORCE * deltaTime; if (tiltDecay > 1.0f) {tiltDecay = 1.0f;} @@ -344,6 +342,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _position += _velocity * deltaTime; // decay velocity + const float VELOCITY_DECAY = 0.9; float decay = 1.0 - VELOCITY_DECAY * deltaTime; if ( decay < 0.0 ) { _velocity = glm::vec3( 0.0f, 0.0f, 0.0f ); @@ -647,12 +646,21 @@ void Avatar::updateCollisionWithVoxels() { void Avatar::applyCollisionWithScene(const glm::vec3& penetration) { _position -= penetration; - + static float STATIC_FRICTION_VELOCITY = 0.15f; + static float STATIC_FRICTION_DAMPING = 0.0f; + static float KINETIC_FRICTION_DAMPING = 0.95f; + const float BOUNCE = 0.3f; + // reflect the velocity component in the direction of penetration float penetrationLength = glm::length(penetration); if (penetrationLength > EPSILON) { glm::vec3 direction = penetration / penetrationLength; _velocity -= 2.0f * glm::dot(_velocity, direction) * direction * BOUNCE; + _velocity *= KINETIC_FRICTION_DAMPING; + // If velocity is quite low, apply static friction that takes away energy + if (glm::length(_velocity) < STATIC_FRICTION_VELOCITY) { + _velocity *= STATIC_FRICTION_DAMPING; + } } } @@ -755,6 +763,8 @@ void Avatar::setGravity(glm::vec3 gravity) { float gravityLength = glm::length(gravity); if (gravityLength > EPSILON) { _worldUpDirection = _gravity / -gravityLength; + } else { + _worldUpDirection = DEFAULT_UP_DIRECTION; } } diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index f762aaeed1..d087281569 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -58,11 +58,17 @@ void Environment::renderAtmospheres(Camera& camera) { } glm::vec3 Environment::getGravity (const glm::vec3& position) { - // the "original gravity" - glm::vec3 gravity; - if (position.x > 0.0f && position.x < EDGE_SIZE_GROUND_PLANE && position.y > 0.0f && - position.y < 3.0f && position.z > 0.0f && position.z < EDGE_SIZE_GROUND_PLANE) { - gravity = glm::vec3(0.0f, -1.0f, 0.0f); + // + // 'Default' gravity pulls you downward in Y when you are near the X/Z plane + const glm::vec3 DEFAULT_GRAVITY(0.f, -1.f, 0.f); + glm::vec3 gravity(DEFAULT_GRAVITY); + float DEFAULT_SURFACE_RADIUS = 30.f; + float gravityStrength; + + // Weaken gravity with height + if (position.y > 0.f) { + gravityStrength = 1.f / powf((DEFAULT_SURFACE_RADIUS + position.y) / DEFAULT_SURFACE_RADIUS, 2.f); + gravity *= gravityStrength; } // get the lock for the duration of the call @@ -71,12 +77,18 @@ glm::vec3 Environment::getGravity (const glm::vec3& position) { foreach (const ServerData& serverData, _data) { foreach (const EnvironmentData& environmentData, serverData) { glm::vec3 vector = environmentData.getAtmosphereCenter() - position; - const float GRAVITY_RADIUS_MULTIPLIER = 1.5f; - if (glm::length(vector) < environmentData.getAtmosphereOuterRadius() * GRAVITY_RADIUS_MULTIPLIER) { + float surfaceRadius = environmentData.getAtmosphereInnerRadius(); + if (glm::length(vector) <= surfaceRadius) { + // At or inside a planet, gravity is as set for the planet gravity += glm::normalize(vector) * environmentData.getGravity(); + } else { + // Outside a planet, the gravity falls off with distance + gravityStrength = 1.f / powf(glm::length(vector) / surfaceRadius, 2.f); + gravity += glm::normalize(vector) * environmentData.getGravity() * gravityStrength; } } } + return gravity; } diff --git a/interface/src/world.h b/interface/src/world.h index c0c514c26d..950068ca73 100644 --- a/interface/src/world.h +++ b/interface/src/world.h @@ -15,8 +15,8 @@ const float WORLD_SIZE = 10.0; #define PI 3.14159265 #define PIf 3.14159265f -#define GRAVITY_EARTH 9.80665f; +const float GRAVITY_EARTH = 9.80665f; const float EDGE_SIZE_GROUND_PLANE = 20.f; #endif From 3ce051bff7c11232238ee03dc90a92665c8f7022 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 31 May 2013 14:11:46 -0700 Subject: [PATCH 43/51] merge --- interface/src/Application.cpp | 2 +- interface/src/Avatar.cpp | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cb7596c79d..4d3628d5b9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -50,7 +50,7 @@ using namespace std; -const bool TESTING_AVATAR_TOUCH = false; +const bool TESTING_AVATAR_TOUCH = true; // Starfield information static char STAR_FILE[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt"; diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index adab703f96..c22f00f120 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -677,9 +677,10 @@ void Avatar::updateAvatarCollisions(float deltaTime) { for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) { Avatar *otherAvatar = (Avatar *)agent->getLinkedData(); - + // check if the bounding spheres of the two avatars are colliding glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position); + if (glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF) { //apply forces from collision applyCollisionWithOtherAvatar(otherAvatar, deltaTime); @@ -699,8 +700,8 @@ void Avatar::updateAvatarCollisions(float deltaTime) { //detect collisions with other avatars and respond void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime) { - - float bodyMomentum = 1.0f; + + //float bodyMomentum = 1.0f; glm::vec3 bodyPushForce = glm::vec3(0.0f, 0.0f, 0.0f); // loop through the joints of each avatar to check for every possible collision @@ -721,7 +722,6 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime glm::vec3 directionVector = vectorBetweenJoints / distanceBetweenJoints; // push balls away from each other and apply friction - float penetration = 1.0f - (distanceBetweenJoints / (combinedRadius * COLLISION_RADIUS_SCALAR)); glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * penetration * deltaTime; @@ -763,8 +763,10 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime } // collidable //apply forces and frictions on the bodies of both avatars - _velocity += bodyPushForce; -//otherAvatar->_velocity -= bodyPushForce; + +// _velocity += bodyPushForce; + + //otherAvatar->_velocity -= bodyPushForce; // _velocity *= bodyMomentum; //otherAvatar->_velocity *= bodyMomentum; } From f1fc3fe704dd01a7c0243bcf7bf6d9203a75e3fd Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 31 May 2013 14:52:24 -0700 Subject: [PATCH 44/51] merge --- interface/src/Avatar.cpp | 50 ++++++++------------------------------ interface/src/Skeleton.cpp | 4 ++- interface/src/Skeleton.h | 6 +---- 3 files changed, 14 insertions(+), 46 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index c22f00f120..ce742e1236 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -107,6 +107,7 @@ Avatar::Avatar(Agent* owningAgent) : _skeleton.initialize(); + _height = _skeleton.getHeight(); _maxArmLength = _skeleton.getArmLength(); _pelvisStandingHeight = _skeleton.getPelvisStandingHeight(); _pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight(); @@ -485,13 +486,13 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { // reset hand and arm positions according to hand movement glm::vec3 right = orientation * AVATAR_RIGHT; - glm::vec3 up = orientation * AVATAR_UP; + 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.z * 2.0f; + + up * -_movedHandOffset.y * 2.0f + + front * -_movedHandOffset.y * 2.0f; _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement; @@ -677,13 +678,13 @@ void Avatar::updateAvatarCollisions(float deltaTime) { for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) { Avatar *otherAvatar = (Avatar *)agent->getLinkedData(); - + // check if the bounding spheres of the two avatars are colliding glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position); if (glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF) { - //apply forces from collision - applyCollisionWithOtherAvatar(otherAvatar, deltaTime); + //apply forces from collision + applyCollisionWithOtherAvatar(otherAvatar, deltaTime); } // test other avatar hand position for proximity @@ -701,7 +702,6 @@ void Avatar::updateAvatarCollisions(float deltaTime) { //detect collisions with other avatars and respond void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime) { - //float bodyMomentum = 1.0f; glm::vec3 bodyPushForce = glm::vec3(0.0f, 0.0f, 0.0f); // loop through the joints of each avatar to check for every possible collision @@ -727,33 +727,8 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * penetration * deltaTime; bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime; - /* - float ballMomentum = 1.0 - COLLISION_BALL_FRICTION * deltaTime; - if (ballMomentum < 0.0) { ballMomentum = 0.0;} - */ - _skeleton.joint[b].springyVelocity += ballPushForce; otherAvatar->_skeleton.joint[o].springyVelocity -= ballPushForce; - - - /* - float shift = distanceBetweenJoints - combinedRadius * COLLISION_RADIUS_SCALAR; - - _skeleton.joint[b].springyPosition += directionVector * 2.0f * deltaTime; - otherAvatar->_skeleton.joint[o].springyPosition -= directionVector * 2.0f * deltaTime; - */ - - - /* - _skeleton.joint[b].springyVelocity *= ballMomentum; - otherAvatar->_skeleton.joint[o].springyVelocity *= ballMomentum; - */ - - // accumulate forces and frictions to apply to the velocities of avatar bodies - //bodyPushForce += directionVector * COLLISION_BODY_FORCE * deltaTime; - //bodyMomentum -= COLLISION_BODY_FRICTION * deltaTime; - //if (bodyMomentum < 0.0) { bodyMomentum = 0.0;} - }// check for collision } // to avoid divide by zero @@ -762,13 +737,8 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime } // b loop } // collidable - //apply forces and frictions on the bodies of both avatars - -// _velocity += bodyPushForce; - - //otherAvatar->_velocity -= bodyPushForce; - // _velocity *= bodyMomentum; - //otherAvatar->_velocity *= bodyMomentum; + //apply force on the whole body + _velocity += bodyPushForce; } @@ -948,7 +918,7 @@ void Avatar::updateArmIKAndConstraints(float deltaTime) { // set elbow position glm::vec3 newElbowPosition = _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position + armVector * ONE_HALF; - glm::vec3 perpendicular = glm::cross(getBodyFrontDirection(), armVector); + glm::vec3 perpendicular = glm::cross(getBodyRightDirection(), armVector); newElbowPosition += perpendicular * (1.0f - (_maxArmLength / distance)) * ONE_HALF; _skeleton.joint[ AVATAR_JOINT_RIGHT_ELBOW ].position = newElbowPosition; diff --git a/interface/src/Skeleton.cpp b/interface/src/Skeleton.cpp index a328ffb4c5..78c40986af 100644 --- a/interface/src/Skeleton.cpp +++ b/interface/src/Skeleton.cpp @@ -112,11 +112,13 @@ void Skeleton::initialize() { 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; joint[ AVATAR_JOINT_RIGHT_WRIST ].isCollidable = false; joint[ AVATAR_JOINT_RIGHT_FINGERTIPS].isCollidable = false; - + */ + // calculate bone length calculateBoneLengths(); diff --git a/interface/src/Skeleton.h b/interface/src/Skeleton.h index 362cab6080..69d2fe0d2b 100644 --- a/interface/src/Skeleton.h +++ b/interface/src/Skeleton.h @@ -65,11 +65,7 @@ public: 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 + glm::quat rotation; // the parent-relative rotation (orientation) of the joint as a quaternion 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 From 303643e921face2fcafa9cf5187998626dd501a7 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 31 May 2013 15:01:08 -0700 Subject: [PATCH 45/51] cleanup --- interface/src/Avatar.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 5af0874f5a..080d9e31ca 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -33,13 +33,9 @@ const float YOUR_HAND_HOLDING_PULL = 1.0; const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f; const float BODY_SPRING_FORCE = 300.0f; const float BODY_SPRING_DECAY = 16.0f; - const float COLLISION_RADIUS_SCALAR = 1.2; //pertains to avatar-to-avatar collisions const float COLLISION_BALL_FORCE = 200.0; //pertains to avatar-to-avatar collisions const float COLLISION_BODY_FORCE = 30.0; //pertains to avatar-to-avatar collisions -const float COLLISION_BALL_FRICTION = 60.0; //pertains to avatar-to-avatar collisions -const float COLLISION_BODY_FRICTION = 0.5; //pertains to avatar-to-avatar collisions - const float HEAD_ROTATION_SCALE = 0.70; const float HEAD_ROLL_SCALE = 0.40; const float HEAD_MAX_PITCH = 45; From 1061b3eb4dccdd25fa7c367e42e60c2ab3cc64b6 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 31 May 2013 15:05:05 -0700 Subject: [PATCH 46/51] cleanup --- interface/src/Application.cpp | 39 ++++++++++++++--------------------- 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4d3628d5b9..fe84ec4748 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -50,8 +50,6 @@ using namespace std; -const bool TESTING_AVATAR_TOUCH = true; - // Starfield information static char STAR_FILE[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt"; static char STAR_CACHE_FILE[] = "cachedStars.txt"; @@ -1080,31 +1078,24 @@ void Application::idle() { _myAvatar.simulate(deltaTime, NULL); } - if ( TESTING_AVATAR_TOUCH) { - if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { - _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); - _myCamera.setModeShiftRate(1.0f); - } - } else { - if (_myCamera.getMode() != CAMERA_MODE_MIRROR && !OculusManager::isConnected()) { - if (_manualFirstPerson) { - if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) { + if (_myCamera.getMode() != CAMERA_MODE_MIRROR && !OculusManager::isConnected()) { + if (_manualFirstPerson) { + if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) { + _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + _myCamera.setModeShiftRate(1.0f); + } + } else { + + if (_myAvatar.getIsNearInteractingOther()) { + if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); _myCamera.setModeShiftRate(1.0f); } - } else { - - if (_myAvatar.getIsNearInteractingOther()) { - if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { - _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); - _myCamera.setModeShiftRate(1.0f); - } - } - else { - if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { - _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); - _myCamera.setModeShiftRate(1.0f); - } + } + else { + if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { + _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); + _myCamera.setModeShiftRate(1.0f); } } } From 4f49f1769e5f2c70c734513ad4de1c9b6fcea112 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 31 May 2013 16:54:56 -0700 Subject: [PATCH 47/51] separated springy balls from skeleton --- interface/src/Avatar.cpp | 176 ++++++++++++++++++++++++------------- interface/src/Avatar.h | 30 +++---- interface/src/Skeleton.cpp | 79 ++--------------- interface/src/Skeleton.h | 16 +--- 4 files changed, 136 insertions(+), 165 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 080d9e31ca..61974dd9b1 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -98,12 +98,14 @@ Avatar::Avatar(Agent* owningAgent) : } _skeleton.initialize(); - - _height = _skeleton.getHeight(); - _maxArmLength = _skeleton.getArmLength(); - _pelvisStandingHeight = _skeleton.getPelvisStandingHeight(); - _pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight(); + initializeBalls(); + + _height = _skeleton.getHeight() + _ball[ AVATAR_JOINT_LEFT_HEEL ].radius + _ball[ AVATAR_JOINT_HEAD_BASE ].radius; + _maxArmLength = _skeleton.getArmLength(); + _pelvisStandingHeight = _skeleton.getPelvisStandingHeight() + _ball[ AVATAR_JOINT_LEFT_HEEL ].radius; + _pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight() + _ball[ AVATAR_JOINT_LEFT_HEEL ].radius; + _avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS); if (BALLS_ON) { @@ -113,6 +115,56 @@ Avatar::Avatar(Agent* owningAgent) : } } + +void Avatar::initializeBalls() { + + for (int b=0; b (1.0f - range)) { - _skeleton.joint[b].touchForce = (dot - (1.0f - range)) / range; + _ball[b].touchForce = (dot - (1.0f - range)) / range; } else { - _skeleton.joint[b].touchForce = 0.0; + _ball[b].touchForce = 0.0; } } } @@ -527,7 +579,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { _avatarTouch.setHasInteractingOther(true); _avatarTouch.setYourBodyPosition(_interactingOther->_position); - _avatarTouch.setYourHandPosition(_interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); + _avatarTouch.setYourHandPosition(_interactingOther->_ball[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); _avatarTouch.setYourOrientation (_interactingOther->getOrientation()); _avatarTouch.setYourHandState (_interactingOther->_handState); @@ -598,7 +650,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { } _avatarTouch.setMyHandState(_handState); - _avatarTouch.setMyHandPosition(_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); + _avatarTouch.setMyHandPosition(_ball[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); } } @@ -610,9 +662,9 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere); if (distanceToBigSphere < myBodyApproximateBoundingRadius + radius) { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 vectorFromJointToBigSphereCenter(_skeleton.joint[b].springyPosition - position); + glm::vec3 vectorFromJointToBigSphereCenter(_ball[b].position - position); float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter); - float combinedRadius = _skeleton.joint[b].radius + radius; + float combinedRadius = _ball[b].radius + radius; if (distanceToBigSphereCenter < combinedRadius) { jointCollision = true; @@ -622,9 +674,9 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius); glm::vec3 collisionForce = vectorFromJointToBigSphereCenter * penetration; - _skeleton.joint[b].springyVelocity += collisionForce * 0.0f * deltaTime; + _ball[b].velocity += collisionForce * 0.0f * deltaTime; _velocity += collisionForce * 40.0f * deltaTime; - _skeleton.joint[b].springyPosition = position + directionVector * combinedRadius; + _ball[b].position = position + directionVector * combinedRadius; } } } @@ -710,16 +762,16 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime // loop through the joints of each avatar to check for every possible collision for (int b=1; b_skeleton.joint[o].isCollidable) { + if (otherAvatar->_ball[o].isCollidable) { - glm::vec3 vectorBetweenJoints(_skeleton.joint[b].springyPosition - otherAvatar->_skeleton.joint[o].springyPosition); + glm::vec3 vectorBetweenJoints(_ball[b].position - otherAvatar->_ball[o].position); float distanceBetweenJoints = glm::length(vectorBetweenJoints); if (distanceBetweenJoints > 0.0) { // to avoid divide by zero - float combinedRadius = _skeleton.joint[b].radius + otherAvatar->_skeleton.joint[o].radius; + float combinedRadius = _ball[b].radius + otherAvatar->_ball[o].radius; // check for collision if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) { @@ -731,8 +783,8 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * penetration * deltaTime; bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime; - _skeleton.joint[b].springyVelocity += ballPushForce; - otherAvatar->_skeleton.joint[o].springyVelocity -= ballPushForce; + _ball[b].velocity += ballPushForce; + otherAvatar->_ball[o].velocity -= ballPushForce; }// check for collision } // to avoid divide by zero @@ -805,7 +857,7 @@ void Avatar::render(bool lookingInMirror) { } glPushMatrix(); - glm::vec3 chatPosition = _skeleton.joint[AVATAR_JOINT_HEAD_BASE].springyPosition + getBodyUpDirection() * chatMessageHeight; + glm::vec3 chatPosition = _ball[AVATAR_JOINT_HEAD_BASE].position + getBodyUpDirection() * chatMessageHeight; glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z); glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation(); glm::vec3 chatAxis = glm::axis(chatRotation); @@ -842,25 +894,25 @@ void Avatar::render(bool lookingInMirror) { void Avatar::initializeBodySprings() { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - _skeleton.joint[b].springyPosition = _skeleton.joint[b].position; - _skeleton.joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + _ball[b].position = _skeleton.joint[b].position; + _ball[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f); } } void Avatar::updateBodySprings(float deltaTime) { // Check for a large repositioning, and re-initialize body springs if this has happened const float BEYOND_BODY_SPRING_RANGE = 2.f; - if (glm::length(_position - _skeleton.joint[AVATAR_JOINT_PELVIS].springyPosition) > BEYOND_BODY_SPRING_RANGE) { - _skeleton.initializeBodySprings(); + if (glm::length(_position - _ball[AVATAR_JOINT_PELVIS].position) > BEYOND_BODY_SPRING_RANGE) { + initializeBodySprings(); } for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 springVector(_skeleton.joint[b].springyPosition); + glm::vec3 springVector(_ball[b].position); if (_skeleton.joint[b].parent == AVATAR_JOINT_NULL) { springVector -= _position; } else { - springVector -= _skeleton.joint[ _skeleton.joint[b].parent ].springyPosition; + springVector -= _ball[ _skeleton.joint[b].parent ].position; } float length = glm::length(springVector); @@ -869,23 +921,23 @@ void Avatar::updateBodySprings(float deltaTime) { glm::vec3 springDirection = springVector / length; float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime; - _skeleton.joint[b].springyVelocity -= springDirection * force; + _ball[b].velocity -= springDirection * force; if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) { - _skeleton.joint[_skeleton.joint[b].parent].springyVelocity += springDirection * force; + _ball[_skeleton.joint[b].parent].velocity += springDirection * force; } } // apply tightness force - (causing springy position to be close to rigid body position) - _skeleton.joint[b].springyVelocity += (_skeleton.joint[b].position - _skeleton.joint[b].springyPosition) * _skeleton.joint[b].springBodyTightness * deltaTime; + _ball[b].velocity += (_skeleton.joint[b].position - _ball[b].position) * _ball[b].jointTightness * deltaTime; // apply decay float decay = 1.0 - BODY_SPRING_DECAY * deltaTime; if (decay > 0.0) { - _skeleton.joint[b].springyVelocity *= decay; + _ball[b].velocity *= decay; } else { - _skeleton.joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + _ball[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f); } /* @@ -896,7 +948,7 @@ void Avatar::updateBodySprings(float deltaTime) { */ //update position by velocity... - _skeleton.joint[b].springyPosition += _skeleton.joint[b].springyVelocity * deltaTime; + _ball[b].position += _ball[b].velocity * deltaTime; } } @@ -981,21 +1033,21 @@ void Avatar::renderBody(bool lookingInMirror) { if (_owningAgent || b == AVATAR_JOINT_RIGHT_ELBOW || b == AVATAR_JOINT_RIGHT_WRIST || b == AVATAR_JOINT_RIGHT_FINGERTIPS ) { - glColor3f(SKIN_COLOR[0] + _skeleton.joint[b].touchForce * 0.3f, - SKIN_COLOR[1] - _skeleton.joint[b].touchForce * 0.2f, - SKIN_COLOR[2] - _skeleton.joint[b].touchForce * 0.1f); + glColor3f(SKIN_COLOR[0] + _ball[b].touchForce * 0.3f, + SKIN_COLOR[1] - _ball[b].touchForce * 0.2f, + SKIN_COLOR[2] - _ball[b].touchForce * 0.1f); } else { - glColor4f(SKIN_COLOR[0] + _skeleton.joint[b].touchForce * 0.3f, - SKIN_COLOR[1] - _skeleton.joint[b].touchForce * 0.2f, - SKIN_COLOR[2] - _skeleton.joint[b].touchForce * 0.1f, + glColor4f(SKIN_COLOR[0] + _ball[b].touchForce * 0.3f, + SKIN_COLOR[1] - _ball[b].touchForce * 0.2f, + SKIN_COLOR[2] - _ball[b].touchForce * 0.1f, alpha); } if ((b != AVATAR_JOINT_HEAD_TOP ) && (b != AVATAR_JOINT_HEAD_BASE )) { glPushMatrix(); - glTranslatef(_skeleton.joint[b].springyPosition.x, _skeleton.joint[b].springyPosition.y, _skeleton.joint[b].springyPosition.z); - glutSolidSphere(_skeleton.joint[b].radius, 20.0f, 20.0f); + glTranslatef(_ball[b].position.x, _ball[b].position.y, _ball[b].position.z); + glutSolidSphere(_ball[b].radius, 20.0f, 20.0f); glPopMatrix(); } @@ -1012,15 +1064,15 @@ void Avatar::renderBody(bool lookingInMirror) { && (b != AVATAR_JOINT_RIGHT_SHOULDER)) { glColor3fv(DARK_SKIN_COLOR); - float r1 = _skeleton.joint[_skeleton.joint[b].parent ].radius * 0.8; - float r2 = _skeleton.joint[b ].radius * 0.8; + float r1 = _ball[_skeleton.joint[b].parent ].radius * 0.8; + float r2 = _ball[b ].radius * 0.8; if (b == AVATAR_JOINT_HEAD_BASE) { r1 *= 0.5f; } renderJointConnectingCone ( - _skeleton.joint[_skeleton.joint[b].parent ].springyPosition, - _skeleton.joint[b ].springyPosition, r2, r2 + _ball[_skeleton.joint[b].parent ].position, + _ball[b ].position, r2, r2 ); } } diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 5cc7d66f8b..462cb1bb12 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -69,8 +69,8 @@ public: float getBodyYaw () const { return _bodyYaw;} bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();} const glm::vec3& getHeadPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].position;} - const glm::vec3& getSpringyHeadPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition;} - const glm::vec3& getJointPosition (AvatarJointID j) const { return _skeleton.joint[j].springyPosition;} + const glm::vec3& getSpringyHeadPosition () const { return _ball[ AVATAR_JOINT_HEAD_BASE ].position;} + const glm::vec3& getJointPosition (AvatarJointID j) const { return _ball[j].position;} glm::vec3 getBodyRightDirection () const { return getOrientation() * AVATAR_RIGHT; } glm::vec3 getBodyUpDirection () const { return getOrientation() * AVATAR_UP; } @@ -104,22 +104,15 @@ private: Avatar(const Avatar&); Avatar& operator= (const Avatar&); -/* - struct AvatarJoint + struct AvatarBall { - 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 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) + glm::vec3 position; + glm::vec3 velocity; + float jointTightness; + float radius; + bool isCollidable; + float touchForce; }; -*/ Head _head; Skeleton _skeleton; @@ -131,7 +124,7 @@ 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 ]; + AvatarBall _ball[ NUM_AVATAR_JOINTS ]; AvatarMode _mode; glm::vec3 _cameraPosition; glm::vec3 _handHoldingPosition; @@ -159,7 +152,8 @@ private: 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 initializeSkeleton(); + void initializeBalls(); void initializeBodySprings(); void updateBodySprings( float deltaTime ); void calculateBoneLengths(); diff --git a/interface/src/Skeleton.cpp b/interface/src/Skeleton.cpp index 78c40986af..97dded3254 100644 --- a/interface/src/Skeleton.cpp +++ b/interface/src/Skeleton.cpp @@ -15,17 +15,11 @@ Skeleton::Skeleton() { void Skeleton::initialize() { for (int b=0; b Date: Fri, 31 May 2013 16:58:58 -0700 Subject: [PATCH 48/51] cleanup --- interface/src/Avatar.cpp | 4 ++-- interface/src/Avatar.h | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 61974dd9b1..acf71db0b1 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -892,7 +892,7 @@ void Avatar::render(bool lookingInMirror) { } } -void Avatar::initializeBodySprings() { +void Avatar::resetBodySprings() { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { _ball[b].position = _skeleton.joint[b].position; _ball[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f); @@ -903,7 +903,7 @@ void Avatar::updateBodySprings(float deltaTime) { // Check for a large repositioning, and re-initialize body springs if this has happened const float BEYOND_BODY_SPRING_RANGE = 2.f; if (glm::length(_position - _ball[AVATAR_JOINT_PELVIS].position) > BEYOND_BODY_SPRING_RANGE) { - initializeBodySprings(); + resetBodySprings(); } for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { glm::vec3 springVector(_ball[b].position); diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 462cb1bb12..b775de15e7 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -152,9 +152,8 @@ private: 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 initializeBalls(); - void initializeBodySprings(); + void resetBodySprings(); void updateBodySprings( float deltaTime ); void calculateBoneLengths(); void readSensors(); From d98b28d4abdabe00b2b67fdd1023d258082dd868 Mon Sep 17 00:00:00 2001 From: Geenz Date: Fri, 31 May 2013 20:30:42 -0400 Subject: [PATCH 49/51] So apparently, this was a scale problem the entire time. --- interface/resources/shaders/SkyFromAtmosphere.frag | 2 +- interface/resources/shaders/SkyFromSpace.frag | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/shaders/SkyFromAtmosphere.frag b/interface/resources/shaders/SkyFromAtmosphere.frag index c7fedd4e4a..4f3bbff9b0 100644 --- a/interface/resources/shaders/SkyFromAtmosphere.frag +++ b/interface/resources/shaders/SkyFromAtmosphere.frag @@ -87,7 +87,7 @@ void main (void) float fHeight = length(v3SamplePoint); float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight)); float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight; - float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; + float fCameraAngle = dot(normalize(v3Ray), v3SamplePoint) / fHeight * 0.99; float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle))); vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI)); v3FrontColor += v3Attenuate * (fDepth * fScaledLength); diff --git a/interface/resources/shaders/SkyFromSpace.frag b/interface/resources/shaders/SkyFromSpace.frag index 2dcbc9d6fb..d4e1c58da5 100644 --- a/interface/resources/shaders/SkyFromSpace.frag +++ b/interface/resources/shaders/SkyFromSpace.frag @@ -97,7 +97,7 @@ void main (void) float fHeight = length(v3SamplePoint); float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight)); float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight; - float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; + float fCameraAngle = dot(normalize(v3Ray), v3SamplePoint) / fHeight * 0.99; float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle))); vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI)); v3FrontColor += v3Attenuate * (fDepth * fScaledLength); From de49d7fc6c63b33d81a7038807e66b92332cfd89 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 31 May 2013 17:32:30 -0700 Subject: [PATCH 50/51] more fixes --- interface/src/Avatar.cpp | 202 +++++++++++++++++----------------- interface/src/Avatar.h | 12 +- interface/src/AvatarTouch.cpp | 10 +- interface/src/Skeleton.cpp | 5 +- 4 files changed, 115 insertions(+), 114 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index acf71db0b1..46a4d302ca 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -99,12 +99,12 @@ Avatar::Avatar(Agent* owningAgent) : _skeleton.initialize(); - initializeBalls(); + initializeBodyBalls(); - _height = _skeleton.getHeight() + _ball[ AVATAR_JOINT_LEFT_HEEL ].radius + _ball[ AVATAR_JOINT_HEAD_BASE ].radius; + _height = _skeleton.getHeight() + _bodyBall[ AVATAR_JOINT_LEFT_HEEL ].radius + _bodyBall[ AVATAR_JOINT_HEAD_BASE ].radius; _maxArmLength = _skeleton.getArmLength(); - _pelvisStandingHeight = _skeleton.getPelvisStandingHeight() + _ball[ AVATAR_JOINT_LEFT_HEEL ].radius; - _pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight() + _ball[ AVATAR_JOINT_LEFT_HEEL ].radius; + _pelvisStandingHeight = _skeleton.getPelvisStandingHeight() + _bodyBall[ AVATAR_JOINT_LEFT_HEEL ].radius; + _pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight() + _bodyBall[ AVATAR_JOINT_LEFT_HEEL ].radius; _avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS); @@ -116,51 +116,51 @@ Avatar::Avatar(Agent* owningAgent) : } -void Avatar::initializeBalls() { +void Avatar::initializeBodyBalls() { for (int b=0; b 0.0f) { glm::vec3 headLean = right * _head.getLeanSideways() + front * _head.getLeanForward(); - _ball[ AVATAR_JOINT_TORSO ].position += headLean * 0.1f; - _ball[ AVATAR_JOINT_CHEST ].position += headLean * 0.4f; - _ball[ AVATAR_JOINT_NECK_BASE ].position += headLean * 0.7f; - _ball[ AVATAR_JOINT_HEAD_BASE ].position += headLean * 1.0f; + _bodyBall[ AVATAR_JOINT_TORSO ].position += headLean * 0.1f; + _bodyBall[ AVATAR_JOINT_CHEST ].position += headLean * 0.4f; + _bodyBall[ AVATAR_JOINT_NECK_BASE ].position += headLean * 0.7f; + _bodyBall[ AVATAR_JOINT_HEAD_BASE ].position += headLean * 1.0f; - _ball[ AVATAR_JOINT_LEFT_COLLAR ].position += headLean * 0.6f; - _ball[ AVATAR_JOINT_LEFT_SHOULDER ].position += headLean * 0.6f; - _ball[ AVATAR_JOINT_LEFT_ELBOW ].position += headLean * 0.2f; - _ball[ AVATAR_JOINT_LEFT_WRIST ].position += headLean * 0.1f; - _ball[ AVATAR_JOINT_LEFT_FINGERTIPS ].position += headLean * 0.0f; + _bodyBall[ AVATAR_JOINT_LEFT_COLLAR ].position += headLean * 0.6f; + _bodyBall[ AVATAR_JOINT_LEFT_SHOULDER ].position += headLean * 0.6f; + _bodyBall[ AVATAR_JOINT_LEFT_ELBOW ].position += headLean * 0.2f; + _bodyBall[ AVATAR_JOINT_LEFT_WRIST ].position += headLean * 0.1f; + _bodyBall[ AVATAR_JOINT_LEFT_FINGERTIPS ].position += headLean * 0.0f; - _ball[ AVATAR_JOINT_RIGHT_COLLAR ].position += headLean * 0.6f; - _ball[ AVATAR_JOINT_RIGHT_SHOULDER ].position += headLean * 0.6f; - _ball[ AVATAR_JOINT_RIGHT_ELBOW ].position += headLean * 0.2f; - _ball[ AVATAR_JOINT_RIGHT_WRIST ].position += headLean * 0.1f; - _ball[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += headLean * 0.0f; + _bodyBall[ AVATAR_JOINT_RIGHT_COLLAR ].position += headLean * 0.6f; + _bodyBall[ AVATAR_JOINT_RIGHT_SHOULDER ].position += headLean * 0.6f; + _bodyBall[ AVATAR_JOINT_RIGHT_ELBOW ].position += headLean * 0.2f; + _bodyBall[ AVATAR_JOINT_RIGHT_WRIST ].position += headLean * 0.1f; + _bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += headLean * 0.0f; } } @@ -485,8 +485,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } _head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); - _head.setPosition(_ball[ AVATAR_JOINT_HEAD_BASE ].position); - _head.setScale (_ball[ AVATAR_JOINT_HEAD_BASE ].radius); + _head.setPosition(_bodyBall[ AVATAR_JOINT_HEAD_BASE ].position); + _head.setScale (_bodyBall[ AVATAR_JOINT_HEAD_BASE ].radius); _head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2])); _head.simulate(deltaTime, !_owningAgent); @@ -502,15 +502,15 @@ void Avatar::checkForMouseRayTouching() { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 directionToBodySphere = glm::normalize(_ball[b].position - _mouseRayOrigin); + glm::vec3 directionToBodySphere = glm::normalize(_bodyBall[b].position - _mouseRayOrigin); float dot = glm::dot(directionToBodySphere, _mouseRayDirection); - float range = _ball[b].radius * JOINT_TOUCH_RANGE; + float range = _bodyBall[b].radius * JOINT_TOUCH_RANGE; if (dot > (1.0f - range)) { - _ball[b].touchForce = (dot - (1.0f - range)) / range; + _bodyBall[b].touchForce = (dot - (1.0f - range)) / range; } else { - _ball[b].touchForce = 0.0; + _bodyBall[b].touchForce = 0.0; } } } @@ -579,7 +579,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { _avatarTouch.setHasInteractingOther(true); _avatarTouch.setYourBodyPosition(_interactingOther->_position); - _avatarTouch.setYourHandPosition(_interactingOther->_ball[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); + _avatarTouch.setYourHandPosition(_interactingOther->_bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); _avatarTouch.setYourOrientation (_interactingOther->getOrientation()); _avatarTouch.setYourHandState (_interactingOther->_handState); @@ -650,7 +650,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { } _avatarTouch.setMyHandState(_handState); - _avatarTouch.setMyHandPosition(_ball[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); + _avatarTouch.setMyHandPosition(_bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); } } @@ -662,9 +662,9 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere); if (distanceToBigSphere < myBodyApproximateBoundingRadius + radius) { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 vectorFromJointToBigSphereCenter(_ball[b].position - position); + glm::vec3 vectorFromJointToBigSphereCenter(_bodyBall[b].position - position); float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter); - float combinedRadius = _ball[b].radius + radius; + float combinedRadius = _bodyBall[b].radius + radius; if (distanceToBigSphereCenter < combinedRadius) { jointCollision = true; @@ -674,9 +674,9 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius); glm::vec3 collisionForce = vectorFromJointToBigSphereCenter * penetration; - _ball[b].velocity += collisionForce * 0.0f * deltaTime; + _bodyBall[b].velocity += collisionForce * 0.0f * deltaTime; _velocity += collisionForce * 40.0f * deltaTime; - _ball[b].position = position + directionVector * combinedRadius; + _bodyBall[b].position = position + directionVector * combinedRadius; } } } @@ -762,16 +762,16 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime // loop through the joints of each avatar to check for every possible collision for (int b=1; b_ball[o].isCollidable) { + if (otherAvatar->_bodyBall[o].isCollidable) { - glm::vec3 vectorBetweenJoints(_ball[b].position - otherAvatar->_ball[o].position); + glm::vec3 vectorBetweenJoints(_bodyBall[b].position - otherAvatar->_bodyBall[o].position); float distanceBetweenJoints = glm::length(vectorBetweenJoints); if (distanceBetweenJoints > 0.0) { // to avoid divide by zero - float combinedRadius = _ball[b].radius + otherAvatar->_ball[o].radius; + float combinedRadius = _bodyBall[b].radius + otherAvatar->_bodyBall[o].radius; // check for collision if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) { @@ -783,8 +783,8 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * penetration * deltaTime; bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime; - _ball[b].velocity += ballPushForce; - otherAvatar->_ball[o].velocity -= ballPushForce; + _bodyBall[b].velocity += ballPushForce; + otherAvatar->_bodyBall[o].velocity -= ballPushForce; }// check for collision } // to avoid divide by zero @@ -857,7 +857,7 @@ void Avatar::render(bool lookingInMirror) { } glPushMatrix(); - glm::vec3 chatPosition = _ball[AVATAR_JOINT_HEAD_BASE].position + getBodyUpDirection() * chatMessageHeight; + glm::vec3 chatPosition = _bodyBall[AVATAR_JOINT_HEAD_BASE].position + getBodyUpDirection() * chatMessageHeight; glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z); glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation(); glm::vec3 chatAxis = glm::axis(chatRotation); @@ -892,27 +892,27 @@ void Avatar::render(bool lookingInMirror) { } } -void Avatar::resetBodySprings() { +void Avatar::resetBodyBalls() { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - _ball[b].position = _skeleton.joint[b].position; - _ball[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f); + _bodyBall[b].position = _skeleton.joint[b].position; + _bodyBall[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f); } } -void Avatar::updateBodySprings(float deltaTime) { - // Check for a large repositioning, and re-initialize body springs if this has happened +void Avatar::updateBodyBalls(float deltaTime) { + // Check for a large repositioning, and re-initialize balls if this has happened const float BEYOND_BODY_SPRING_RANGE = 2.f; - if (glm::length(_position - _ball[AVATAR_JOINT_PELVIS].position) > BEYOND_BODY_SPRING_RANGE) { - resetBodySprings(); + if (glm::length(_position - _bodyBall[AVATAR_JOINT_PELVIS].position) > BEYOND_BODY_SPRING_RANGE) { + resetBodyBalls(); } for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 springVector(_ball[b].position); + glm::vec3 springVector(_bodyBall[b].position); if (_skeleton.joint[b].parent == AVATAR_JOINT_NULL) { springVector -= _position; } else { - springVector -= _ball[ _skeleton.joint[b].parent ].position; + springVector -= _bodyBall[ _skeleton.joint[b].parent ].position; } float length = glm::length(springVector); @@ -921,23 +921,23 @@ void Avatar::updateBodySprings(float deltaTime) { glm::vec3 springDirection = springVector / length; float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime; - _ball[b].velocity -= springDirection * force; + _bodyBall[b].velocity -= springDirection * force; if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) { - _ball[_skeleton.joint[b].parent].velocity += springDirection * force; + _bodyBall[_skeleton.joint[b].parent].velocity += springDirection * force; } } - // apply tightness force - (causing springy position to be close to rigid body position) - _ball[b].velocity += (_skeleton.joint[b].position - _ball[b].position) * _ball[b].jointTightness * deltaTime; + // apply tightness force - (causing ball position to be close to skeleton joint position) + _bodyBall[b].velocity += (_skeleton.joint[b].position - _bodyBall[b].position) * _bodyBall[b].jointTightness * deltaTime; // apply decay float decay = 1.0 - BODY_SPRING_DECAY * deltaTime; if (decay > 0.0) { - _ball[b].velocity *= decay; + _bodyBall[b].velocity *= decay; } else { - _ball[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f); + _bodyBall[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f); } /* @@ -948,7 +948,7 @@ void Avatar::updateBodySprings(float deltaTime) { */ //update position by velocity... - _ball[b].position += _ball[b].velocity * deltaTime; + _bodyBall[b].position += _bodyBall[b].velocity * deltaTime; } } @@ -1033,21 +1033,21 @@ void Avatar::renderBody(bool lookingInMirror) { if (_owningAgent || b == AVATAR_JOINT_RIGHT_ELBOW || b == AVATAR_JOINT_RIGHT_WRIST || b == AVATAR_JOINT_RIGHT_FINGERTIPS ) { - glColor3f(SKIN_COLOR[0] + _ball[b].touchForce * 0.3f, - SKIN_COLOR[1] - _ball[b].touchForce * 0.2f, - SKIN_COLOR[2] - _ball[b].touchForce * 0.1f); + glColor3f(SKIN_COLOR[0] + _bodyBall[b].touchForce * 0.3f, + SKIN_COLOR[1] - _bodyBall[b].touchForce * 0.2f, + SKIN_COLOR[2] - _bodyBall[b].touchForce * 0.1f); } else { - glColor4f(SKIN_COLOR[0] + _ball[b].touchForce * 0.3f, - SKIN_COLOR[1] - _ball[b].touchForce * 0.2f, - SKIN_COLOR[2] - _ball[b].touchForce * 0.1f, + glColor4f(SKIN_COLOR[0] + _bodyBall[b].touchForce * 0.3f, + SKIN_COLOR[1] - _bodyBall[b].touchForce * 0.2f, + SKIN_COLOR[2] - _bodyBall[b].touchForce * 0.1f, alpha); } if ((b != AVATAR_JOINT_HEAD_TOP ) && (b != AVATAR_JOINT_HEAD_BASE )) { glPushMatrix(); - glTranslatef(_ball[b].position.x, _ball[b].position.y, _ball[b].position.z); - glutSolidSphere(_ball[b].radius, 20.0f, 20.0f); + glTranslatef(_bodyBall[b].position.x, _bodyBall[b].position.y, _bodyBall[b].position.z); + glutSolidSphere(_bodyBall[b].radius, 20.0f, 20.0f); glPopMatrix(); } @@ -1064,15 +1064,15 @@ void Avatar::renderBody(bool lookingInMirror) { && (b != AVATAR_JOINT_RIGHT_SHOULDER)) { glColor3fv(DARK_SKIN_COLOR); - float r1 = _ball[_skeleton.joint[b].parent ].radius * 0.8; - float r2 = _ball[b ].radius * 0.8; + float r1 = _bodyBall[_skeleton.joint[b].parent ].radius * 0.8; + float r2 = _bodyBall[b ].radius * 0.8; if (b == AVATAR_JOINT_HEAD_BASE) { r1 *= 0.5f; } renderJointConnectingCone ( - _ball[_skeleton.joint[b].parent ].position, - _ball[b ].position, r2, r2 + _bodyBall[_skeleton.joint[b].parent ].position, + _bodyBall[b ].position, r2, r2 ); } } diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index b775de15e7..6746ba51cd 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -69,8 +69,8 @@ public: float getBodyYaw () const { return _bodyYaw;} bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();} const glm::vec3& getHeadPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].position;} - const glm::vec3& getSpringyHeadPosition () const { return _ball[ AVATAR_JOINT_HEAD_BASE ].position;} - const glm::vec3& getJointPosition (AvatarJointID j) const { return _ball[j].position;} + const glm::vec3& getSpringyHeadPosition () const { return _bodyBall[ AVATAR_JOINT_HEAD_BASE ].position;} + const glm::vec3& getJointPosition (AvatarJointID j) const { return _bodyBall[j].position;} glm::vec3 getBodyRightDirection () const { return getOrientation() * AVATAR_RIGHT; } glm::vec3 getBodyUpDirection () const { return getOrientation() * AVATAR_UP; } @@ -124,7 +124,7 @@ private: float _bodyRollDelta; glm::vec3 _movedHandOffset; glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion - AvatarBall _ball[ NUM_AVATAR_JOINTS ]; + AvatarBall _bodyBall[ NUM_AVATAR_JOINTS ]; AvatarMode _mode; glm::vec3 _cameraPosition; glm::vec3 _handHoldingPosition; @@ -152,9 +152,9 @@ private: 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 initializeBalls(); - void resetBodySprings(); - void updateBodySprings( float deltaTime ); + void initializeBodyBalls(); + void resetBodyBalls(); + void updateBodyBalls( float deltaTime ); void calculateBoneLengths(); void readSensors(); void updateHandMovementAndTouching(float deltaTime); diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 6f7456dd09..1e06663b01 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -43,6 +43,10 @@ void AvatarTouch::simulate (float deltaTime) { glm::vec3 vectorBetweenBodies = _yourBodyPosition - _myBodyPosition; float distanceBetweenBodies = glm::length(vectorBetweenBodies); + + //KEEP THIS - it is another variation that we are considering getting rid of + //the following code take into account of the two avatars are facing each other + /* glm::vec3 directionBetweenBodies = vectorBetweenBodies / distanceBetweenBodies; bool facingEachOther = false; @@ -50,13 +54,13 @@ void AvatarTouch::simulate (float deltaTime) { 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 + 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; } + */ if (distanceBetweenBodies < _reachableRadius) - //&& (facingEachOther)) { _canReachToOtherAvatar = true; diff --git a/interface/src/Skeleton.cpp b/interface/src/Skeleton.cpp index 97dded3254..64a8645247 100644 --- a/interface/src/Skeleton.cpp +++ b/interface/src/Skeleton.cpp @@ -83,10 +83,9 @@ void Skeleton::initialize() { } } - +// calculate positions and rotations of all bones by traversing the skeleton tree: void Skeleton::update(float deltaTime, const glm::quat& orientation, glm::vec3 position) { - // calculate positions of all bones by traversing the skeleton tree: for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { if (joint[b].parent == AVATAR_JOINT_NULL) { joint[b].rotation = orientation; @@ -97,9 +96,7 @@ void Skeleton::update(float deltaTime, const glm::quat& orientation, glm::vec3 p joint[b].position = joint[ joint[b].parent ].position; } - // the following will be replaced by a proper rotation...close glm::vec3 rotatedJointVector = joint[b].rotation * joint[b].defaultPosePosition; - joint[b].position += rotatedJointVector; } } From de76851207d07486b47919dd6aa3273a12057a09 Mon Sep 17 00:00:00 2001 From: Geenz Date: Fri, 31 May 2013 20:35:26 -0400 Subject: [PATCH 51/51] Remove unnecessary normalize. --- interface/resources/shaders/SkyFromAtmosphere.frag | 2 +- interface/resources/shaders/SkyFromSpace.frag | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/shaders/SkyFromAtmosphere.frag b/interface/resources/shaders/SkyFromAtmosphere.frag index 4f3bbff9b0..b640f5f952 100644 --- a/interface/resources/shaders/SkyFromAtmosphere.frag +++ b/interface/resources/shaders/SkyFromAtmosphere.frag @@ -87,7 +87,7 @@ void main (void) float fHeight = length(v3SamplePoint); float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight)); float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight; - float fCameraAngle = dot(normalize(v3Ray), v3SamplePoint) / fHeight * 0.99; + float fCameraAngle = dot((v3Ray), v3SamplePoint) / fHeight * 0.99; float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle))); vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI)); v3FrontColor += v3Attenuate * (fDepth * fScaledLength); diff --git a/interface/resources/shaders/SkyFromSpace.frag b/interface/resources/shaders/SkyFromSpace.frag index d4e1c58da5..b1380d00be 100644 --- a/interface/resources/shaders/SkyFromSpace.frag +++ b/interface/resources/shaders/SkyFromSpace.frag @@ -97,7 +97,7 @@ void main (void) float fHeight = length(v3SamplePoint); float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight)); float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight; - float fCameraAngle = dot(normalize(v3Ray), v3SamplePoint) / fHeight * 0.99; + float fCameraAngle = dot((v3Ray), v3SamplePoint) / fHeight * 0.99; float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle))); vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI)); v3FrontColor += v3Attenuate * (fDepth * fScaledLength);