From d248e1e2c49d1c01e1999660b7d912d5379d9ab5 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 12 Nov 2014 23:03:26 -0800 Subject: [PATCH 01/10] Add reflect(direction, normal) to Vec3 scripting calls --- libraries/script-engine/src/Vec3.cpp | 3 +++ libraries/script-engine/src/Vec3.h | 1 + 2 files changed, 4 insertions(+) diff --git a/libraries/script-engine/src/Vec3.cpp b/libraries/script-engine/src/Vec3.cpp index bab63bbd4e..cb9ad045ff 100644 --- a/libraries/script-engine/src/Vec3.cpp +++ b/libraries/script-engine/src/Vec3.cpp @@ -15,6 +15,9 @@ #include "Vec3.h" +glm::vec3 Vec3::reflect(const glm::vec3& v1, const glm::vec3& v2) { + return glm::reflect(v1, v2); +} glm::vec3 Vec3::cross(const glm::vec3& v1, const glm::vec3& v2) { return glm::cross(v1,v2); } diff --git a/libraries/script-engine/src/Vec3.h b/libraries/script-engine/src/Vec3.h index 3f7d5476a2..2a2e145e8e 100644 --- a/libraries/script-engine/src/Vec3.h +++ b/libraries/script-engine/src/Vec3.h @@ -25,6 +25,7 @@ class Vec3 : public QObject { Q_OBJECT public slots: + glm::vec3 reflect(const glm::vec3& v1, const glm::vec3& v2); glm::vec3 cross(const glm::vec3& v1, const glm::vec3& v2); float dot(const glm::vec3& v1, const glm::vec3& v2); glm::vec3 multiply(const glm::vec3& v1, float f); From 1ccd47fd1d811b08f359fed67667606d41beb72e Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 13 Nov 2014 17:27:16 -0800 Subject: [PATCH 02/10] Fix drumstick script --- examples/drumStick.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/drumStick.js b/examples/drumStick.js index 463b653e5f..88ffa36c50 100644 --- a/examples/drumStick.js +++ b/examples/drumStick.js @@ -64,9 +64,7 @@ function checkSticks(deltaTime) { if ((palmVelocity.y > 0.0) || (speed < STOP_SPEED)) { state[palm] = 0; - var options = { - position: Controller.getSpatialControlPosition(palm * 2 + 1); - } + var options = { position: Controller.getSpatialControlPosition(palm * 2 + 1) }; if (strokeSpeed[palm] > 1.0) { strokeSpeed[palm] = 1.0; } options.volume = strokeSpeed[palm]; From e1ad9d3b4b1c730b8c39f3e1360f9d73f7381542 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 20 Nov 2014 17:26:11 -0600 Subject: [PATCH 03/10] Fix eyes jittering when turning away/toward someone --- interface/src/avatar/Avatar.h | 1 + interface/src/avatar/MyAvatar.cpp | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 376e229d0c..2d1a44403f 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -87,6 +87,7 @@ public: void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } void setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction); void setIsLookAtTarget(const bool isLookAtTarget) { _isLookAtTarget = isLookAtTarget; } + bool getIsLookAtTarget() const { return _isLookAtTarget; } //getters bool isInitialized() const { return _initialized; } SkeletonModel& getSkeletonModel() { return _skeletonModel; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8b5fefc3be..39c88ef642 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -930,14 +930,16 @@ void MyAvatar::updateLookAtTargetAvatar() { glm::vec3 lookForward = faceRotation * IDENTITY_FRONT; glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); float smallestAngleTo = glm::radians(Application::getInstance()->getCamera()->getFieldOfView()) / 2.f; + const float KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR = 1.3f; int howManyLookingAtMe = 0; foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) { Avatar* avatar = static_cast(avatarPointer.data()); + bool isCurrentTarget = avatar->getIsLookAtTarget(); avatar->setIsLookAtTarget(false); if (!avatar->isMyAvatar() && avatar->isInitialized()) { float angleTo = glm::angle(lookForward, glm::normalize(avatar->getHead()->getEyePosition() - cameraPosition)); - if (angleTo < smallestAngleTo) { + if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) { _lookAtTargetAvatar = avatarPointer; _targetAvatarPosition = avatarPointer->getPosition(); smallestAngleTo = angleTo; From d8a74a4db4240e54abc09c57d33358ffb74b7685 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 20 Nov 2014 18:34:06 -0600 Subject: [PATCH 04/10] add max distance at which you will auto-magically look at someone else --- examples/butterflies.js | 1 - interface/src/avatar/MyAvatar.cpp | 4 +++- interface/src/devices/Faceshift.cpp | 6 ++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/butterflies.js b/examples/butterflies.js index 27492b6f3e..8055e5b7d9 100644 --- a/examples/butterflies.js +++ b/examples/butterflies.js @@ -107,7 +107,6 @@ function addButterfly() { animationIsPlaying: true, modelURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/models/content/butterfly/butterfly.fbx" }; - //properties.position.z = properties.position.z + 1; butterflies.push(new defineButterfly(Entities.addEntity(properties), properties.position)); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ab5e7bc6ff..3cbe2ac8ae 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -932,13 +932,15 @@ void MyAvatar::updateLookAtTargetAvatar() { float smallestAngleTo = glm::radians(Application::getInstance()->getCamera()->getFieldOfView()) / 2.0f; const float KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR = 1.3f; + const float GREATEST_LOOKING_AT_DISTANCE = 10.0f; int howManyLookingAtMe = 0; foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) { Avatar* avatar = static_cast(avatarPointer.data()); bool isCurrentTarget = avatar->getIsLookAtTarget(); + float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition); avatar->setIsLookAtTarget(false); - if (!avatar->isMyAvatar() && avatar->isInitialized()) { + if (!avatar->isMyAvatar() && avatar->isInitialized() && (distanceTo < GREATEST_LOOKING_AT_DISTANCE * getScale())) { float angleTo = glm::angle(lookForward, glm::normalize(avatar->getHead()->getEyePosition() - cameraPosition)); if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) { _lookAtTargetAvatar = avatarPointer; diff --git a/interface/src/devices/Faceshift.cpp b/interface/src/devices/Faceshift.cpp index 663c570ffc..fb74f416a9 100644 --- a/interface/src/devices/Faceshift.cpp +++ b/interface/src/devices/Faceshift.cpp @@ -109,10 +109,8 @@ void Faceshift::update() { _longTermAverageEyePitch = glm::mix(eulers.x, _longTermAverageEyePitch, LONG_TERM_AVERAGE_SMOOTHING); _longTermAverageEyeYaw = glm::mix(eulers.y, _longTermAverageEyeYaw, LONG_TERM_AVERAGE_SMOOTHING); } - //_estimatedEyePitch = eulers.x - _longTermAverageEyePitch; - //_estimatedEyeYaw = eulers.y - _longTermAverageEyeYaw; - _estimatedEyePitch = 0.0; // eulers.x; - _estimatedEyeYaw = 0.0; // eulers.y; + _estimatedEyePitch = eulers.x - _longTermAverageEyePitch; + _estimatedEyeYaw = eulers.y - _longTermAverageEyeYaw; } void Faceshift::reset() { From 6e89437bce8f3a3ce9d286da8a8e17912dfa5725 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 20 Nov 2014 19:34:56 -0600 Subject: [PATCH 05/10] simplify audio scope menu(s) --- interface/src/Menu.cpp | 7 +++---- interface/src/Menu.h | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 1eacfa8363..ff34c0200c 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -625,17 +625,16 @@ Menu::Menu() : audioSourceGroup->addAction(sine440); } - addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioScope, + QMenu* audioScopeMenu = audioDebugMenu->addMenu("Audio Scope"); + addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScope, Qt::CTRL | Qt::Key_P, false, appInstance->getAudio(), SLOT(toggleScope())); - addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioScopePause, + addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopePause, Qt::CTRL | Qt::SHIFT | Qt::Key_P , false, appInstance->getAudio(), SLOT(toggleScopePause())); - - QMenu* audioScopeMenu = audioDebugMenu->addMenu("Audio Scope"); addDisabledActionAndSeparator(audioScopeMenu, "Display Frames"); { QAction *fiveFrames = addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopeFiveFrames, diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 7ed8811b4f..2f5ccc533c 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -338,11 +338,11 @@ namespace MenuOption { const QString AudioFilterBassCut = "Bass Cut"; const QString AudioFilterSmiley = "Smiley Curve"; const QString AudioNoiseReduction = "Audio Noise Reduction"; - const QString AudioScope = "Audio Scope"; + const QString AudioScope = "Show Scope"; const QString AudioScopeFiftyFrames = "Fifty"; const QString AudioScopeFiveFrames = "Five"; const QString AudioScopeFrames = "Display Frames"; - const QString AudioScopePause = "Pause Audio Scope"; + const QString AudioScopePause = "Pause Scope"; const QString AudioScopeTwentyFrames = "Twenty"; const QString AudioStats = "Audio Stats"; const QString AudioStatsShowInjectedStreams = "Audio Stats Show Injected Streams"; From e07f53d022e9889e17bd40aa5df4251a86da3641 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 20 Nov 2014 19:57:24 -0600 Subject: [PATCH 06/10] remove unused test audio filters --- interface/src/Audio.cpp | 35 +---------------------------------- interface/src/Audio.h | 10 ---------- interface/src/Menu.cpp | 41 ----------------------------------------- interface/src/Menu.h | 5 ----- 4 files changed, 1 insertion(+), 90 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index af11b4922c..75b8c252f7 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -115,7 +115,6 @@ Audio::Audio(QObject* parent) : _samplesPerScope(NETWORK_SAMPLES_PER_FRAME * _framesPerScope), _noiseSourceEnabled(false), _toneSourceEnabled(true), - _peqEnabled(false), _scopeInput(0), _scopeOutputLeft(0), _scopeOutputRight(0), @@ -153,7 +152,6 @@ void Audio::init(QGLWidget *parent) { void Audio::reset() { _receivedAudioStream.reset(); resetStats(); - _peq.reset(); _noiseSource.reset(); _toneSource.reset(); _sourceGain.reset(); @@ -457,7 +455,6 @@ void Audio::start() { } _inputFrameBuffer.initialize( _inputFormat.channelCount(), _audioInput->bufferSize() * 8 ); - _peq.initialize( _inputFormat.sampleRate() ); _inputGain.initialize(); _sourceGain.initialize(); _noiseSource.initialize(); @@ -469,7 +466,6 @@ void Audio::start() { void Audio::stop() { _inputFrameBuffer.finalize(); - _peq.finalize(); _inputGain.finalize(); _sourceGain.finalize(); _noiseSource.finalize(); @@ -664,7 +660,7 @@ void Audio::handleAudioInput() { QByteArray inputByteArray = _inputDevice->readAll(); - if (!_muted && (_audioSourceInjectEnabled || _peqEnabled)) { + if (!_muted && _audioSourceInjectEnabled) { int16_t* inputFrameData = (int16_t*)inputByteArray.data(); const uint32_t inputFrameCount = inputByteArray.size() / sizeof(int16_t); @@ -685,10 +681,6 @@ void Audio::handleAudioInput() { } _sourceGain.render(_inputFrameBuffer); // post gain } - if (_peqEnabled) { - _peq.render(_inputFrameBuffer); // 3-band parametric eq - } - _inputFrameBuffer.copyFrames(1, inputFrameCount, inputFrameData, true /*copy out*/); } @@ -1473,31 +1465,6 @@ void Audio::renderToolBox(int x, int y, bool boxed) { glDisable(GL_TEXTURE_2D); } -void Audio::toggleAudioFilter() { - _peqEnabled = !_peqEnabled; -} - -void Audio::selectAudioFilterFlat() { - if (Menu::getInstance()->isOptionChecked(MenuOption::AudioFilterFlat)) { - _peq.loadProfile(0); - } -} -void Audio::selectAudioFilterTrebleCut() { - if (Menu::getInstance()->isOptionChecked(MenuOption::AudioFilterTrebleCut)) { - _peq.loadProfile(1); - } -} -void Audio::selectAudioFilterBassCut() { - if (Menu::getInstance()->isOptionChecked(MenuOption::AudioFilterBassCut)) { - _peq.loadProfile(2); - } -} -void Audio::selectAudioFilterSmiley() { - if (Menu::getInstance()->isOptionChecked(MenuOption::AudioFilterSmiley)) { - _peq.loadProfile(3); - } -} - void Audio::toggleScope() { _scopeEnabled = !_scopeEnabled; if (_scopeEnabled) { diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 65db32b723..0f92dc7258 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -26,8 +26,6 @@ #include "AudioSourceTone.h" #include "AudioSourceNoise.h" #include "AudioGain.h" -#include "AudioFilter.h" -#include "AudioFilterBank.h" #include #include @@ -149,11 +147,6 @@ public slots: void addLastFrameRepeatedWithFadeToScope(int samplesPerChannel); void addStereoSamplesToScope(const QByteArray& samples); void processReceivedSamples(const QByteArray& inputBuffer, QByteArray& outputBuffer); - void toggleAudioFilter(); - void selectAudioFilterFlat(); - void selectAudioFilterTrebleCut(); - void selectAudioFilterBassCut(); - void selectAudioFilterSmiley(); virtual bool outputLocalInjector(bool isStereo, qreal volume, AudioInjector* injector); @@ -332,9 +325,6 @@ private: bool _toneSourceEnabled; AudioSourceTone _toneSource; - // Multi-band parametric EQ - bool _peqEnabled; - AudioFilterPEQ3m _peq; QMutex _guard; QByteArray* _scopeInput; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ff34c0200c..8cc075fed1 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -545,47 +545,6 @@ Menu::Menu() : appInstance->getAudio(), SLOT(toggleAudioNoiseReduction())); - addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioFilter, - 0, - false, - appInstance->getAudio(), - SLOT(toggleAudioFilter())); - - QMenu* audioFilterMenu = audioDebugMenu->addMenu("Audio Filter"); - addDisabledActionAndSeparator(audioFilterMenu, "Filter Response"); - { - QAction *flat = addCheckableActionToQMenuAndActionHash(audioFilterMenu, MenuOption::AudioFilterFlat, - 0, - true, - appInstance->getAudio(), - SLOT(selectAudioFilterFlat())); - - QAction *trebleCut = addCheckableActionToQMenuAndActionHash(audioFilterMenu, MenuOption::AudioFilterTrebleCut, - 0, - false, - appInstance->getAudio(), - SLOT(selectAudioFilterTrebleCut())); - - QAction *bassCut = addCheckableActionToQMenuAndActionHash(audioFilterMenu, MenuOption::AudioFilterBassCut, - 0, - false, - appInstance->getAudio(), - SLOT(selectAudioFilterBassCut())); - - QAction *smiley = addCheckableActionToQMenuAndActionHash(audioFilterMenu, MenuOption::AudioFilterSmiley, - 0, - false, - appInstance->getAudio(), - SLOT(selectAudioFilterSmiley())); - - - QActionGroup* audioFilterGroup = new QActionGroup(audioFilterMenu); - audioFilterGroup->addAction(flat); - audioFilterGroup->addAction(trebleCut); - audioFilterGroup->addAction(bassCut); - audioFilterGroup->addAction(smiley); - } - addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::StereoAudio, 0, false, diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 2f5ccc533c..17b29996a8 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -332,11 +332,6 @@ namespace MenuOption { const QString Animations = "Animations..."; const QString Atmosphere = "Atmosphere"; const QString Attachments = "Attachments..."; - const QString AudioFilter = "Audio Filter Bank"; - const QString AudioFilterFlat = "Flat Response"; - const QString AudioFilterTrebleCut= "Treble Cut"; - const QString AudioFilterBassCut = "Bass Cut"; - const QString AudioFilterSmiley = "Smiley Curve"; const QString AudioNoiseReduction = "Audio Noise Reduction"; const QString AudioScope = "Show Scope"; const QString AudioScopeFiftyFrames = "Fifty"; From 069f1be89d870c0011ae05a31db3457e019bd76b Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 20 Nov 2014 22:48:03 -0600 Subject: [PATCH 07/10] jump with number keys to preset places --- examples/hotPlaces.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 examples/hotPlaces.js diff --git a/examples/hotPlaces.js b/examples/hotPlaces.js new file mode 100644 index 0000000000..e674edde4b --- /dev/null +++ b/examples/hotPlaces.js @@ -0,0 +1,29 @@ +// +// hotPlaces.js +// +// Press the number keys to jump to different places in the metaverse! +// +// Created by Philip Rosedale on November 20, 2014 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + + +function keyPressEvent(event) { + // if our tools are off, then don't do anything + if (event.text == "1") { + Window.location = "hifi://starchamber"; + } else if (event.text == "2") { + Window.location = "hifi://apartment"; + } else if (event.text == "3") { + Window.location = "hifi://rivenglen"; + } else if (event.text == "4") { + Window.location = "hifi://sanfrancisco"; + } else if (event.text == "5") { + Window.location = "hifi://porto"; + } else if (event.text == "6") { + Window.location = "hifi://hoo"; + } +} +Controller.keyPressEvent.connect(keyPressEvent); \ No newline at end of file From 5d6d9ae0df8779b4f49a1cbc6bfcc07c6d7aa308 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 20 Nov 2014 22:53:49 -0600 Subject: [PATCH 08/10] cleaner version --- examples/hotPlaces.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/hotPlaces.js b/examples/hotPlaces.js index e674edde4b..cb826837ae 100644 --- a/examples/hotPlaces.js +++ b/examples/hotPlaces.js @@ -10,8 +10,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -function keyPressEvent(event) { - // if our tools are off, then don't do anything +Controller.keyPressEvent.connect(function (event) { if (event.text == "1") { Window.location = "hifi://starchamber"; } else if (event.text == "2") { @@ -25,5 +24,4 @@ function keyPressEvent(event) { } else if (event.text == "6") { Window.location = "hifi://hoo"; } -} -Controller.keyPressEvent.connect(keyPressEvent); \ No newline at end of file +}); From 9e32b2c64eeae6c9028a0c40e14416ccaccab43d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 20 Nov 2014 20:58:31 -0800 Subject: [PATCH 09/10] Suppress Windows C4305 compiler warnings in gverb includes --- interface/src/Audio.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 0f92dc7258..166042878c 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -45,10 +45,17 @@ #include #include +#ifdef _WIN32 +#pragma warning( push ) +#pragma warning( disable : 4305 ) +#endif extern "C" { #include #include } +#ifdef _WIN32 +#pragma warning( pop ) +#endif static const int NUM_AUDIO_CHANNELS = 2; From 85419a3e2d44aa72aa54a4a310ece72a53be45f0 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 21 Nov 2014 01:04:52 -0600 Subject: [PATCH 10/10] limit max distance of movement, don't pull to 3P unless going back --- examples/headMove.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/headMove.js b/examples/headMove.js index 56f42984e4..df5c858b46 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -89,6 +89,7 @@ var WARP_SMOOTHING = 0.90; var WARP_START_TIME = 0.25; var WARP_START_DISTANCE = 2.5; var WARP_SENSITIVITY = 0.15; +var MAX_WARP_DISTANCE = 25.0; var fixedHeight = true; @@ -105,7 +106,7 @@ function updateWarp() { willMove = (keyDownTime > WARP_START_TIME); if (willMove) { - var distance = Math.exp(deltaPitch * WARP_SENSITIVITY) * WARP_START_DISTANCE; + var distance = Math.min(Math.exp(deltaPitch * WARP_SENSITIVITY) * WARP_START_DISTANCE, MAX_WARP_DISTANCE); var warpDirection = Vec3.normalize({ x: look.x, y: (fixedHeight ? 0 : look.y), z: look.z }); var startPosition = (watchAvatar ? Camera.getPosition(): MyAvatar.getEyePosition()); warpPosition = Vec3.mix(Vec3.sum(startPosition, Vec3.multiply(warpDirection, distance)), warpPosition, WARP_SMOOTHING); @@ -113,7 +114,7 @@ function updateWarp() { var cameraPosition; - if (!watchAvatar && willMove) { + if (!watchAvatar && willMove && (distance < WARP_START_DISTANCE * 0.5)) { pullBack(); watchAvatar = true; }