From 4cac35293a00d6b01b77ed7b516866671d7862a5 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 10:08:15 -0700 Subject: [PATCH 01/33] Refer to body balls parents, not joint parents. --- interface/src/Avatar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 04e462fd43..82336dec76 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1082,9 +1082,9 @@ void Avatar::updateBodyBalls(float deltaTime) { if (_skeleton.joint[b].parent == AVATAR_JOINT_NULL || length < SMALL_SPRING_LENGTH) { _bodyBall[b].rotation = orientation * _skeleton.joint[_bodyBall[b].parentJoint].absoluteBindPoseRotation; } else { - glm::vec3 parentDirection = _bodyBall[ _skeleton.joint[b].parent ].rotation * JOINT_DIRECTION; + glm::vec3 parentDirection = _bodyBall[ _bodyBall[b].parentBall ].rotation * JOINT_DIRECTION; _bodyBall[b].rotation = rotationBetween(parentDirection, springVector) * - _bodyBall[ _skeleton.joint[b].parent ].rotation; + _bodyBall[ _bodyBall[b].parentBall ].rotation; } } } From e0189c9834f64512548cadf3ba1d3794046f3533 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 10:17:57 -0700 Subject: [PATCH 02/33] Build fix, render body as balls if we don't have an avatar. --- audio-mixer/src/InjectedAudioRingBuffer.cpp | 4 +++- audio-mixer/src/PositionalAudioRingBuffer.cpp | 4 +++- interface/src/Avatar.cpp | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/audio-mixer/src/InjectedAudioRingBuffer.cpp b/audio-mixer/src/InjectedAudioRingBuffer.cpp index b866c2650e..426bbf361d 100644 --- a/audio-mixer/src/InjectedAudioRingBuffer.cpp +++ b/audio-mixer/src/InjectedAudioRingBuffer.cpp @@ -6,6 +6,8 @@ // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // +#include + #include #include "InjectedAudioRingBuffer.h" @@ -38,4 +40,4 @@ int InjectedAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes currentBuffer += parseAudioSamples(currentBuffer, numBytes - (currentBuffer - sourceBuffer)); return currentBuffer - sourceBuffer; -} \ No newline at end of file +} diff --git a/audio-mixer/src/PositionalAudioRingBuffer.cpp b/audio-mixer/src/PositionalAudioRingBuffer.cpp index 81911fc9df..2e83d3a4f6 100644 --- a/audio-mixer/src/PositionalAudioRingBuffer.cpp +++ b/audio-mixer/src/PositionalAudioRingBuffer.cpp @@ -6,6 +6,8 @@ // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // +#include + #include #include "PositionalAudioRingBuffer.h" @@ -64,4 +66,4 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix(int numJitterBufferSamples) { } return false; -} \ No newline at end of file +} diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 4be98641b2..83adb8a62e 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1133,7 +1133,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) { const float RENDER_TRANSLUCENT_BEYOND = 0.5f; // Render the body as balls and cones - if (renderAvatarBalls) { + if (renderAvatarBalls || !_voxels.getVoxelURL().isValid()) { for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) { float distanceToCamera = glm::length(_cameraPosition - _bodyBall[b].position); From 2cc640b6f67bed9a211ef0369abf622d72dc4859 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 10:26:26 -0700 Subject: [PATCH 03/33] Set head bone rotation from head orientation. --- interface/src/Avatar.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 83adb8a62e..79a51a96ff 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1073,6 +1073,9 @@ void Avatar::updateBodyBalls(float deltaTime) { _bodyBall[ _bodyBall[b].parentBall ].rotation; } } + + // copy the head's rotation + _bodyBall[BODY_BALL_HEAD_TOP].rotation = _head.getOrientation(); } void Avatar::updateArmIKAndConstraints(float deltaTime) { From 27717bfcd427eee5dff247e918f4cbda33fd9bb2 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 10:48:35 -0700 Subject: [PATCH 04/33] Removed unused variables. --- interface/src/Avatar.cpp | 1 - interface/src/VoxelSystem.cpp | 2 -- 2 files changed, 3 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 79a51a96ff..c468514bb3 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1008,7 +1008,6 @@ void Avatar::updateBodyBalls(float deltaTime) { resetBodyBalls(); } glm::quat orientation = getOrientation(); - glm::vec3 jointDirection = orientation * JOINT_DIRECTION; for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) { glm::vec3 springVector; diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 7e179c0919..9cde8906be 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -256,7 +256,6 @@ void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() { void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { glBufferIndex segmentStart = 0; - glBufferIndex segmentEnd = 0; bool inSegment = false; for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { bool thisVoxelDirty = _writeVoxelDirtyArray[i]; @@ -560,7 +559,6 @@ void VoxelSystem::updateFullVBOs() { void VoxelSystem::updatePartialVBOs() { glBufferIndex segmentStart = 0; - glBufferIndex segmentEnd = 0; bool inSegment = false; for (glBufferIndex i = 0; i < _voxelsInReadArrays; i++) { bool thisVoxelDirty = _readVoxelDirtyArray[i]; From d9d6891cc8db1939e710c016fa4f754f12fa7cf3 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 10:54:28 -0700 Subject: [PATCH 05/33] Use the head rotation to adjust the position, too. --- interface/src/Avatar.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index c468514bb3..b4e770d664 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1075,6 +1075,8 @@ void Avatar::updateBodyBalls(float deltaTime) { // copy the head's rotation _bodyBall[BODY_BALL_HEAD_TOP].rotation = _head.getOrientation(); + _bodyBall[BODY_BALL_HEAD_TOP].position = _bodyBall[BODY_BALL_HEAD_BASE].position + + _bodyBall[BODY_BALL_HEAD_TOP].rotation * _skeleton.joint[BODY_BALL_HEAD_TOP].bindPosePosition; } void Avatar::updateArmIKAndConstraints(float deltaTime) { From 83f7b2943c772c82c3f9096a6d519387c68525c0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Jun 2013 10:59:03 -0700 Subject: [PATCH 06/33] comment out the FreeVerb effect to check mixer performance --- audio-mixer/src/main.cpp | 68 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 9b6d6032ef..ac3c1ade6f 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -220,40 +220,40 @@ int main(int argc, const char* argv[]) { numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); } - - FreeVerbAgentMap& agentFreeVerbs = agentRingBuffer->getFreeVerbs(); - FreeVerbAgentMap::iterator freeVerbIterator = agentFreeVerbs.find(otherAgent->getAgentID()); - - if (freeVerbIterator == agentFreeVerbs.end()) { - // setup the freeVerb effect for this source for this client - otherAgentFreeVerb = agentFreeVerbs[otherAgent->getAgentID()] = new stk::FreeVerb; - - otherAgentFreeVerb->setDamping(DISTANCE_REVERB_DAMPING); - otherAgentFreeVerb->setRoomSize(DISTANCE_REVERB_ROOM_SIZE); - otherAgentFreeVerb->setWidth(DISTANCE_REVERB_WIDTH); - } else { - otherAgentFreeVerb = freeVerbIterator->second; - } - - const float WETNESS_DOUBLING_DISTANCE_FACTOR = 2.0f; - const float MAX_REVERB_DISTANCE = 160.0f; - - // higher value increases wetness more quickly with distance - const float WETNESS_CALC_EXPONENT_BASE = 2.0f; - - const float MAX_EXPONENT = logf(MAX_REVERB_DISTANCE) / logf(WETNESS_DOUBLING_DISTANCE_FACTOR); - const int MAX_EXPONENT_INT = floorf(MAX_EXPONENT); - const float DISTANCE_REVERB_LOG_REMAINDER = fmodf(MAX_EXPONENT, MAX_EXPONENT_INT); - const float DISTANCE_REVERB_MAX_WETNESS = 1.0f; - const float EFFECT_MIX_RHS = DISTANCE_REVERB_MAX_WETNESS / powf(WETNESS_DOUBLING_DISTANCE_FACTOR, - MAX_EXPONENT_INT); - - float effectMix = powf(WETNESS_CALC_EXPONENT_BASE, - (0.5f * logf(distanceSquareToSource) / logf(WETNESS_CALC_EXPONENT_BASE)) - - DISTANCE_REVERB_LOG_REMAINDER); - effectMix *= EFFECT_MIX_RHS; - - otherAgentFreeVerb->setEffectMix(effectMix); +// +// FreeVerbAgentMap& agentFreeVerbs = agentRingBuffer->getFreeVerbs(); +// FreeVerbAgentMap::iterator freeVerbIterator = agentFreeVerbs.find(otherAgent->getAgentID()); +// +// if (freeVerbIterator == agentFreeVerbs.end()) { +// // setup the freeVerb effect for this source for this client +// otherAgentFreeVerb = agentFreeVerbs[otherAgent->getAgentID()] = new stk::FreeVerb; +// +// otherAgentFreeVerb->setDamping(DISTANCE_REVERB_DAMPING); +// otherAgentFreeVerb->setRoomSize(DISTANCE_REVERB_ROOM_SIZE); +// otherAgentFreeVerb->setWidth(DISTANCE_REVERB_WIDTH); +// } else { +// otherAgentFreeVerb = freeVerbIterator->second; +// } +// +// const float WETNESS_DOUBLING_DISTANCE_FACTOR = 2.0f; +// const float MAX_REVERB_DISTANCE = 160.0f; +// +// // higher value increases wetness more quickly with distance +// const float WETNESS_CALC_EXPONENT_BASE = 2.0f; +// +// const float MAX_EXPONENT = logf(MAX_REVERB_DISTANCE) / logf(WETNESS_DOUBLING_DISTANCE_FACTOR); +// const int MAX_EXPONENT_INT = floorf(MAX_EXPONENT); +// const float DISTANCE_REVERB_LOG_REMAINDER = fmodf(MAX_EXPONENT, MAX_EXPONENT_INT); +// const float DISTANCE_REVERB_MAX_WETNESS = 1.0f; +// const float EFFECT_MIX_RHS = DISTANCE_REVERB_MAX_WETNESS / powf(WETNESS_DOUBLING_DISTANCE_FACTOR, +// MAX_EXPONENT_INT); +// +// float effectMix = powf(WETNESS_CALC_EXPONENT_BASE, +// (0.5f * logf(distanceSquareToSource) / logf(WETNESS_CALC_EXPONENT_BASE)) +// - DISTANCE_REVERB_LOG_REMAINDER); +// effectMix *= EFFECT_MIX_RHS; +// +// otherAgentFreeVerb->setEffectMix(effectMix); } int16_t* goodChannel = (bearingRelativeAngleToSource > 0.0f) From 72325446265ecaad9fe0602795a9759fa973a945 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Jun 2013 11:04:40 -0700 Subject: [PATCH 07/33] uncomment the FreeVerb code --- audio-mixer/src/main.cpp | 68 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index d84a995767..5ed19e6c60 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -220,40 +220,40 @@ int main(int argc, const char* argv[]) { numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); } -// -// FreeVerbAgentMap& agentFreeVerbs = agentRingBuffer->getFreeVerbs(); -// FreeVerbAgentMap::iterator freeVerbIterator = agentFreeVerbs.find(otherAgent->getAgentID()); -// -// if (freeVerbIterator == agentFreeVerbs.end()) { -// // setup the freeVerb effect for this source for this client -// otherAgentFreeVerb = agentFreeVerbs[otherAgent->getAgentID()] = new stk::FreeVerb; -// -// otherAgentFreeVerb->setDamping(DISTANCE_REVERB_DAMPING); -// otherAgentFreeVerb->setRoomSize(DISTANCE_REVERB_ROOM_SIZE); -// otherAgentFreeVerb->setWidth(DISTANCE_REVERB_WIDTH); -// } else { -// otherAgentFreeVerb = freeVerbIterator->second; -// } -// -// const float WETNESS_DOUBLING_DISTANCE_FACTOR = 2.0f; -// const float MAX_REVERB_DISTANCE = 160.0f; -// -// // higher value increases wetness more quickly with distance -// const float WETNESS_CALC_EXPONENT_BASE = 2.0f; -// -// const float MAX_EXPONENT = logf(MAX_REVERB_DISTANCE) / logf(WETNESS_DOUBLING_DISTANCE_FACTOR); -// const int MAX_EXPONENT_INT = floorf(MAX_EXPONENT); -// const float DISTANCE_REVERB_LOG_REMAINDER = fmodf(MAX_EXPONENT, MAX_EXPONENT_INT); -// const float DISTANCE_REVERB_MAX_WETNESS = 1.0f; -// const float EFFECT_MIX_RHS = DISTANCE_REVERB_MAX_WETNESS / powf(WETNESS_DOUBLING_DISTANCE_FACTOR, -// MAX_EXPONENT_INT); -// -// float effectMix = powf(WETNESS_CALC_EXPONENT_BASE, -// (0.5f * logf(distanceSquareToSource) / logf(WETNESS_CALC_EXPONENT_BASE)) -// - DISTANCE_REVERB_LOG_REMAINDER); -// effectMix *= EFFECT_MIX_RHS; -// -// otherAgentFreeVerb->setEffectMix(effectMix); + + FreeVerbAgentMap& agentFreeVerbs = agentRingBuffer->getFreeVerbs(); + FreeVerbAgentMap::iterator freeVerbIterator = agentFreeVerbs.find(otherAgent->getAgentID()); + + if (freeVerbIterator == agentFreeVerbs.end()) { + // setup the freeVerb effect for this source for this client + otherAgentFreeVerb = agentFreeVerbs[otherAgent->getAgentID()] = new stk::FreeVerb; + + otherAgentFreeVerb->setDamping(DISTANCE_REVERB_DAMPING); + otherAgentFreeVerb->setRoomSize(DISTANCE_REVERB_ROOM_SIZE); + otherAgentFreeVerb->setWidth(DISTANCE_REVERB_WIDTH); + } else { + otherAgentFreeVerb = freeVerbIterator->second; + } + + const float WETNESS_DOUBLING_DISTANCE_FACTOR = 2.0f; + const float MAX_REVERB_DISTANCE = 160.0f; + + // higher value increases wetness more quickly with distance + const float WETNESS_CALC_EXPONENT_BASE = 2.0f; + + const float MAX_EXPONENT = logf(MAX_REVERB_DISTANCE) / logf(WETNESS_DOUBLING_DISTANCE_FACTOR); + const int MAX_EXPONENT_INT = floorf(MAX_EXPONENT); + const float DISTANCE_REVERB_LOG_REMAINDER = fmodf(MAX_EXPONENT, MAX_EXPONENT_INT); + const float DISTANCE_REVERB_MAX_WETNESS = 1.0f; + const float EFFECT_MIX_RHS = DISTANCE_REVERB_MAX_WETNESS / powf(WETNESS_DOUBLING_DISTANCE_FACTOR, + MAX_EXPONENT_INT); + + float effectMix = powf(WETNESS_CALC_EXPONENT_BASE, + (0.5f * logf(distanceSquareToSource) / logf(WETNESS_CALC_EXPONENT_BASE)) + - DISTANCE_REVERB_LOG_REMAINDER); + effectMix *= EFFECT_MIX_RHS; + + otherAgentFreeVerb->setEffectMix(effectMix); } int16_t* goodChannel = (bearingRelativeAngleToSource > 0.0f) From 56b4c04a18b468ed6752676d9e3c03d72f455171 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 11:09:09 -0700 Subject: [PATCH 08/33] Adjusted head base/top transforms. --- interface/src/Avatar.cpp | 4 +++- interface/src/Skeleton.cpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index b4e770d664..143b88aaa7 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1074,7 +1074,9 @@ void Avatar::updateBodyBalls(float deltaTime) { } // copy the head's rotation - _bodyBall[BODY_BALL_HEAD_TOP].rotation = _head.getOrientation(); + _bodyBall[BODY_BALL_HEAD_BASE].rotation = _bodyBall[BODY_BALL_HEAD_TOP].rotation = _head.getOrientation(); + _bodyBall[BODY_BALL_HEAD_BASE].position = _bodyBall[BODY_BALL_NECK_BASE].position + + _bodyBall[BODY_BALL_HEAD_BASE].rotation * _skeleton.joint[BODY_BALL_HEAD_BASE].bindPosePosition; _bodyBall[BODY_BALL_HEAD_TOP].position = _bodyBall[BODY_BALL_HEAD_BASE].position + _bodyBall[BODY_BALL_HEAD_TOP].rotation * _skeleton.joint[BODY_BALL_HEAD_TOP].bindPosePosition; } diff --git a/interface/src/Skeleton.cpp b/interface/src/Skeleton.cpp index 92dba252a1..3b3e42a4f4 100644 --- a/interface/src/Skeleton.cpp +++ b/interface/src/Skeleton.cpp @@ -56,6 +56,7 @@ void Skeleton::initialize() { joint[ AVATAR_JOINT_CHEST ].bindPosePosition = glm::vec3( 0.0, 0.09, -0.01 ); joint[ AVATAR_JOINT_NECK_BASE ].bindPosePosition = glm::vec3( 0.0, 0.14, 0.01 ); joint[ AVATAR_JOINT_HEAD_BASE ].bindPosePosition = glm::vec3( 0.0, 0.04, 0.00 ); + joint[ AVATAR_JOINT_HEAD_TOP ].bindPosePosition = glm::vec3( 0.0, 0.04, 0.00 ); joint[ AVATAR_JOINT_LEFT_COLLAR ].bindPosePosition = glm::vec3( -0.06, 0.04, 0.01 ); joint[ AVATAR_JOINT_LEFT_SHOULDER ].bindPosePosition = glm::vec3( -0.05, 0.0, 0.01 ); From 8e4ef406cabaf8eda0fdc4d0f64075312c5183d0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Jun 2013 11:11:57 -0700 Subject: [PATCH 09/33] Revert "uncomment the FreeVerb code" This reverts commit 72325446265ecaad9fe0602795a9759fa973a945. --- audio-mixer/src/main.cpp | 68 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 5ed19e6c60..d84a995767 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -220,40 +220,40 @@ int main(int argc, const char* argv[]) { numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); } - - FreeVerbAgentMap& agentFreeVerbs = agentRingBuffer->getFreeVerbs(); - FreeVerbAgentMap::iterator freeVerbIterator = agentFreeVerbs.find(otherAgent->getAgentID()); - - if (freeVerbIterator == agentFreeVerbs.end()) { - // setup the freeVerb effect for this source for this client - otherAgentFreeVerb = agentFreeVerbs[otherAgent->getAgentID()] = new stk::FreeVerb; - - otherAgentFreeVerb->setDamping(DISTANCE_REVERB_DAMPING); - otherAgentFreeVerb->setRoomSize(DISTANCE_REVERB_ROOM_SIZE); - otherAgentFreeVerb->setWidth(DISTANCE_REVERB_WIDTH); - } else { - otherAgentFreeVerb = freeVerbIterator->second; - } - - const float WETNESS_DOUBLING_DISTANCE_FACTOR = 2.0f; - const float MAX_REVERB_DISTANCE = 160.0f; - - // higher value increases wetness more quickly with distance - const float WETNESS_CALC_EXPONENT_BASE = 2.0f; - - const float MAX_EXPONENT = logf(MAX_REVERB_DISTANCE) / logf(WETNESS_DOUBLING_DISTANCE_FACTOR); - const int MAX_EXPONENT_INT = floorf(MAX_EXPONENT); - const float DISTANCE_REVERB_LOG_REMAINDER = fmodf(MAX_EXPONENT, MAX_EXPONENT_INT); - const float DISTANCE_REVERB_MAX_WETNESS = 1.0f; - const float EFFECT_MIX_RHS = DISTANCE_REVERB_MAX_WETNESS / powf(WETNESS_DOUBLING_DISTANCE_FACTOR, - MAX_EXPONENT_INT); - - float effectMix = powf(WETNESS_CALC_EXPONENT_BASE, - (0.5f * logf(distanceSquareToSource) / logf(WETNESS_CALC_EXPONENT_BASE)) - - DISTANCE_REVERB_LOG_REMAINDER); - effectMix *= EFFECT_MIX_RHS; - - otherAgentFreeVerb->setEffectMix(effectMix); +// +// FreeVerbAgentMap& agentFreeVerbs = agentRingBuffer->getFreeVerbs(); +// FreeVerbAgentMap::iterator freeVerbIterator = agentFreeVerbs.find(otherAgent->getAgentID()); +// +// if (freeVerbIterator == agentFreeVerbs.end()) { +// // setup the freeVerb effect for this source for this client +// otherAgentFreeVerb = agentFreeVerbs[otherAgent->getAgentID()] = new stk::FreeVerb; +// +// otherAgentFreeVerb->setDamping(DISTANCE_REVERB_DAMPING); +// otherAgentFreeVerb->setRoomSize(DISTANCE_REVERB_ROOM_SIZE); +// otherAgentFreeVerb->setWidth(DISTANCE_REVERB_WIDTH); +// } else { +// otherAgentFreeVerb = freeVerbIterator->second; +// } +// +// const float WETNESS_DOUBLING_DISTANCE_FACTOR = 2.0f; +// const float MAX_REVERB_DISTANCE = 160.0f; +// +// // higher value increases wetness more quickly with distance +// const float WETNESS_CALC_EXPONENT_BASE = 2.0f; +// +// const float MAX_EXPONENT = logf(MAX_REVERB_DISTANCE) / logf(WETNESS_DOUBLING_DISTANCE_FACTOR); +// const int MAX_EXPONENT_INT = floorf(MAX_EXPONENT); +// const float DISTANCE_REVERB_LOG_REMAINDER = fmodf(MAX_EXPONENT, MAX_EXPONENT_INT); +// const float DISTANCE_REVERB_MAX_WETNESS = 1.0f; +// const float EFFECT_MIX_RHS = DISTANCE_REVERB_MAX_WETNESS / powf(WETNESS_DOUBLING_DISTANCE_FACTOR, +// MAX_EXPONENT_INT); +// +// float effectMix = powf(WETNESS_CALC_EXPONENT_BASE, +// (0.5f * logf(distanceSquareToSource) / logf(WETNESS_CALC_EXPONENT_BASE)) +// - DISTANCE_REVERB_LOG_REMAINDER); +// effectMix *= EFFECT_MIX_RHS; +// +// otherAgentFreeVerb->setEffectMix(effectMix); } int16_t* goodChannel = (bearingRelativeAngleToSource > 0.0f) From b13f22be26e4af52642878ef4254b206fc137ab2 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 11:14:57 -0700 Subject: [PATCH 10/33] Forgot to update the default pose position. --- interface/src/Skeleton.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/Skeleton.cpp b/interface/src/Skeleton.cpp index 3b3e42a4f4..2fa43c9010 100644 --- a/interface/src/Skeleton.cpp +++ b/interface/src/Skeleton.cpp @@ -86,6 +86,7 @@ void Skeleton::initialize() { 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_HEAD_TOP ].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 ); From 19ab1816bbe1e32e88af86ae17026c4ac4b3b6e8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Jun 2013 11:45:33 -0700 Subject: [PATCH 11/33] remove the CPU hogging FreeVerb effect --- audio-mixer/src/AvatarAudioRingBuffer.cpp | 8 ---- audio-mixer/src/AvatarAudioRingBuffer.h | 8 ---- audio-mixer/src/main.cpp | 52 ----------------------- 3 files changed, 68 deletions(-) diff --git a/audio-mixer/src/AvatarAudioRingBuffer.cpp b/audio-mixer/src/AvatarAudioRingBuffer.cpp index 61d23f0fe6..6da4e20871 100644 --- a/audio-mixer/src/AvatarAudioRingBuffer.cpp +++ b/audio-mixer/src/AvatarAudioRingBuffer.cpp @@ -11,18 +11,10 @@ #include "AvatarAudioRingBuffer.h" AvatarAudioRingBuffer::AvatarAudioRingBuffer() : - _freeVerbs(), _shouldLoopbackForAgent(false) { } -AvatarAudioRingBuffer::~AvatarAudioRingBuffer() { - // enumerate the freeVerbs map and delete the FreeVerb objects - for (FreeVerbAgentMap::iterator verbIterator = _freeVerbs.begin(); verbIterator != _freeVerbs.end(); verbIterator++) { - delete verbIterator->second; - } -} - int AvatarAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { _shouldLoopbackForAgent = (sourceBuffer[0] == PACKET_HEADER_MICROPHONE_AUDIO_WITH_ECHO); return PositionalAudioRingBuffer::parseData(sourceBuffer, numBytes); diff --git a/audio-mixer/src/AvatarAudioRingBuffer.h b/audio-mixer/src/AvatarAudioRingBuffer.h index 1ca069b70c..7efb503f16 100644 --- a/audio-mixer/src/AvatarAudioRingBuffer.h +++ b/audio-mixer/src/AvatarAudioRingBuffer.h @@ -9,28 +9,20 @@ #ifndef __hifi__AvatarAudioRingBuffer__ #define __hifi__AvatarAudioRingBuffer__ -#include -#include - #include "PositionalAudioRingBuffer.h" -typedef std::map FreeVerbAgentMap; - class AvatarAudioRingBuffer : public PositionalAudioRingBuffer { public: AvatarAudioRingBuffer(); - ~AvatarAudioRingBuffer(); int parseData(unsigned char* sourceBuffer, int numBytes); - FreeVerbAgentMap& getFreeVerbs() { return _freeVerbs; } bool shouldLoopbackForAgent() const { return _shouldLoopbackForAgent; } private: // disallow copying of AvatarAudioRingBuffer objects AvatarAudioRingBuffer(const AvatarAudioRingBuffer&); AvatarAudioRingBuffer& operator= (const AvatarAudioRingBuffer&); - FreeVerbAgentMap _freeVerbs; bool _shouldLoopbackForAgent; }; diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index d84a995767..3618982a79 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -104,11 +104,6 @@ int main(int argc, const char* argv[]) { int16_t clientSamples[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {}; - // setup STK for the reverb effect - const float DISTANCE_REVERB_DAMPING = 0.6f; - const float DISTANCE_REVERB_ROOM_SIZE = 0.75f; - const float DISTANCE_REVERB_WIDTH = 0.5f; - gettimeofday(&startTime, NULL); while (true) { @@ -142,8 +137,6 @@ int main(int argc, const char* argv[]) { int numSamplesDelay = 0; float weakChannelAmplitudeRatio = 1.0f; - stk::FreeVerb* otherAgentFreeVerb = NULL; - if (otherAgent != agent) { glm::vec3 listenerPosition = agentRingBuffer->getPosition(); @@ -220,40 +213,6 @@ int main(int argc, const char* argv[]) { numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); } -// -// FreeVerbAgentMap& agentFreeVerbs = agentRingBuffer->getFreeVerbs(); -// FreeVerbAgentMap::iterator freeVerbIterator = agentFreeVerbs.find(otherAgent->getAgentID()); -// -// if (freeVerbIterator == agentFreeVerbs.end()) { -// // setup the freeVerb effect for this source for this client -// otherAgentFreeVerb = agentFreeVerbs[otherAgent->getAgentID()] = new stk::FreeVerb; -// -// otherAgentFreeVerb->setDamping(DISTANCE_REVERB_DAMPING); -// otherAgentFreeVerb->setRoomSize(DISTANCE_REVERB_ROOM_SIZE); -// otherAgentFreeVerb->setWidth(DISTANCE_REVERB_WIDTH); -// } else { -// otherAgentFreeVerb = freeVerbIterator->second; -// } -// -// const float WETNESS_DOUBLING_DISTANCE_FACTOR = 2.0f; -// const float MAX_REVERB_DISTANCE = 160.0f; -// -// // higher value increases wetness more quickly with distance -// const float WETNESS_CALC_EXPONENT_BASE = 2.0f; -// -// const float MAX_EXPONENT = logf(MAX_REVERB_DISTANCE) / logf(WETNESS_DOUBLING_DISTANCE_FACTOR); -// const int MAX_EXPONENT_INT = floorf(MAX_EXPONENT); -// const float DISTANCE_REVERB_LOG_REMAINDER = fmodf(MAX_EXPONENT, MAX_EXPONENT_INT); -// const float DISTANCE_REVERB_MAX_WETNESS = 1.0f; -// const float EFFECT_MIX_RHS = DISTANCE_REVERB_MAX_WETNESS / powf(WETNESS_DOUBLING_DISTANCE_FACTOR, -// MAX_EXPONENT_INT); -// -// float effectMix = powf(WETNESS_CALC_EXPONENT_BASE, -// (0.5f * logf(distanceSquareToSource) / logf(WETNESS_CALC_EXPONENT_BASE)) -// - DISTANCE_REVERB_LOG_REMAINDER); -// effectMix *= EFFECT_MIX_RHS; -// -// otherAgentFreeVerb->setEffectMix(effectMix); } int16_t* goodChannel = (bearingRelativeAngleToSource > 0.0f) @@ -280,17 +239,6 @@ int main(int argc, const char* argv[]) { int16_t currentSample = otherAgentBuffer->getNextOutput()[s]; - // apply the STK FreeVerb effect - if (otherAgentFreeVerb) { - currentSample = otherAgentFreeVerb->tick(currentSample); - - if (s >= BUFFER_LENGTH_SAMPLES_PER_CHANNEL - PHASE_DELAY_AT_90) { - // there is the possiblity this will be re-used as a delayed sample - // so store the reverbed sample so that is what will be pulled - otherAgentBuffer->getNextOutput()[s] = currentSample; - } - } - currentSample *= attenuationCoefficient; plateauAdditionOfSamples(goodChannel[s], currentSample); From 53fece29fa01edbb0b2b19520bbb8e7a3259e910 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Jun 2013 11:47:14 -0700 Subject: [PATCH 12/33] remove redundant calculation --- audio-mixer/src/main.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 3618982a79..955345b942 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -237,9 +237,7 @@ int main(int argc, const char* argv[]) { plateauAdditionOfSamples(delayedChannel[s], earlierSample); } - int16_t currentSample = otherAgentBuffer->getNextOutput()[s]; - - currentSample *= attenuationCoefficient; + int16_t currentSample = otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient; plateauAdditionOfSamples(goodChannel[s], currentSample); From 115c39dbcff10938705c794bff1299ae7d28386e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Jun 2013 11:48:20 -0700 Subject: [PATCH 13/33] bring PHASE_DELAY_AT_90 constant above algorithim that uses it --- audio-mixer/src/main.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 955345b942..cbe64706cd 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -124,8 +124,6 @@ int main(int argc, const char* argv[]) { // zero out the client mix for this agent memset(clientSamples, 0, sizeof(clientSamples)); - const int PHASE_DELAY_AT_90 = 20; - for (AgentList::iterator otherAgent = agentList->begin(); otherAgent != agentList->end(); otherAgent++) { if (((PositionalAudioRingBuffer*) otherAgent->getLinkedData())->willBeAddedToMix() && (otherAgent != agent || (otherAgent == agent && agentRingBuffer->shouldLoopbackForAgent()))) { @@ -205,6 +203,7 @@ int main(int argc, const char* argv[]) { glm::normalize(rotatedSourcePosition), glm::vec3(0.0f, 1.0f, 0.0f)); + const int PHASE_DELAY_AT_90 = 20; const float PHASE_AMPLITUDE_RATIO_AT_90 = 0.5; // figure out the number of samples of delay and the ratio of the amplitude From ecd03d7b4b3d94b3cfaed2d8c5d077683aab023e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Jun 2013 11:54:44 -0700 Subject: [PATCH 14/33] replace magic number 1 with sizeof --- interface/src/Audio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index cba5139c05..1f1f9cc335 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -129,7 +129,7 @@ int audioCallback (const void* inputBuffer, glm::vec3 headPosition = interfaceAvatar->getHeadJointPosition(); glm::quat headOrientation = interfaceAvatar->getHead().getOrientation(); - int leadingBytes = 1 + sizeof(headPosition) + sizeof(headOrientation); + int leadingBytes = sizeof(PACKET_HEADER_MICROPHONE_AUDIO_NO_ECHO) + sizeof(headPosition) + sizeof(headOrientation); // we need the amount of bytes in the buffer + 1 for type // + 12 for 3 floats for position + float for bearing + 1 attenuation byte From 233ce67379e0105a68ac1f9dcd6dab5652e45f20 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Jun 2013 11:57:38 -0700 Subject: [PATCH 15/33] don't link STK library while not being used --- audio-mixer/CMakeLists.txt | 8 +------- audio-mixer/src/main.cpp | 2 -- injector/CMakeLists.txt | 8 +------- interface/CMakeLists.txt | 6 ------ libraries/audio/CMakeLists.txt | 8 +------- 5 files changed, 3 insertions(+), 29 deletions(-) diff --git a/audio-mixer/CMakeLists.txt b/audio-mixer/CMakeLists.txt index 7e83e6fc1a..eac2792883 100644 --- a/audio-mixer/CMakeLists.txt +++ b/audio-mixer/CMakeLists.txt @@ -18,10 +18,4 @@ include_glm(${TARGET_NAME} ${ROOT_DIR}) # link the shared hifi library include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) -link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR}) - -# link the stk library -set(STK_ROOT_DIR ${ROOT_DIR}/externals/stk) -find_package(STK REQUIRED) -target_link_libraries(${TARGET_NAME} ${STK_LIBRARIES}) -include_directories(${STK_INCLUDE_DIRS}) \ No newline at end of file +link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index cbe64706cd..7276a24594 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include "InjectedAudioRingBuffer.h" #include "AvatarAudioRingBuffer.h" diff --git a/injector/CMakeLists.txt b/injector/CMakeLists.txt index 83a650c62e..2c022b0e92 100644 --- a/injector/CMakeLists.txt +++ b/injector/CMakeLists.txt @@ -19,10 +19,4 @@ include_glm(${TARGET_NAME} ${ROOT_DIR}) include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR}) -link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR}) - -# link the stk library -set(STK_ROOT_DIR ${ROOT_DIR}/externals/stk) -find_package(STK REQUIRED) -target_link_libraries(${TARGET_NAME} ${STK_LIBRARIES}) -include_directories(${STK_INCLUDE_DIRS}) \ No newline at end of file +link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 5b0f94d7db..b2984b35bb 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -146,12 +146,6 @@ else (WIN32) include_directories(${PORTAUDIO_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${PORTAUDIO_LIBRARIES}) - # link the stk library - set(STK_ROOT_DIR ${ROOT_DIR}/externals/stk) - find_package(STK REQUIRED) - target_link_libraries(${TARGET_NAME} ${STK_LIBRARIES}) - include_directories(${STK_INCLUDE_DIRS}) - # link required libraries on UNIX if (UNIX AND NOT APPLE) find_package(Threads REQUIRED) diff --git a/libraries/audio/CMakeLists.txt b/libraries/audio/CMakeLists.txt index 229f3dd49f..686986340f 100644 --- a/libraries/audio/CMakeLists.txt +++ b/libraries/audio/CMakeLists.txt @@ -19,10 +19,4 @@ link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) # link the threads library find_package(Threads REQUIRED) -target_link_libraries(${TARGET_NAME} ${CMAKE_THREAD_LIBS_INIT}) - -# link the stk library -set(STK_ROOT_DIR ${ROOT_DIR}/externals/stk) -find_package(STK REQUIRED) -target_link_libraries(${TARGET_NAME} ${STK_LIBRARIES}) -include_directories(${STK_INCLUDE_DIRS}) \ No newline at end of file +target_link_libraries(${TARGET_NAME} ${CMAKE_THREAD_LIBS_INIT}) \ No newline at end of file From a85149968417d87780c1d15b6a4387181ae8a265 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 12:03:50 -0700 Subject: [PATCH 16/33] Rework rotation estimation bits to use quaternions. --- interface/src/SerialInterface.cpp | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index 1e472c5a11..ad23051a1b 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -229,8 +229,8 @@ void SerialInterface::readData(float deltaTime) { _lastRotationRates[2] = ((float) -rollRate) * LSB_TO_DEGREES_PER_SECOND; // Update raw rotation estimates - _estimatedRotation += deltaTime * (_lastRotationRates - _averageRotationRates); - + glm::quat estimatedRotation = glm::quat(glm::radians(_estimatedRotation)) * + glm::quat(glm::radians(deltaTime * (_lastRotationRates - _averageRotationRates))); // Update estimated position and velocity float const DECAY_VELOCITY = 0.95f; @@ -258,29 +258,12 @@ void SerialInterface::readData(float deltaTime) { 1.f/(float)GRAVITY_SAMPLES * _lastAcceleration; } else { // Use gravity reading to do sensor fusion on the pitch and roll estimation - float truePitchAngle = glm::angle(glm::normalize(glm::vec3(0, _gravity.y, _gravity.z)), - glm::normalize(glm::vec3(0, _lastAcceleration.y, _lastAcceleration.z))) - * ((_lastAcceleration.z > _gravity.z) ? -1.0 : 1.0); - - float trueRollAngle = glm::angle(glm::normalize(glm::vec3(_gravity.x, _gravity.y, 0)), - glm::normalize(glm::vec3(_lastAcceleration.x, _lastAcceleration.y, 0))) - * ((_lastAcceleration.x > _gravity.x) ? -1.0 : 1.0); - - // PER: BUG: This is bizarre, because glm::angle() SOMETIMES returns NaN for what seem to - // be perfectly valid inputs. So I added these NaN tests, gotta fix. - if (!glm::isnan(truePitchAngle) && !glm::isnan(trueRollAngle)) { - _estimatedRotation.x = (1.f - 1.f/(float)SENSOR_FUSION_SAMPLES) * _estimatedRotation.x - + 1.f/(float)SENSOR_FUSION_SAMPLES * truePitchAngle; - _estimatedRotation.z = (1.f - 1.f/(float)SENSOR_FUSION_SAMPLES) * _estimatedRotation.z - + 1.f/(float)SENSOR_FUSION_SAMPLES * trueRollAngle; - // Without a compass heading, always decay estimated Yaw slightly - const float YAW_DECAY = 0.995; - _estimatedRotation.y *= YAW_DECAY; - } - + _estimatedRotation = safeMix(_estimatedRotation, + rotationBetween(_gravity, _lastAcceleration) * _estimatedRotation, 1.0f / SENSOR_FUSION_SAMPLES); } } - + + _estimatedRotation = safeEulerAngles(estimatedRotation); totalSamples++; } From 14f331b07db2c3b22edd258e5d6427458453f41b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 12:05:52 -0700 Subject: [PATCH 17/33] Scratch that; need to do this in a branch. --- interface/src/SerialInterface.cpp | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index ad23051a1b..1e472c5a11 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -229,8 +229,8 @@ void SerialInterface::readData(float deltaTime) { _lastRotationRates[2] = ((float) -rollRate) * LSB_TO_DEGREES_PER_SECOND; // Update raw rotation estimates - glm::quat estimatedRotation = glm::quat(glm::radians(_estimatedRotation)) * - glm::quat(glm::radians(deltaTime * (_lastRotationRates - _averageRotationRates))); + _estimatedRotation += deltaTime * (_lastRotationRates - _averageRotationRates); + // Update estimated position and velocity float const DECAY_VELOCITY = 0.95f; @@ -258,12 +258,29 @@ void SerialInterface::readData(float deltaTime) { 1.f/(float)GRAVITY_SAMPLES * _lastAcceleration; } else { // Use gravity reading to do sensor fusion on the pitch and roll estimation - _estimatedRotation = safeMix(_estimatedRotation, - rotationBetween(_gravity, _lastAcceleration) * _estimatedRotation, 1.0f / SENSOR_FUSION_SAMPLES); + float truePitchAngle = glm::angle(glm::normalize(glm::vec3(0, _gravity.y, _gravity.z)), + glm::normalize(glm::vec3(0, _lastAcceleration.y, _lastAcceleration.z))) + * ((_lastAcceleration.z > _gravity.z) ? -1.0 : 1.0); + + float trueRollAngle = glm::angle(glm::normalize(glm::vec3(_gravity.x, _gravity.y, 0)), + glm::normalize(glm::vec3(_lastAcceleration.x, _lastAcceleration.y, 0))) + * ((_lastAcceleration.x > _gravity.x) ? -1.0 : 1.0); + + // PER: BUG: This is bizarre, because glm::angle() SOMETIMES returns NaN for what seem to + // be perfectly valid inputs. So I added these NaN tests, gotta fix. + if (!glm::isnan(truePitchAngle) && !glm::isnan(trueRollAngle)) { + _estimatedRotation.x = (1.f - 1.f/(float)SENSOR_FUSION_SAMPLES) * _estimatedRotation.x + + 1.f/(float)SENSOR_FUSION_SAMPLES * truePitchAngle; + _estimatedRotation.z = (1.f - 1.f/(float)SENSOR_FUSION_SAMPLES) * _estimatedRotation.z + + 1.f/(float)SENSOR_FUSION_SAMPLES * trueRollAngle; + // Without a compass heading, always decay estimated Yaw slightly + const float YAW_DECAY = 0.995; + _estimatedRotation.y *= YAW_DECAY; + } + } } - - _estimatedRotation = safeEulerAngles(estimatedRotation); + totalSamples++; } From f04e45b7c12ecff91c13b26e22a7ed34e59694f2 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 12:07:34 -0700 Subject: [PATCH 18/33] Use quaternions for rotation estimates. --- interface/src/SerialInterface.cpp | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index 1e472c5a11..ad23051a1b 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -229,8 +229,8 @@ void SerialInterface::readData(float deltaTime) { _lastRotationRates[2] = ((float) -rollRate) * LSB_TO_DEGREES_PER_SECOND; // Update raw rotation estimates - _estimatedRotation += deltaTime * (_lastRotationRates - _averageRotationRates); - + glm::quat estimatedRotation = glm::quat(glm::radians(_estimatedRotation)) * + glm::quat(glm::radians(deltaTime * (_lastRotationRates - _averageRotationRates))); // Update estimated position and velocity float const DECAY_VELOCITY = 0.95f; @@ -258,29 +258,12 @@ void SerialInterface::readData(float deltaTime) { 1.f/(float)GRAVITY_SAMPLES * _lastAcceleration; } else { // Use gravity reading to do sensor fusion on the pitch and roll estimation - float truePitchAngle = glm::angle(glm::normalize(glm::vec3(0, _gravity.y, _gravity.z)), - glm::normalize(glm::vec3(0, _lastAcceleration.y, _lastAcceleration.z))) - * ((_lastAcceleration.z > _gravity.z) ? -1.0 : 1.0); - - float trueRollAngle = glm::angle(glm::normalize(glm::vec3(_gravity.x, _gravity.y, 0)), - glm::normalize(glm::vec3(_lastAcceleration.x, _lastAcceleration.y, 0))) - * ((_lastAcceleration.x > _gravity.x) ? -1.0 : 1.0); - - // PER: BUG: This is bizarre, because glm::angle() SOMETIMES returns NaN for what seem to - // be perfectly valid inputs. So I added these NaN tests, gotta fix. - if (!glm::isnan(truePitchAngle) && !glm::isnan(trueRollAngle)) { - _estimatedRotation.x = (1.f - 1.f/(float)SENSOR_FUSION_SAMPLES) * _estimatedRotation.x - + 1.f/(float)SENSOR_FUSION_SAMPLES * truePitchAngle; - _estimatedRotation.z = (1.f - 1.f/(float)SENSOR_FUSION_SAMPLES) * _estimatedRotation.z - + 1.f/(float)SENSOR_FUSION_SAMPLES * trueRollAngle; - // Without a compass heading, always decay estimated Yaw slightly - const float YAW_DECAY = 0.995; - _estimatedRotation.y *= YAW_DECAY; - } - + _estimatedRotation = safeMix(_estimatedRotation, + rotationBetween(_gravity, _lastAcceleration) * _estimatedRotation, 1.0f / SENSOR_FUSION_SAMPLES); } } - + + _estimatedRotation = safeEulerAngles(estimatedRotation); totalSamples++; } From 9afb1b333818a94c8955f4517597d60459cb25d4 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 13:09:00 -0700 Subject: [PATCH 19/33] Enhanced workiness. --- interface/src/SerialInterface.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index ad23051a1b..5bcb8b32ca 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -6,6 +6,7 @@ // #include "SerialInterface.h" +#include "Util.h" #include #include @@ -258,8 +259,8 @@ void SerialInterface::readData(float deltaTime) { 1.f/(float)GRAVITY_SAMPLES * _lastAcceleration; } else { // Use gravity reading to do sensor fusion on the pitch and roll estimation - _estimatedRotation = safeMix(_estimatedRotation, - rotationBetween(_gravity, _lastAcceleration) * _estimatedRotation, 1.0f / SENSOR_FUSION_SAMPLES); + estimatedRotation = safeMix(estimatedRotation, + rotationBetween(_gravity, _lastAcceleration) * estimatedRotation, 1.0f / SENSOR_FUSION_SAMPLES); } } From 650981abfae985fa7aa6dcfc15e3d6b94bf6f106 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 13:41:22 -0700 Subject: [PATCH 20/33] Remove the bounce term; it causes fluctuations in velocity. --- interface/src/Avatar.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 143b88aaa7..c0be97aebb 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -806,13 +806,12 @@ void Avatar::applyCollisionWithScene(const glm::vec3& 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 + // cancel out 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 -= glm::dot(_velocity, direction) * direction; _velocity *= KINETIC_FRICTION_DAMPING; // If velocity is quite low, apply static friction that takes away energy if (glm::length(_velocity) < STATIC_FRICTION_VELOCITY) { From d87e165b06b8ffee736245c6fb2047d6d8038ee0 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 14:08:53 -0700 Subject: [PATCH 21/33] Acceleration is presumably relative to the current orientation. --- interface/src/SerialInterface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index 5bcb8b32ca..e0c5da889b 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -260,7 +260,8 @@ void SerialInterface::readData(float deltaTime) { } else { // Use gravity reading to do sensor fusion on the pitch and roll estimation estimatedRotation = safeMix(estimatedRotation, - rotationBetween(_gravity, _lastAcceleration) * estimatedRotation, 1.0f / SENSOR_FUSION_SAMPLES); + rotationBetween(estimatedRotation * _lastAcceleration, _gravity) * estimatedRotation, + 1.0f / SENSOR_FUSION_SAMPLES); } } From 081f193db89ef77cf211cb240f118fd204eb6916 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 14:34:28 -0700 Subject: [PATCH 22/33] Add back yaw decay the quaternion way. --- interface/src/SerialInterface.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index e0c5da889b..5b53acf332 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -262,6 +262,12 @@ void SerialInterface::readData(float deltaTime) { estimatedRotation = safeMix(estimatedRotation, rotationBetween(estimatedRotation * _lastAcceleration, _gravity) * estimatedRotation, 1.0f / SENSOR_FUSION_SAMPLES); + + // Without a compass heading, always decay estimated Yaw slightly + const float YAW_DECAY = 0.995; + glm::vec3 forward = estimatedRotation * glm::vec3(0.0f, 0.0f, -1.0f); + safeMix(glm::angleAxis(glm::degrees(atan2f(forward.x, -forward.z)), glm::vec3(0.0f, 1.0f, 0.0f)) * + estimatedRotation, estimatedRotation, YAW_DECAY); } } From ba6f2307ba17b00060b2e9fbfbe629173c537fbc Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 15:43:26 -0700 Subject: [PATCH 23/33] Coordinate fix. --- interface/src/SerialInterface.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index 5b53acf332..3274856e25 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -215,7 +215,7 @@ void SerialInterface::readData(float deltaTime) { // From MPU-9150 register map, with setting on // highest resolution = +/- 2G - _lastAcceleration = glm::vec3(accelXRate, accelYRate, -accelZRate) * LSB_TO_METERS_PER_SECOND2; + _lastAcceleration = glm::vec3(-accelXRate, -accelYRate, -accelZRate) * LSB_TO_METERS_PER_SECOND2; int rollRate, yawRate, pitchRate; @@ -266,8 +266,8 @@ void SerialInterface::readData(float deltaTime) { // Without a compass heading, always decay estimated Yaw slightly const float YAW_DECAY = 0.995; glm::vec3 forward = estimatedRotation * glm::vec3(0.0f, 0.0f, -1.0f); - safeMix(glm::angleAxis(glm::degrees(atan2f(forward.x, -forward.z)), glm::vec3(0.0f, 1.0f, 0.0f)) * - estimatedRotation, estimatedRotation, YAW_DECAY); + esimatedRotation = safeMix(glm::angleAxis(glm::degrees(atan2f(forward.x, -forward.z)), + glm::vec3(0.0f, 1.0f, 0.0f)) * estimatedRotation, estimatedRotation, YAW_DECAY); } } From a7c265d017781a0fa3203df6f94d069ba9e78613 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 15:44:38 -0700 Subject: [PATCH 24/33] More compiley. --- interface/src/SerialInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index 3274856e25..82878480a8 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -266,7 +266,7 @@ void SerialInterface::readData(float deltaTime) { // Without a compass heading, always decay estimated Yaw slightly const float YAW_DECAY = 0.995; glm::vec3 forward = estimatedRotation * glm::vec3(0.0f, 0.0f, -1.0f); - esimatedRotation = safeMix(glm::angleAxis(glm::degrees(atan2f(forward.x, -forward.z)), + estimatedRotation = safeMix(glm::angleAxis(glm::degrees(atan2f(forward.x, -forward.z)), glm::vec3(0.0f, 1.0f, 0.0f)) * estimatedRotation, estimatedRotation, YAW_DECAY); } } From 0dbb5375dbd1685961996fdec080434513743b10 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 15:50:14 -0700 Subject: [PATCH 25/33] Approach the "down" direction more rapidly. --- interface/src/SerialInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index 82878480a8..8c765544fd 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -18,7 +18,7 @@ const short NO_READ_MAXIMUM_MSECS = 3000; const int GRAVITY_SAMPLES = 60; // Use the first few samples to baseline values -const int SENSOR_FUSION_SAMPLES = 200; +const int SENSOR_FUSION_SAMPLES = 20; const int LONG_TERM_RATE_SAMPLES = 1000; const bool USING_INVENSENSE_MPU9150 = 1; From bd553ef061a9ea0d1b1c3898c43805e20bf634b4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Jun 2013 16:01:36 -0700 Subject: [PATCH 26/33] repair indentation and NULL comparisons in Avatar class --- interface/src/Avatar.cpp | 62 +++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index c0be97aebb..26ffb812fc 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -62,37 +62,35 @@ float chatMessageScale = 0.0015; float chatMessageHeight = 0.20; Avatar::Avatar(Agent* owningAgent) : -AvatarData(owningAgent), -_initialized(false), -_head(this), -_ballSpringsInitialized(false), -_TEST_bigSphereRadius(0.5f), -_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f), -_mousePressed(false), -_bodyPitchDelta(0.0f), -_bodyYawDelta(0.0f), -_bodyRollDelta(0.0f), -_movedHandOffset(0.0f, 0.0f, 0.0f), -_mode(AVATAR_MODE_STANDING), -_cameraPosition(0.0f, 0.0f, 0.0f), -_handHoldingPosition(0.0f, 0.0f, 0.0f), -_velocity(0.0f, 0.0f, 0.0f), -_thrust(0.0f, 0.0f, 0.0f), -_speed(0.0f), -_maxArmLength(0.0f), -_pelvisStandingHeight(0.0f), -_pelvisFloatingHeight(0.0f), -_distanceToNearestAvatar(std::numeric_limits::max()), -_gravity(0.0f, -1.0f, 0.0f), -_worldUpDirection(DEFAULT_UP_DIRECTION), -_mouseRayOrigin(0.0f, 0.0f, 0.0f), -_mouseRayDirection(0.0f, 0.0f, 0.0f), -_interactingOther(NULL), -_isMouseTurningRight(false), -_voxels(this) - + AvatarData(owningAgent), + _initialized(false), + _head(this), + _ballSpringsInitialized(false), + _TEST_bigSphereRadius(0.5f), + _TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f), + _mousePressed(false), + _bodyPitchDelta(0.0f), + _bodyYawDelta(0.0f), + _bodyRollDelta(0.0f), + _movedHandOffset(0.0f, 0.0f, 0.0f), + _mode(AVATAR_MODE_STANDING), + _cameraPosition(0.0f, 0.0f, 0.0f), + _handHoldingPosition(0.0f, 0.0f, 0.0f), + _velocity(0.0f, 0.0f, 0.0f), + _thrust(0.0f, 0.0f, 0.0f), + _speed(0.0f), + _maxArmLength(0.0f), + _pelvisStandingHeight(0.0f), + _pelvisFloatingHeight(0.0f), + _distanceToNearestAvatar(std::numeric_limits::max()), + _gravity(0.0f, -1.0f, 0.0f), + _worldUpDirection(DEFAULT_UP_DIRECTION), + _mouseRayOrigin(0.0f, 0.0f, 0.0f), + _mouseRayDirection(0.0f, 0.0f, 0.0f), + _interactingOther(NULL), + _isMouseTurningRight(false), + _voxels(this) { - // give the pointer to our head to inherited _headData variable from AvatarData _headData = &_head; @@ -659,7 +657,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { //loop through all the other avatars for potential interactions... AgentList* agentList = AgentList::getInstance(); for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) { + if (agent->getLinkedData() && agent->getType() == AGENT_TYPE_AVATAR) { Avatar *otherAvatar = (Avatar *)agent->getLinkedData(); // test whether shoulders are close enough to allow for reaching to touch hands @@ -828,7 +826,7 @@ void Avatar::updateAvatarCollisions(float deltaTime) { // loop through all the other avatars for potential interactions... AgentList* agentList = AgentList::getInstance(); for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) { + if (agent->getLinkedData() && agent->getType() == AGENT_TYPE_AVATAR) { Avatar *otherAvatar = (Avatar *)agent->getLinkedData(); // check if the bounding spheres of the two avatars are colliding From ffc1c334556f51762b4f6a1a8e9a3bf0a98c366c Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 17:25:52 -0700 Subject: [PATCH 27/33] Removed double negation for coordinates, world aligned orientation -> camera orientation, removed roll. --- interface/src/Application.cpp | 4 ++-- interface/src/Head.cpp | 5 ++--- interface/src/Head.h | 2 +- interface/src/SerialInterface.cpp | 10 +++++----- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c85e8ecd96..0480a4a087 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -311,11 +311,11 @@ void Application::paintGL() { } else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { _myCamera.setTightness(0.0f); // In first person, camera follows head exactly without delay _myCamera.setTargetPosition(_myAvatar.getBallPosition(AVATAR_JOINT_HEAD_BASE)); - _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation()); + _myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation()); } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { _myCamera.setTargetPosition(_myAvatar.getHeadJointPosition()); - _myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation()); + _myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation()); } // Update camera position diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 44a8ef299d..b4459f52b3 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -314,10 +314,9 @@ glm::quat Head::getOrientation() const { glm::vec3(_pitch, -_yaw, -_roll) : glm::vec3(_pitch, _yaw, _roll))); } -glm::quat Head::getWorldAlignedOrientation () const { +glm::quat Head::getCameraOrientation () const { Avatar* owningAvatar = static_cast(_owningAvatar); - return owningAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(_lookingInMirror ? - glm::vec3(_pitch, -_yaw, -_roll) : glm::vec3(_pitch, _yaw, _roll))); + return owningAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(glm::vec3(_pitch, _yaw, 0.0f))); } void Head::renderHeadSphere() { diff --git a/interface/src/Head.h b/interface/src/Head.h index 66ce07d133..65f944205b 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -47,7 +47,7 @@ public: void setRenderLookatVectors(bool onOff ) { _renderLookatVectors = onOff; } glm::quat getOrientation() const; - glm::quat getWorldAlignedOrientation () const; + glm::quat getCameraOrientation () const; glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } glm::vec3 getUpDirection () const { return getOrientation() * IDENTITY_UP; } diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index 8c765544fd..b585e4b428 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -215,7 +215,7 @@ void SerialInterface::readData(float deltaTime) { // From MPU-9150 register map, with setting on // highest resolution = +/- 2G - _lastAcceleration = glm::vec3(-accelXRate, -accelYRate, -accelZRate) * LSB_TO_METERS_PER_SECOND2; + _lastAcceleration = glm::vec3(accelXRate, accelYRate, accelZRate) * LSB_TO_METERS_PER_SECOND2; int rollRate, yawRate, pitchRate; @@ -225,9 +225,9 @@ void SerialInterface::readData(float deltaTime) { // Convert the integer rates to floats const float LSB_TO_DEGREES_PER_SECOND = 1.f / 16.4f; // From MPU-9150 register map, 2000 deg/sec. - _lastRotationRates[0] = ((float) -pitchRate) * LSB_TO_DEGREES_PER_SECOND; - _lastRotationRates[1] = ((float) -yawRate) * LSB_TO_DEGREES_PER_SECOND; - _lastRotationRates[2] = ((float) -rollRate) * LSB_TO_DEGREES_PER_SECOND; + _lastRotationRates[0] = ((float) pitchRate) * LSB_TO_DEGREES_PER_SECOND; + _lastRotationRates[1] = ((float) yawRate) * LSB_TO_DEGREES_PER_SECOND; + _lastRotationRates[2] = ((float) rollRate) * LSB_TO_DEGREES_PER_SECOND; // Update raw rotation estimates glm::quat estimatedRotation = glm::quat(glm::radians(_estimatedRotation)) * @@ -264,7 +264,7 @@ void SerialInterface::readData(float deltaTime) { 1.0f / SENSOR_FUSION_SAMPLES); // Without a compass heading, always decay estimated Yaw slightly - const float YAW_DECAY = 0.995; + const float YAW_DECAY = 0.999f; glm::vec3 forward = estimatedRotation * glm::vec3(0.0f, 0.0f, -1.0f); estimatedRotation = safeMix(glm::angleAxis(glm::degrees(atan2f(forward.x, -forward.z)), glm::vec3(0.0f, 1.0f, 0.0f)) * estimatedRotation, estimatedRotation, YAW_DECAY); From e0e94481c9d9d221dedeb174686373ebb8b33f47 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 17:53:00 -0700 Subject: [PATCH 28/33] Add pitch/yaw scale preference to control degree of view rotation. --- interface/src/Application.cpp | 14 ++++++++++++-- interface/src/Application.h | 1 + interface/src/Head.cpp | 5 +++-- interface/src/Head.h | 2 +- interface/src/SerialInterface.cpp | 8 ++++---- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0480a4a087..970e5a77c8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -144,6 +145,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _viewFrustumOffsetUp(0.0), _audioScope(256, 200, true), _manualFirstPerson(false), + _headCameraPitchYawScale(0.0f), _mouseX(0), _mouseY(0), _mousePressed(false), @@ -311,11 +313,11 @@ void Application::paintGL() { } else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { _myCamera.setTightness(0.0f); // In first person, camera follows head exactly without delay _myCamera.setTargetPosition(_myAvatar.getBallPosition(AVATAR_JOINT_HEAD_BASE)); - _myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation()); + _myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(_headCameraPitchYawScale)); } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { _myCamera.setTargetPosition(_myAvatar.getHeadJointPosition()); - _myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation()); + _myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(_headCameraPitchYawScale)); } // Update camera position @@ -1026,6 +1028,10 @@ void Application::editPreferences() { avatarURL->setMinimumWidth(400); form->addRow("Avatar URL:", avatarURL); + QDoubleSpinBox* headCameraPitchYawScale = new QDoubleSpinBox(); + headCameraPitchYawScale->setValue(_headCameraPitchYawScale); + form->addRow("Head Camera Pitch/Yaw Scale:", headCameraPitchYawScale); + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject())); @@ -1038,6 +1044,8 @@ void Application::editPreferences() { _settings->setValue("avatarURL", url); _myAvatar.getVoxels()->setVoxelURL(url); sendAvatarVoxelURLMessage(url); + + _headCameraPitchYawScale = headCameraPitchYawScale->value(); } void Application::pair() { @@ -2538,6 +2546,7 @@ void Application::loadSettings(QSettings* set) { scanMenuBar(&Application::loadAction, set); getAvatar()->loadData(set); + _headCameraPitchYawScale = set->value("headCameraPitchYawScale").toFloat(); } void Application::saveSettings(QSettings* set) { @@ -2545,6 +2554,7 @@ void Application::saveSettings(QSettings* set) { scanMenuBar(&Application::saveAction, set); getAvatar()->saveData(set); + set->setValue("headCameraPitchYawScale", _headCameraPitchYawScale); } void Application::importSettings() { diff --git a/interface/src/Application.h b/interface/src/Application.h index 15fe56c8f8..63a32d35e7 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -248,6 +248,7 @@ private: int _headMouseX, _headMouseY; bool _manualFirstPerson; + float _headCameraPitchYawScale; HandControl _handControl; diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index b4459f52b3..d58c29f84d 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -314,9 +314,10 @@ glm::quat Head::getOrientation() const { glm::vec3(_pitch, -_yaw, -_roll) : glm::vec3(_pitch, _yaw, _roll))); } -glm::quat Head::getCameraOrientation () const { +glm::quat Head::getCameraOrientation (float pitchYawScale) const { Avatar* owningAvatar = static_cast(_owningAvatar); - return owningAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(glm::vec3(_pitch, _yaw, 0.0f))); + return owningAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(glm::vec3( + _pitch * pitchYawScale, _yaw * pitchYawScale, 0.0f))); } void Head::renderHeadSphere() { diff --git a/interface/src/Head.h b/interface/src/Head.h index 65f944205b..4150cbbc50 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -47,7 +47,7 @@ public: void setRenderLookatVectors(bool onOff ) { _renderLookatVectors = onOff; } glm::quat getOrientation() const; - glm::quat getCameraOrientation () const; + glm::quat getCameraOrientation (float pitchYawScale) const; glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } glm::vec3 getUpDirection () const { return getOrientation() * IDENTITY_UP; } diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index b585e4b428..28ae7eceb4 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -215,7 +215,7 @@ void SerialInterface::readData(float deltaTime) { // From MPU-9150 register map, with setting on // highest resolution = +/- 2G - _lastAcceleration = glm::vec3(accelXRate, accelYRate, accelZRate) * LSB_TO_METERS_PER_SECOND2; + _lastAcceleration = glm::vec3(-accelXRate, -accelYRate, -accelZRate) * LSB_TO_METERS_PER_SECOND2; int rollRate, yawRate, pitchRate; @@ -225,9 +225,9 @@ void SerialInterface::readData(float deltaTime) { // Convert the integer rates to floats const float LSB_TO_DEGREES_PER_SECOND = 1.f / 16.4f; // From MPU-9150 register map, 2000 deg/sec. - _lastRotationRates[0] = ((float) pitchRate) * LSB_TO_DEGREES_PER_SECOND; - _lastRotationRates[1] = ((float) yawRate) * LSB_TO_DEGREES_PER_SECOND; - _lastRotationRates[2] = ((float) rollRate) * LSB_TO_DEGREES_PER_SECOND; + _lastRotationRates[0] = ((float) -pitchRate) * LSB_TO_DEGREES_PER_SECOND; + _lastRotationRates[1] = ((float) -yawRate) * LSB_TO_DEGREES_PER_SECOND; + _lastRotationRates[2] = ((float) -rollRate) * LSB_TO_DEGREES_PER_SECOND; // Update raw rotation estimates glm::quat estimatedRotation = glm::quat(glm::radians(_estimatedRotation)) * From ce68c1a6a4f6e90440ad87dc7a8d4846d1d1e065 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 18:03:38 -0700 Subject: [PATCH 29/33] Think this needs to be a double. --- 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 970e5a77c8..b1b1ea826c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2546,7 +2546,7 @@ void Application::loadSettings(QSettings* set) { scanMenuBar(&Application::loadAction, set); getAvatar()->loadData(set); - _headCameraPitchYawScale = set->value("headCameraPitchYawScale").toFloat(); + _headCameraPitchYawScale = set->value("headCameraPitchYawScale").toDouble(); } void Application::saveSettings(QSettings* set) { From 1b698b24e2cf93eec6f6b69e8d2279f7a0dc24b0 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 18:05:39 -0700 Subject: [PATCH 30/33] OK, one more try. --- interface/src/Application.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b1b1ea826c..afbc6ae5f7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2544,17 +2544,17 @@ void Application::setAutosave(bool wantsAutosave) { void Application::loadSettings(QSettings* set) { if (!set) set = getSettings(); - scanMenuBar(&Application::loadAction, set); - getAvatar()->loadData(set); _headCameraPitchYawScale = set->value("headCameraPitchYawScale").toDouble(); + scanMenuBar(&Application::loadAction, set); + getAvatar()->loadData(set); } void Application::saveSettings(QSettings* set) { if (!set) set = getSettings(); - scanMenuBar(&Application::saveAction, set); - getAvatar()->saveData(set); set->setValue("headCameraPitchYawScale", _headCameraPitchYawScale); + scanMenuBar(&Application::saveAction, set); + getAvatar()->saveData(set); } void Application::importSettings() { From acc8efa026c53ae772a48153aa07d1164760df91 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 18:10:21 -0700 Subject: [PATCH 31/33] One more "one more try." --- interface/src/Application.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index afbc6ae5f7..ef2a44fa68 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -145,7 +145,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _viewFrustumOffsetUp(0.0), _audioScope(256, 200, true), _manualFirstPerson(false), - _headCameraPitchYawScale(0.0f), _mouseX(0), _mouseY(0), _mousePressed(false), @@ -2544,7 +2543,7 @@ void Application::setAutosave(bool wantsAutosave) { void Application::loadSettings(QSettings* set) { if (!set) set = getSettings(); - _headCameraPitchYawScale = set->value("headCameraPitchYawScale").toDouble(); + _headCameraPitchYawScale = set->value("headCameraPitchYawScale", 0.0f).toFloat(); scanMenuBar(&Application::loadAction, set); getAvatar()->loadData(set); } From 26de3028fa2403fa21c3b929e3cb09f96d233a0f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Jun 2013 18:25:16 -0700 Subject: [PATCH 32/33] We need to sync in order to ensure that the settings are saved. --- interface/src/Application.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ef2a44fa68..645717b8db 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2553,7 +2553,9 @@ void Application::saveSettings(QSettings* set) { set->setValue("headCameraPitchYawScale", _headCameraPitchYawScale); scanMenuBar(&Application::saveAction, set); - getAvatar()->saveData(set); + getAvatar()->saveData(set); + + set->sync(); } void Application::importSettings() { From 2a1730af72c68f8aee139d0b5a724c4d0cc1beab Mon Sep 17 00:00:00 2001 From: atlante45 Date: Fri, 7 Jun 2013 16:35:43 +0200 Subject: [PATCH 33/33] #19365 - Frustum menu moved inside the Debug menu --- interface/src/Application.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c85e8ecd96..74e7496077 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1454,7 +1454,9 @@ void Application::initMenu() { voxelMenu->addAction("Copy Voxels", this, SLOT(copyVoxels()), Qt::CTRL | Qt::Key_C); voxelMenu->addAction("Paste Voxels", this, SLOT(pasteVoxels()), Qt::CTRL | Qt::Key_V); - QMenu* frustumMenu = menuBar->addMenu("Frustum"); + QMenu* debugMenu = menuBar->addMenu("Debug"); + + QMenu* frustumMenu = debugMenu->addMenu("View Frustum..."); (_frustumOn = frustumMenu->addAction("Display Frustum"))->setCheckable(true); _frustumOn->setShortcut(Qt::SHIFT | Qt::Key_F); (_viewFrustumFromOffset = frustumMenu->addAction( @@ -1466,7 +1468,6 @@ void Application::initMenu() { "Render Mode", this, SLOT(cycleFrustumRenderMode()), Qt::SHIFT | Qt::Key_R); updateFrustumRenderModeAction(); - QMenu* debugMenu = menuBar->addMenu("Debug"); debugMenu->addAction("Show Render Pipeline Warnings", this, SLOT(setRenderWarnings(bool)))->setCheckable(true); debugMenu->addAction("Kill Local Voxels", this, SLOT(doKillLocalVoxels())); debugMenu->addAction("Randomize Voxel TRUE Colors", this, SLOT(doRandomizeVoxelColors()), Qt::CTRL | Qt::Key_R);