diff --git a/examples/gamepad.js b/examples/gamepad.js index b4c2758edd..a2f1034e26 100644 --- a/examples/gamepad.js +++ b/examples/gamepad.js @@ -20,7 +20,7 @@ var BUTTON_TURN_AROUND = Joysticks.BUTTON_RIGHT_STICK; var BUTTON_FLY_UP = Joysticks.BUTTON_RIGHT_SHOULDER; var BUTTON_FLY_DOWN = Joysticks.BUTTON_LEFT_SHOULDER; -var BUTTON_WARP = Joysticks.BUTTON_FACE_BOTTOM; +var BUTTON_WARP = Joysticks.BUTTON_FACE_RIGHT; var BUTTON_WARP_FORWARD = Joysticks.BUTTON_DPAD_UP; var BUTTON_WARP_BACKWARD = Joysticks.BUTTON_DPAD_DOWN; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9561115478..9c3eb48993 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4042,20 +4042,20 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser return scriptEngine; } -void Application::handleScriptEngineLoaded(const QUrl& scriptURL) { +void Application::handleScriptEngineLoaded(const QString& scriptFilename) { ScriptEngine* scriptEngine = qobject_cast(sender()); - _scriptEnginesHash.insertMulti(scriptURL.toString(), scriptEngine); + _scriptEnginesHash.insertMulti(scriptFilename, scriptEngine); _runningScriptsWidget->setRunningScripts(getRunningScripts()); - UserActivityLogger::getInstance().loadedScript(scriptURL.toString()); + UserActivityLogger::getInstance().loadedScript(scriptFilename); // register our application services and set it off on its own thread registerScriptEngineWithApplicationServices(scriptEngine); } -void Application::handleScriptLoadError(const QUrl& scriptURL) { +void Application::handleScriptLoadError(const QString& scriptFilename) { qDebug() << "Application::loadScript(), script failed to load..."; - QMessageBox::warning(getWindow(), "Error Loading Script", scriptURL.toString() + " failed to load."); + QMessageBox::warning(getWindow(), "Error Loading Script", scriptFilename + " failed to load."); } void Application::scriptFinished(const QString& scriptName) { diff --git a/interface/src/Application.h b/interface/src/Application.h index caaebea876..92ef00e8a5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -394,8 +394,8 @@ private slots: void idle(); void aboutToQuit(); - void handleScriptEngineLoaded(const QUrl& scriptURL); - void handleScriptLoadError(const QUrl& scriptURL); + void handleScriptEngineLoaded(const QString& scriptFilename); + void handleScriptLoadError(const QString& scriptFilename); void connectedToDomain(const QString& hostname); diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 167c44111e..2214bb54cf 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -1438,7 +1438,7 @@ void Audio::renderToolBox(int x, int y, bool boxed) { static const float PULSE_MAX = 1.0f; static const float PULSE_FREQUENCY = 1.0f; // in Hz qint64 now = usecTimestampNow(); - if (now - _iconPulseTimeReference > USECS_PER_SECOND) { + if (now - _iconPulseTimeReference > (qint64)USECS_PER_SECOND) { // Prevents t from getting too big, which would diminish glm::cos precision _iconPulseTimeReference = now - ((now - _iconPulseTimeReference) % USECS_PER_SECOND); } diff --git a/interface/src/Hair.cpp b/interface/src/Hair.cpp index e14fc519d3..cb664f39ed 100644 --- a/interface/src/Hair.cpp +++ b/interface/src/Hair.cpp @@ -18,8 +18,8 @@ const float HAIR_DAMPING = 0.99f; const float CONSTRAINT_RELAXATION = 10.0f; const float HAIR_ACCELERATION_COUPLING = 0.045f; -const float HAIR_ANGULAR_VELOCITY_COUPLING = 0.020f; -const float HAIR_ANGULAR_ACCELERATION_COUPLING = 0.003f; +const float HAIR_ANGULAR_VELOCITY_COUPLING = 0.001f; +const float HAIR_ANGULAR_ACCELERATION_COUPLING = 0.001f; const float HAIR_MAX_LINEAR_ACCELERATION = 4.0f; const float HAIR_STIFFNESS = 0.00f; const glm::vec3 HAIR_COLOR1(0.98f, 0.76f, 0.075f); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3301cf0347..9f3309ece2 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -68,8 +68,7 @@ const int SCRIPTED_MOTOR_WORLD_FRAME = 2; MyAvatar::MyAvatar() : Avatar(), _mousePressed(false), - _bodyPitchDelta(0.0f), - _bodyRollDelta(0.0f), + _turningKeyPressTime(0.0f), _gravity(0.0f, 0.0f, 0.0f), _distanceToNearestAvatar(std::numeric_limits::max()), _shouldJump(false), @@ -1169,26 +1168,41 @@ bool MyAvatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode rend void MyAvatar::updateOrientation(float deltaTime) { // Gather rotation information from keyboard - _bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_SPEED * deltaTime; - _bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_SPEED * deltaTime; + const float TIME_BETWEEN_HMD_TURNS = 0.5f; + const float HMD_TURN_DEGREES = 22.5f; + if (!OculusManager::isConnected()) { + // Smoothly rotate body with arrow keys if not in HMD + _bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_SPEED * deltaTime; + _bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_SPEED * deltaTime; + } else { + // Jump turns if in HMD + if (_driveKeys[ROT_RIGHT] || _driveKeys[ROT_LEFT]) { + if (_turningKeyPressTime == 0.0f) { + setOrientation(getOrientation() * + glm::quat(glm::radians(glm::vec3(0.f, _driveKeys[ROT_LEFT] ? HMD_TURN_DEGREES : -HMD_TURN_DEGREES, 0.0f)))); + } + _turningKeyPressTime += deltaTime; + if (_turningKeyPressTime > TIME_BETWEEN_HMD_TURNS) { + _turningKeyPressTime = 0.0f; + } + } else { + _turningKeyPressTime = 0.0f; + } + } getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime); - // update body yaw by body yaw delta - glm::quat orientation = getOrientation() * glm::quat(glm::radians( - glm::vec3(_bodyPitchDelta, _bodyYawDelta, _bodyRollDelta) * deltaTime)); + // update body orientation by movement inputs + setOrientation(getOrientation() * + glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta, 0.0f) * deltaTime))); // decay body rotation momentum const float BODY_SPIN_FRICTION = 7.5f; float bodySpinMomentum = 1.0f - BODY_SPIN_FRICTION * deltaTime; if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; } - _bodyPitchDelta *= bodySpinMomentum; _bodyYawDelta *= bodySpinMomentum; - _bodyRollDelta *= bodySpinMomentum; float MINIMUM_ROTATION_RATE = 2.0f; if (fabs(_bodyYawDelta) < MINIMUM_ROTATION_RATE) { _bodyYawDelta = 0.0f; } - if (fabs(_bodyRollDelta) < MINIMUM_ROTATION_RATE) { _bodyRollDelta = 0.0f; } - if (fabs(_bodyPitchDelta) < MINIMUM_ROTATION_RATE) { _bodyPitchDelta = 0.0f; } if (OculusManager::isConnected()) { // these angles will be in radians @@ -1201,8 +1215,11 @@ void MyAvatar::updateOrientation(float deltaTime) { // Record the angular velocity Head* head = getHead(); - glm::vec3 angularVelocity(yaw - head->getBaseYaw(), pitch - head->getBasePitch(), roll - head->getBaseRoll()); - head->setAngularVelocity(angularVelocity); + if (deltaTime > 0.0f) { + glm::vec3 angularVelocity(pitch - head->getBasePitch(), yaw - head->getBaseYaw(), roll - head->getBaseRoll()); + angularVelocity *= 1.0f / deltaTime; + head->setAngularVelocity(angularVelocity); + } //Invert yaw and roll when in mirror mode if (Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) { @@ -1217,8 +1234,6 @@ void MyAvatar::updateOrientation(float deltaTime) { } - // update the euler angles - setOrientation(orientation); } glm::vec3 MyAvatar::applyKeyboardMotor(float deltaTime, const glm::vec3& localVelocity, bool hasFloor) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index dd1178c7b5..37b93e2f04 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -204,8 +204,7 @@ protected: private: bool _mousePressed; - float _bodyPitchDelta; // degrees - float _bodyRollDelta; // degrees + float _turningKeyPressTime; glm::vec3 _gravity; float _distanceToNearestAvatar; // How close is the nearest avatar? diff --git a/interface/src/ui/MetavoxelEditor.cpp b/interface/src/ui/MetavoxelEditor.cpp index b6b43c4baf..349a73b9c7 100644 --- a/interface/src/ui/MetavoxelEditor.cpp +++ b/interface/src/ui/MetavoxelEditor.cpp @@ -884,7 +884,8 @@ void ImportHeightfieldTool::updateSpanner() { } HeightfieldBrushTool::HeightfieldBrushTool(MetavoxelEditor* editor, const QString& name) : - MetavoxelTool(editor, name, false) { + MetavoxelTool(editor, name, false), + _positionValid(false) { QWidget* widget = new QWidget(); widget->setLayout(_form = new QFormLayout()); @@ -911,8 +912,10 @@ void HeightfieldBrushTool::render() { float distance; if (!Application::getInstance()->getMetavoxels()->findFirstRayHeightfieldIntersection(origin, direction, distance)) { + _positionValid = false; return; } + _positionValid = true; Application::getInstance()->getMetavoxels()->renderHeightfieldCursor( _position = origin + distance * direction, _radius->value()); } @@ -924,7 +927,7 @@ bool HeightfieldBrushTool::eventFilter(QObject* watched, QEvent* event) { _radius->setValue(_radius->value() * glm::pow(2.0f, angle * ANGLE_SCALE)); return true; - } else if (event->type() == QEvent::MouseButtonPress) { + } else if (event->type() == QEvent::MouseButtonPress && _positionValid) { MetavoxelEditMessage message = { createEdit(static_cast(event)->button() == Qt::RightButton) }; Application::getInstance()->getMetavoxels()->applyEdit(message, true); return true; @@ -1103,7 +1106,8 @@ void VoxelMaterialSpannerTool::applyEdit(const AttributePointer& attribute, cons } VoxelBrushTool::VoxelBrushTool(MetavoxelEditor* editor, const QString& name) : - MetavoxelTool(editor, name, false, true) { + MetavoxelTool(editor, name, false, true), + _positionValid(false) { QWidget* widget = new QWidget(); widget->setLayout(_form = new QFormLayout()); @@ -1132,8 +1136,10 @@ void VoxelBrushTool::render() { if (!(Application::getInstance()->getMetavoxels()->findFirstRayHeightfieldIntersection( origin, direction, heightfieldDistance) | Application::getInstance()->getMetavoxels()->findFirstRayVoxelIntersection(origin, direction, voxelDistance))) { + _positionValid = false; return; } + _positionValid = true; Application::getInstance()->getMetavoxels()->renderVoxelCursor( _position = origin + qMin(heightfieldDistance, voxelDistance) * direction, _radius->value()); } @@ -1145,7 +1151,7 @@ bool VoxelBrushTool::eventFilter(QObject* watched, QEvent* event) { _radius->setValue(_radius->value() * glm::pow(2.0f, angle * ANGLE_SCALE)); return true; - } else if (event->type() == QEvent::MouseButtonPress) { + } else if (event->type() == QEvent::MouseButtonPress && _positionValid) { MetavoxelEditMessage message = { createEdit(static_cast(event)->button() == Qt::RightButton) }; Application::getInstance()->getMetavoxels()->applyEdit(message, true); return true; diff --git a/interface/src/ui/MetavoxelEditor.h b/interface/src/ui/MetavoxelEditor.h index cccb41ecfc..15e731e2ee 100644 --- a/interface/src/ui/MetavoxelEditor.h +++ b/interface/src/ui/MetavoxelEditor.h @@ -326,6 +326,7 @@ protected: QDoubleSpinBox* _radius; glm::vec3 _position; + bool _positionValid; }; /// Allows raising or lowering parts of the heightfield. @@ -456,6 +457,7 @@ protected: QDoubleSpinBox* _radius; glm::vec3 _position; + bool _positionValid; }; /// Allows texturing parts of the voxel field. diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index f041fb8569..d0a25f4f4a 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -461,10 +461,10 @@ void Stats::display( if (_metavoxelSendTotal > 0 || _metavoxelReceiveTotal > 0) { stringstream reliableStats; if (_metavoxelSendTotal > 0) { - reliableStats << "Upload: " << (_metavoxelSendProgress * 100 / _metavoxelSendTotal) << "% "; + reliableStats << "Upload: " << (_metavoxelSendProgress * 100LL / _metavoxelSendTotal) << "% "; } if (_metavoxelReceiveTotal > 0) { - reliableStats << "Download: " << (_metavoxelReceiveProgress * 100 / _metavoxelReceiveTotal) << "%"; + reliableStats << "Download: " << (_metavoxelReceiveProgress * 100LL / _metavoxelReceiveTotal) << "%"; } verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, scale, rotation, font, reliableStats.str().c_str(), color); diff --git a/interface/src/ui/TextRenderer.cpp b/interface/src/ui/TextRenderer.cpp index edc14dabf5..fce4c76c0d 100644 --- a/interface/src/ui/TextRenderer.cpp +++ b/interface/src/ui/TextRenderer.cpp @@ -29,7 +29,7 @@ // the width/height of the cached glyph textures -const int IMAGE_SIZE = 256; +const int IMAGE_SIZE = 512; static uint qHash(const TextRenderer::Properties& key, uint seed = 0) { // can be switched to qHash(key.font, seed) when we require Qt 5.3+ diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index 496839fdcd..e1b6327652 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -109,11 +109,11 @@ public: /// For loading resources, returns the number of bytes received. qint64 getBytesReceived() const { return _bytesReceived; } - /// For loading resources, returns the number of total bytes (or zero if unknown). + /// For loading resources, returns the number of total bytes (<= zero if unknown). qint64 getBytesTotal() const { return _bytesTotal; } /// For loading resources, returns the load progress. - float getProgress() const { return (_bytesTotal == 0) ? 0.0f : (float)_bytesReceived / _bytesTotal; } + float getProgress() const { return (_bytesTotal <= 0) ? 0.0f : (float)_bytesReceived / _bytesTotal; } /// Refreshes the resource. void refresh(); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 6cef69d23f..70c536e116 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -156,31 +156,30 @@ void ScriptEngine::loadURL(const QUrl& scriptURL) { if (_isRunning) { return; } - - QString scriptURLString = scriptURL.toString(); - _fileNameString = scriptURLString; + + _fileNameString = scriptURL.toString(); QUrl url(scriptURL); // if the scheme length is one or lower, maybe they typed in a file, let's try const int WINDOWS_DRIVE_LETTER_SIZE = 1; if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) { - url = QUrl::fromLocalFile(scriptURLString); + url = QUrl::fromLocalFile(_fileNameString); } // ok, let's see if it's valid... and if so, load it if (url.isValid()) { if (url.scheme() == "file") { - QString fileName = url.toLocalFile(); - QFile scriptFile(fileName); + _fileNameString = url.toLocalFile(); + QFile scriptFile(_fileNameString); if (scriptFile.open(QFile::ReadOnly | QFile::Text)) { - qDebug() << "Loading file:" << fileName; + qDebug() << "ScriptEngine loading file:" << _fileNameString; QTextStream in(&scriptFile); _scriptContents = in.readAll(); - emit scriptLoaded(url); + emit scriptLoaded(_fileNameString); } else { - qDebug() << "ERROR Loading file:" << fileName; - emit errorLoadingScript(url); + qDebug() << "ERROR Loading file:" << _fileNameString; + emit errorLoadingScript(_fileNameString); } } else { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); @@ -195,10 +194,10 @@ void ScriptEngine::handleScriptDownload() { if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) { _scriptContents = reply->readAll(); - emit scriptLoaded(reply->url()); + emit scriptLoaded(_fileNameString); } else { qDebug() << "ERROR Loading file:" << reply->url().toString(); - emit errorLoadingScript(reply->url()); + emit errorLoadingScript(_fileNameString); } } diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 4b6b3e48ab..fd28e98cab 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -107,8 +107,8 @@ public slots: void nodeKilled(SharedNodePointer node); signals: - void scriptLoaded(const QUrl& scriptURL); - void errorLoadingScript(const QUrl& scriptURL); + void scriptLoaded(const QString& scriptFilename); + void errorLoadingScript(const QString& scriptFilename); void update(float deltaTime); void scriptEnding(); void finished(const QString& fileNameString);