mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 01:00:44 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into newEditGrab
This commit is contained in:
commit
c722b4b04d
31 changed files with 417 additions and 104 deletions
21
interface/resources/icons/tablet-icons/EmoteAppIcon.svg
Normal file
21
interface/resources/icons/tablet-icons/EmoteAppIcon.svg
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 22.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 100 100.8" style="enable-background:new 0 0 100 100.8;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<path class="st0" d="M26.7,83.9c7.3,1.2,14.8,1.8,22.1,1.8c0.4,0,0.8,0,1.2,0c7.8-0.1,15.6-0.8,23.4-2.2l0,0
|
||||||
|
c5.7-1.1,11.3-6.6,12.5-12.3C87.3,64.2,88,57,88,50s-0.7-14.2-2.1-21.2c-1.2-5.6-6.8-11.1-12.5-12.2c-7.7-1.4-15.6-2.2-23.4-2.2
|
||||||
|
c-7.7-0.1-15.6,0.5-23.4,1.8c-5.7,1-11.4,6.5-12.6,12.3c-1.4,7.2-2.1,14.4-2.1,21.6s0.7,14.4,2.1,21.7
|
||||||
|
C15.3,77.4,20.9,82.9,26.7,83.9z M20.9,29.8c0.6-2.9,4-6.3,6.9-6.8c7-1.1,14-1.7,21-1.7c0.4,0,0.8,0,1.2,0
|
||||||
|
c7.4,0.1,14.8,0.8,22.1,2.1c2.9,0.6,6.4,3.9,6.9,6.7c1.3,6.6,1.9,13.3,1.9,19.9c0,6.6-0.6,13.3-1.9,19.8c-0.6,2.8-4,6.2-6.9,6.8
|
||||||
|
c-7.3,1.3-14.8,2.1-22.1,2.1c-7.4,0.1-14.8-0.5-22.1-1.7c-2.9-0.5-6.3-3.9-6.9-6.7c-1.3-6.7-2-13.5-2-20.3
|
||||||
|
C19,43.3,19.6,36.4,20.9,29.8z"/>
|
||||||
|
<path class="st0" d="M32.3,61.4c-0.5,1.3-0.1,2.8,0.9,3.8c0.3,0.3,7.2,6.6,15.9,6.6c0.8,0,1.7-0.1,2.6-0.2
|
||||||
|
c9.8-1.5,15.5-11.1,15.8-11.5c0.7-1.2,0.6-2.8-0.2-3.9c-0.9-1.1-2.3-1.6-3.7-1.3c-9.2,2.5-18.6,3.9-28.1,4.2
|
||||||
|
C34,59.1,32.8,60,32.3,61.4z"/>
|
||||||
|
<circle class="st0" cx="36.5" cy="42.8" r="9"/>
|
||||||
|
<path class="st0" d="M61.4,44.1h6.1c1.9,0,3.3-1.5,3.3-3.3c0-1.9-1.5-3.3-3.3-3.3h-6.1c-1.9,0-3.3,1.5-3.3,3.3
|
||||||
|
C58.1,42.7,59.6,44.1,61.4,44.1z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
BIN
interface/resources/images/preview-privacy.png
Normal file
BIN
interface/resources/images/preview-privacy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
|
@ -209,6 +209,7 @@
|
||||||
#include "commerce/QmlCommerce.h"
|
#include "commerce/QmlCommerce.h"
|
||||||
|
|
||||||
#include "webbrowser/WebBrowserSuggestionsEngine.h"
|
#include "webbrowser/WebBrowserSuggestionsEngine.h"
|
||||||
|
#include <DesktopPreviewProvider.h>
|
||||||
|
|
||||||
// On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
// On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||||
// FIXME seems to be broken.
|
// FIXME seems to be broken.
|
||||||
|
@ -631,6 +632,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
||||||
DependencyManager::set<PointerScriptingInterface>();
|
DependencyManager::set<PointerScriptingInterface>();
|
||||||
DependencyManager::set<PickScriptingInterface>();
|
DependencyManager::set<PickScriptingInterface>();
|
||||||
DependencyManager::set<Cursor::Manager>();
|
DependencyManager::set<Cursor::Manager>();
|
||||||
|
DependencyManager::set<DesktopPreviewProvider>();
|
||||||
DependencyManager::set<AccountManager>(std::bind(&Application::getUserAgent, qApp));
|
DependencyManager::set<AccountManager>(std::bind(&Application::getUserAgent, qApp));
|
||||||
DependencyManager::set<StatTracker>();
|
DependencyManager::set<StatTracker>();
|
||||||
DependencyManager::set<ScriptEngines>(ScriptEngine::CLIENT_SCRIPT);
|
DependencyManager::set<ScriptEngines>(ScriptEngine::CLIENT_SCRIPT);
|
||||||
|
@ -5763,6 +5765,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
||||||
scriptEngine->registerFunction("OverlayWindow", QmlWindowClass::constructor);
|
scriptEngine->registerFunction("OverlayWindow", QmlWindowClass::constructor);
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance());
|
scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance());
|
||||||
|
scriptEngine->registerGlobalObject("DesktopPreviewProvider", DependencyManager::get<DesktopPreviewProvider>().data());
|
||||||
scriptEngine->registerGlobalObject("Stats", Stats::getInstance());
|
scriptEngine->registerGlobalObject("Stats", Stats::getInstance());
|
||||||
scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance());
|
scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance());
|
||||||
scriptEngine->registerGlobalObject("Snapshot", DependencyManager::get<Snapshot>().data());
|
scriptEngine->registerGlobalObject("Snapshot", DependencyManager::get<Snapshot>().data());
|
||||||
|
|
|
@ -175,4 +175,8 @@ QVariantMap PointerScriptingInterface::getPrevPickResult(unsigned int uid) const
|
||||||
result = pickResult->toVariantMap();
|
result = pickResult->toVariantMap();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PointerScriptingInterface::setDoesHover(unsigned int uid, bool hover) const {
|
||||||
|
DependencyManager::get<PointerManager>()->setDoesHover(uid, hover);
|
||||||
|
}
|
||||||
|
|
|
@ -202,6 +202,14 @@ public:
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const { DependencyManager::get<PointerManager>()->setLockEndUUID(uid, objectID, isOverlay, offsetMat); }
|
Q_INVOKABLE void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const { DependencyManager::get<PointerManager>()->setLockEndUUID(uid, objectID, isOverlay, offsetMat); }
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Sets whether or not a pointer should generate hover events.
|
||||||
|
* @function Pointers.setDoesHover
|
||||||
|
* @param {boolean} uid - The ID of the Pointer, as returned by {@link Pointers.createPointer}.
|
||||||
|
* @param {boolean} hover - If <code>true</code> then the pointer generates hover events, otherwise it does not.
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void setDoesHover(unsigned int uid, bool hove) const;
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Check if a Pointer is associated with the left hand.
|
* Check if a Pointer is associated with the left hand.
|
||||||
* @function Pointers.isLeftHand
|
* @function Pointers.isLeftHand
|
||||||
|
|
|
@ -277,7 +277,8 @@ void WindowScriptingInterface::browseAsync(const QString& title, const QString&
|
||||||
if (!result.isEmpty()) {
|
if (!result.isEmpty()) {
|
||||||
setPreviousBrowseLocation(QFileInfo(result).absolutePath());
|
setPreviousBrowseLocation(QFileInfo(result).absolutePath());
|
||||||
}
|
}
|
||||||
emit openFileChanged(result);
|
emit browseChanged(result);
|
||||||
|
emit openFileChanged(result); // Deprecated signal; to be removed in due course.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,18 +197,19 @@ public slots:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Prompt the user to choose a file. Displays a non-modal dialog that navigates the directory tree. A
|
* Prompt the user to choose a file. Displays a non-modal dialog that navigates the directory tree. A
|
||||||
* {@link Window.openFileChanged|openFileChanged} signal is emitted when a file is chosen; no signal is emitted if the user
|
* {@link Window.browseChanged|browseChanged} signal is emitted when a file is chosen; no signal is emitted if the user
|
||||||
* cancels the dialog.
|
* cancels the dialog.
|
||||||
|
* @deprecated A deprecated {@link Window.openFileChanged|openFileChanged} signal is also emitted when a file is chosen.
|
||||||
* @function Window.browseAsync
|
* @function Window.browseAsync
|
||||||
* @param {string} title="" - The title to display at the top of the dialog.
|
* @param {string} title="" - The title to display at the top of the dialog.
|
||||||
* @param {string} directory="" - The initial directory to start browsing at.
|
* @param {string} directory="" - The initial directory to start browsing at.
|
||||||
* @param {string} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and
|
* @param {string} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and
|
||||||
* <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified.
|
* <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified.
|
||||||
* @example <caption>Ask the user to choose an image file without waiting for the answer.</caption>
|
* @example <caption>Ask the user to choose an image file without waiting for the answer.</caption>
|
||||||
* function onOpenFileChanged(filename) {
|
* function onBrowseChanged(filename) {
|
||||||
* print("File: " + filename);
|
* print("File: " + filename);
|
||||||
* }
|
* }
|
||||||
* Window.openFileChanged.connect(onOpenFileChanged);
|
* Window.browseChanged.connect(onBrowseChanged);
|
||||||
*
|
*
|
||||||
* Window.browseAsync("Select Image File", Paths.resources, "Images (*.png *.jpg *.svg)");
|
* Window.browseAsync("Select Image File", Paths.resources, "Images (*.png *.jpg *.svg)");
|
||||||
* print("Script continues without waiting");
|
* print("Script continues without waiting");
|
||||||
|
@ -659,9 +660,18 @@ signals:
|
||||||
*/
|
*/
|
||||||
void saveFileChanged(QString filename);
|
void saveFileChanged(QString filename);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Triggered when the user chooses a file in a {@link Window.browseAsync|browseAsync} dialog.
|
||||||
|
* @function Window.browseChanged
|
||||||
|
* @param {string} filename - The path and name of the file the user chose in the dialog.
|
||||||
|
* @returns {Signal}
|
||||||
|
*/
|
||||||
|
void browseChanged(QString filename);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Triggered when the user chooses a file in a {@link Window.browseAsync|browseAsync} dialog.
|
* Triggered when the user chooses a file in a {@link Window.browseAsync|browseAsync} dialog.
|
||||||
* @function Window.openFileChanged
|
* @function Window.openFileChanged
|
||||||
|
* @deprecated This signal is being replaced with {@link Window.browseChanged|browseChanged} and will be removed.
|
||||||
* @param {string} filename - The path and name of the file the user chose in the dialog.
|
* @param {string} filename - The path and name of the file the user chose in the dialog.
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "../Logging.h"
|
#include "../Logging.h"
|
||||||
#include "../CompositorHelper.h"
|
#include "../CompositorHelper.h"
|
||||||
|
|
||||||
|
#include "DesktopPreviewProvider.h"
|
||||||
#include "render-utils/hmd_ui_vert.h"
|
#include "render-utils/hmd_ui_vert.h"
|
||||||
#include "render-utils/hmd_ui_frag.h"
|
#include "render-utils/hmd_ui_frag.h"
|
||||||
|
|
||||||
|
@ -254,17 +255,9 @@ void HmdDisplayPlugin::internalPresent() {
|
||||||
swapBuffers();
|
swapBuffers();
|
||||||
|
|
||||||
} else if (_clearPreviewFlag) {
|
} else if (_clearPreviewFlag) {
|
||||||
QImage image;
|
|
||||||
if (_vsyncEnabled) {
|
|
||||||
image = QImage(PathUtils::resourcesPath() + "images/preview.png");
|
|
||||||
} else {
|
|
||||||
image = QImage(PathUtils::resourcesPath() + "images/preview-disabled.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
image = image.mirrored();
|
QImage image = DesktopPreviewProvider::getInstance()->getPreviewDisabledImage(_vsyncEnabled);
|
||||||
image = image.convertToFormat(QImage::Format_RGBA8888);
|
_previewTexture = gpu::Texture::createStrict(
|
||||||
if (!_previewTexture) {
|
|
||||||
_previewTexture = gpu::Texture::createStrict(
|
|
||||||
gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA),
|
gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA),
|
||||||
image.width(), image.height(),
|
image.width(), image.height(),
|
||||||
gpu::Texture::MAX_NUM_MIPS,
|
gpu::Texture::MAX_NUM_MIPS,
|
||||||
|
@ -274,7 +267,6 @@ void HmdDisplayPlugin::internalPresent() {
|
||||||
_previewTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
_previewTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||||
_previewTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
_previewTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||||
_previewTexture->setAutoGenerateMips(true);
|
_previewTexture->setAutoGenerateMips(true);
|
||||||
}
|
|
||||||
|
|
||||||
auto viewport = getViewportForSourceSize(uvec2(_previewTexture->getDimensions()));
|
auto viewport = getViewportForSourceSize(uvec2(_previewTexture->getDimensions()));
|
||||||
|
|
||||||
|
|
|
@ -1394,8 +1394,14 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
// That is where _currentFrame and _lastAnimated were updated.
|
// That is where _currentFrame and _lastAnimated were updated.
|
||||||
if (_animating) {
|
if (_animating) {
|
||||||
DETAILED_PROFILE_RANGE(simulation_physics, "Animate");
|
DETAILED_PROFILE_RANGE(simulation_physics, "Animate");
|
||||||
|
|
||||||
if (!jointsMapped()) {
|
if (!jointsMapped()) {
|
||||||
mapJoints(entity, model->getJointNames());
|
mapJoints(entity, model->getJointNames());
|
||||||
|
//else the joint have been mapped before but we have a new animation to load
|
||||||
|
} else if (_animation && (_animation->getURL().toString() != entity->getAnimationURL())) {
|
||||||
|
_animation = DependencyManager::get<AnimationCache>()->getAnimation(entity->getAnimationURL());
|
||||||
|
_jointMappingCompleted = false;
|
||||||
|
mapJoints(entity, model->getJointNames());
|
||||||
}
|
}
|
||||||
if (!(entity->getAnimationFirstFrame() < 0) && !(entity->getAnimationFirstFrame() > entity->getAnimationLastFrame())) {
|
if (!(entity->getAnimationFirstFrame() < 0) && !(entity->getAnimationFirstFrame() > entity->getAnimationLastFrame())) {
|
||||||
animate(entity);
|
animate(entity);
|
||||||
|
|
|
@ -368,6 +368,7 @@ public:
|
||||||
void* getPhysicsInfo() const { return _physicsInfo; }
|
void* getPhysicsInfo() const { return _physicsInfo; }
|
||||||
|
|
||||||
void setPhysicsInfo(void* data) { _physicsInfo = data; }
|
void setPhysicsInfo(void* data) { _physicsInfo = data; }
|
||||||
|
|
||||||
EntityTreeElementPointer getElement() const { return _element; }
|
EntityTreeElementPointer getElement() const { return _element; }
|
||||||
EntityTreePointer getTree() const;
|
EntityTreePointer getTree() const;
|
||||||
virtual SpatialParentTree* getParentTree() const override;
|
virtual SpatialParentTree* getParentTree() const override;
|
||||||
|
|
|
@ -256,25 +256,32 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
|
||||||
assert(_entity);
|
assert(_entity);
|
||||||
assert(entityTreeIsLocked());
|
assert(entityTreeIsLocked());
|
||||||
measureBodyAcceleration();
|
measureBodyAcceleration();
|
||||||
bool positionSuccess;
|
|
||||||
_entity->setWorldPosition(bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset(), positionSuccess, false);
|
// If transform or velocities are flagged as dirty it means a network or scripted change
|
||||||
if (!positionSuccess) {
|
// occured between the beginning and end of the stepSimulation() and we DON'T want to apply
|
||||||
static QString repeatedMessage =
|
// these physics simulation results.
|
||||||
LogHandler::getInstance().addRepeatedMessageRegex("EntityMotionState::setWorldTransform "
|
uint32_t flags = _entity->getDirtyFlags() & (Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES);
|
||||||
"setPosition failed.*");
|
if (!flags) {
|
||||||
qCDebug(physics) << "EntityMotionState::setWorldTransform setPosition failed" << _entity->getID();
|
// flags are clear
|
||||||
|
_entity->setWorldTransform(bulletToGLM(worldTrans.getOrigin()), bulletToGLM(worldTrans.getRotation()));
|
||||||
|
_entity->setWorldVelocity(getBodyLinearVelocity());
|
||||||
|
_entity->setWorldAngularVelocity(getBodyAngularVelocity());
|
||||||
|
_entity->setLastSimulated(usecTimestampNow());
|
||||||
|
} else {
|
||||||
|
// only set properties NOT flagged
|
||||||
|
if (!(flags & Simulation::DIRTY_TRANSFORM)) {
|
||||||
|
_entity->setWorldTransform(bulletToGLM(worldTrans.getOrigin()), bulletToGLM(worldTrans.getRotation()));
|
||||||
|
}
|
||||||
|
if (!(flags & Simulation::DIRTY_LINEAR_VELOCITY)) {
|
||||||
|
_entity->setWorldVelocity(getBodyLinearVelocity());
|
||||||
|
}
|
||||||
|
if (!(flags & Simulation::DIRTY_ANGULAR_VELOCITY)) {
|
||||||
|
_entity->setWorldAngularVelocity(getBodyAngularVelocity());
|
||||||
|
}
|
||||||
|
if (flags != (Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES)) {
|
||||||
|
_entity->setLastSimulated(usecTimestampNow());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool orientationSuccess;
|
|
||||||
_entity->setWorldOrientation(bulletToGLM(worldTrans.getRotation()), orientationSuccess, false);
|
|
||||||
if (!orientationSuccess) {
|
|
||||||
static QString repeatedMessage =
|
|
||||||
LogHandler::getInstance().addRepeatedMessageRegex("EntityMotionState::setWorldTransform "
|
|
||||||
"setOrientation failed.*");
|
|
||||||
qCDebug(physics) << "EntityMotionState::setWorldTransform setOrientation failed" << _entity->getID();
|
|
||||||
}
|
|
||||||
_entity->setVelocity(getBodyLinearVelocity());
|
|
||||||
_entity->setAngularVelocity(getBodyAngularVelocity());
|
|
||||||
_entity->setLastSimulated(usecTimestampNow());
|
|
||||||
|
|
||||||
if (_entity->getSimulatorID().isNull()) {
|
if (_entity->getSimulatorID().isNull()) {
|
||||||
_loopsWithoutOwner++;
|
_loopsWithoutOwner++;
|
||||||
|
@ -530,9 +537,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
||||||
|
|
||||||
if (!_body->isActive()) {
|
if (!_body->isActive()) {
|
||||||
// make sure all derivatives are zero
|
// make sure all derivatives are zero
|
||||||
_entity->setVelocity(Vectors::ZERO);
|
zeroCleanObjectVelocities();
|
||||||
_entity->setAngularVelocity(Vectors::ZERO);
|
|
||||||
_entity->setAcceleration(Vectors::ZERO);
|
|
||||||
_numInactiveUpdates++;
|
_numInactiveUpdates++;
|
||||||
} else {
|
} else {
|
||||||
glm::vec3 gravity = _entity->getGravity();
|
glm::vec3 gravity = _entity->getGravity();
|
||||||
|
@ -559,9 +564,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
||||||
if (movingSlowly) {
|
if (movingSlowly) {
|
||||||
// velocities might not be zero, but we'll fake them as such, which will hopefully help convince
|
// velocities might not be zero, but we'll fake them as such, which will hopefully help convince
|
||||||
// other simulating observers to deactivate their own copies
|
// other simulating observers to deactivate their own copies
|
||||||
glm::vec3 zero(0.0f);
|
zeroCleanObjectVelocities();
|
||||||
_entity->setVelocity(zero);
|
|
||||||
_entity->setAngularVelocity(zero);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_numInactiveUpdates = 0;
|
_numInactiveUpdates = 0;
|
||||||
|
@ -818,3 +821,22 @@ bool EntityMotionState::shouldBeLocallyOwned() const {
|
||||||
void EntityMotionState::upgradeOutgoingPriority(uint8_t priority) {
|
void EntityMotionState::upgradeOutgoingPriority(uint8_t priority) {
|
||||||
_outgoingPriority = glm::max<uint8_t>(_outgoingPriority, priority);
|
_outgoingPriority = glm::max<uint8_t>(_outgoingPriority, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityMotionState::zeroCleanObjectVelocities() const {
|
||||||
|
// If transform or velocities are flagged as dirty it means a network or scripted change
|
||||||
|
// occured between the beginning and end of the stepSimulation() and we DON'T want to apply
|
||||||
|
// these physics simulation results.
|
||||||
|
uint32_t flags = _entity->getDirtyFlags() & (Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES);
|
||||||
|
if (!flags) {
|
||||||
|
_entity->setWorldVelocity(glm::vec3(0.0f));
|
||||||
|
_entity->setWorldAngularVelocity(glm::vec3(0.0f));
|
||||||
|
} else {
|
||||||
|
if (!(flags & Simulation::DIRTY_LINEAR_VELOCITY)) {
|
||||||
|
_entity->setWorldVelocity(glm::vec3(0.0f));
|
||||||
|
}
|
||||||
|
if (!(flags & Simulation::DIRTY_ANGULAR_VELOCITY)) {
|
||||||
|
_entity->setWorldAngularVelocity(glm::vec3(0.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_entity->setAcceleration(glm::vec3(0.0f));
|
||||||
|
}
|
||||||
|
|
|
@ -87,6 +87,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
// changes _outgoingPriority only if priority is larger
|
// changes _outgoingPriority only if priority is larger
|
||||||
void upgradeOutgoingPriority(uint8_t priority);
|
void upgradeOutgoingPriority(uint8_t priority);
|
||||||
|
void zeroCleanObjectVelocities() const;
|
||||||
|
|
||||||
#ifdef WANT_DEBUG_ENTITY_TREE_LOCKS
|
#ifdef WANT_DEBUG_ENTITY_TREE_LOCKS
|
||||||
bool entityTreeIsLocked() const;
|
bool entityTreeIsLocked() const;
|
||||||
|
|
|
@ -64,6 +64,12 @@ bool Pointer::isMouse() const {
|
||||||
return DependencyManager::get<PickManager>()->isMouse(_pickUID);
|
return DependencyManager::get<PickManager>()->isMouse(_pickUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pointer::setDoesHover(bool doesHover) {
|
||||||
|
withWriteLock([&] {
|
||||||
|
_hover = doesHover;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void Pointer::update(unsigned int pointerID) {
|
void Pointer::update(unsigned int pointerID) {
|
||||||
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
|
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
|
@ -95,7 +101,8 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hover events
|
// Hover events
|
||||||
bool doHover = shouldHover(pickResult);
|
bool doHover = _hover && shouldHover(pickResult);
|
||||||
|
|
||||||
Pointer::PickedObject hoveredObject = getHoveredObject(pickResult);
|
Pointer::PickedObject hoveredObject = getHoveredObject(pickResult);
|
||||||
PointerEvent hoveredEvent = buildPointerEvent(hoveredObject, pickResult);
|
PointerEvent hoveredEvent = buildPointerEvent(hoveredObject, pickResult);
|
||||||
hoveredEvent.setType(PointerEvent::Move);
|
hoveredEvent.setType(PointerEvent::Move);
|
||||||
|
@ -104,7 +111,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin
|
||||||
hoveredEvent.setMoveOnHoverLeave(moveOnHoverLeave);
|
hoveredEvent.setMoveOnHoverLeave(moveOnHoverLeave);
|
||||||
|
|
||||||
// if shouldHover && !_prevDoHover, only send hoverBegin
|
// if shouldHover && !_prevDoHover, only send hoverBegin
|
||||||
if (_enabled && _hover && doHover && !_prevDoHover) {
|
if (_enabled && doHover && !_prevDoHover) {
|
||||||
if (hoveredObject.type == ENTITY) {
|
if (hoveredObject.type == ENTITY) {
|
||||||
emit pointerManager->hoverBeginEntity(hoveredObject.objectID, hoveredEvent);
|
emit pointerManager->hoverBeginEntity(hoveredObject.objectID, hoveredEvent);
|
||||||
} else if (hoveredObject.type == OVERLAY) {
|
} else if (hoveredObject.type == OVERLAY) {
|
||||||
|
@ -112,7 +119,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin
|
||||||
} else if (hoveredObject.type == HUD) {
|
} else if (hoveredObject.type == HUD) {
|
||||||
emit pointerManager->hoverBeginHUD(hoveredEvent);
|
emit pointerManager->hoverBeginHUD(hoveredEvent);
|
||||||
}
|
}
|
||||||
} else if (_enabled && _hover && doHover) {
|
} else if (_enabled && doHover) {
|
||||||
if (hoveredObject.type == OVERLAY) {
|
if (hoveredObject.type == OVERLAY) {
|
||||||
if (_prevHoveredObject.type == OVERLAY) {
|
if (_prevHoveredObject.type == OVERLAY) {
|
||||||
if (hoveredObject.objectID == _prevHoveredObject.objectID) {
|
if (hoveredObject.objectID == _prevHoveredObject.objectID) {
|
||||||
|
@ -229,7 +236,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we disable the pointer or disable hovering, send hoverEnd events after triggerEnd
|
// if we disable the pointer or disable hovering, send hoverEnd events after triggerEnd
|
||||||
if (_hover && ((!_enabled && _prevEnabled) || (!doHover && _prevDoHover))) {
|
if ((!_enabled && _prevEnabled) || (!doHover && _prevDoHover)) {
|
||||||
if (_prevHoveredObject.type == ENTITY) {
|
if (_prevHoveredObject.type == ENTITY) {
|
||||||
emit pointerManager->hoverEndEntity(_prevHoveredObject.objectID, hoveredEvent);
|
emit pointerManager->hoverEndEntity(_prevHoveredObject.objectID, hoveredEvent);
|
||||||
} else if (_prevHoveredObject.type == OVERLAY) {
|
} else if (_prevHoveredObject.type == OVERLAY) {
|
||||||
|
|
|
@ -62,6 +62,8 @@ public:
|
||||||
virtual void setLength(float length) {}
|
virtual void setLength(float length) {}
|
||||||
virtual void setLockEndUUID(const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) {}
|
virtual void setLockEndUUID(const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) {}
|
||||||
|
|
||||||
|
virtual void setDoesHover(bool hover);
|
||||||
|
|
||||||
void update(unsigned int pointerID);
|
void update(unsigned int pointerID);
|
||||||
virtual void updateVisuals(const PickResultPointer& pickResult) = 0;
|
virtual void updateVisuals(const PickResultPointer& pickResult) = 0;
|
||||||
void generatePointerEvents(unsigned int pointerID, const PickResultPointer& pickResult);
|
void generatePointerEvents(unsigned int pointerID, const PickResultPointer& pickResult);
|
||||||
|
@ -101,7 +103,6 @@ private:
|
||||||
std::unordered_map<std::string, PickedObject> _triggeredObjects;
|
std::unordered_map<std::string, PickedObject> _triggeredObjects;
|
||||||
|
|
||||||
PointerEvent::Button chooseButton(const std::string& button);
|
PointerEvent::Button chooseButton(const std::string& button);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Pick_h
|
#endif // hifi_Pick_h
|
||||||
|
|
|
@ -122,6 +122,13 @@ void PointerManager::setLockEndUUID(unsigned int uid, const QUuid& objectID, boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PointerManager::setDoesHover(unsigned int uid, bool hover) const {
|
||||||
|
auto pointer = find(uid);
|
||||||
|
if (pointer) {
|
||||||
|
pointer->setDoesHover(hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool PointerManager::isLeftHand(unsigned int uid) {
|
bool PointerManager::isLeftHand(unsigned int uid) {
|
||||||
auto pointer = find(uid);
|
auto pointer = find(uid);
|
||||||
if (pointer) {
|
if (pointer) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
|
|
||||||
void setLength(unsigned int uid, float length) const;
|
void setLength(unsigned int uid, float length) const;
|
||||||
void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const;
|
void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const;
|
||||||
|
void setDoesHover(unsigned int uid, bool hover) const;
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ float specularDistribution(SurfaceData surface) {
|
||||||
// Add geometric factors G1(n,l) and G1(n,v)
|
// Add geometric factors G1(n,l) and G1(n,v)
|
||||||
float smithInvG1NdotL = evalSmithInvG1(surface.roughness4, surface.ndotl);
|
float smithInvG1NdotL = evalSmithInvG1(surface.roughness4, surface.ndotl);
|
||||||
denom *= surface.smithInvG1NdotV * smithInvG1NdotL;
|
denom *= surface.smithInvG1NdotV * smithInvG1NdotL;
|
||||||
// Don't divide by PI as it will be done later
|
// Don't divide by PI as this is part of the light normalization factor
|
||||||
float power = surface.roughness4 / denom;
|
float power = surface.roughness4 / denom;
|
||||||
return power;
|
return power;
|
||||||
}
|
}
|
||||||
|
@ -202,12 +202,11 @@ vec4 evalPBRShading(float metallic, vec3 fresnel, SurfaceData surface) {
|
||||||
vec3 specular = fresnelColor * power * angleAttenuation;
|
vec3 specular = fresnelColor * power * angleAttenuation;
|
||||||
float diffuse = (1.0 - metallic) * angleAttenuation * (1.0 - fresnelColor.x);
|
float diffuse = (1.0 - metallic) * angleAttenuation * (1.0 - fresnelColor.x);
|
||||||
|
|
||||||
diffuse /= 3.1415926;
|
// We don't divided by PI, as the "normalized" equations state we should, because we decide, as Naty Hoffman, that
|
||||||
// Diffuse is divided by PI but specular isn't because an infinitesimal volume light source
|
// we wish to have a similar color as raw albedo on a perfectly diffuse surface perpendicularly lit
|
||||||
// has a multiplier of PI, says Naty Hoffman.
|
// by a white light of intensity 1. But this is an arbitrary normalization of what light intensity "means".
|
||||||
// (see http://blog.selfshadow.com/publications/s2013-shading-course/hoffman/s2013_pbs_physics_math_notes.pdf
|
// (see http://blog.selfshadow.com/publications/s2013-shading-course/hoffman/s2013_pbs_physics_math_notes.pdf
|
||||||
// page 23 paragraph "Punctual light sources")
|
// page 23 paragraph "Punctual light sources")
|
||||||
|
|
||||||
return vec4(specular, diffuse);
|
return vec4(specular, diffuse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,9 +221,9 @@ vec4 evalPBRShadingDielectric(SurfaceData surface, float fresnel) {
|
||||||
vec3 specular = vec3(fresnelScalar) * power * angleAttenuation;
|
vec3 specular = vec3(fresnelScalar) * power * angleAttenuation;
|
||||||
float diffuse = angleAttenuation * (1.0 - fresnelScalar);
|
float diffuse = angleAttenuation * (1.0 - fresnelScalar);
|
||||||
|
|
||||||
diffuse /= 3.1415926;
|
// We don't divided by PI, as the "normalized" equations state we should, because we decide, as Naty Hoffman, that
|
||||||
// Diffuse is divided by PI but specular isn't because an infinitesimal volume light source
|
// we wish to have a similar color as raw albedo on a perfectly diffuse surface perpendicularly lit
|
||||||
// has a multiplier of PI, says Naty Hoffman.
|
// by a white light of intensity 1. But this is an arbitrary normalization of what light intensity "means".
|
||||||
// (see http://blog.selfshadow.com/publications/s2013-shading-course/hoffman/s2013_pbs_physics_math_notes.pdf
|
// (see http://blog.selfshadow.com/publications/s2013-shading-course/hoffman/s2013_pbs_physics_math_notes.pdf
|
||||||
// page 23 paragraph "Punctual light sources")
|
// page 23 paragraph "Punctual light sources")
|
||||||
return vec4(specular, diffuse);
|
return vec4(specular, diffuse);
|
||||||
|
@ -239,8 +238,9 @@ vec4 evalPBRShadingMetallic(SurfaceData surface, vec3 fresnel) {
|
||||||
float power = specularDistribution(surface);
|
float power = specularDistribution(surface);
|
||||||
vec3 specular = fresnelColor * power * angleAttenuation;
|
vec3 specular = fresnelColor * power * angleAttenuation;
|
||||||
|
|
||||||
// Specular isn't divided by PI because an infinitesimal volume light source
|
// We don't divided by PI, as the "normalized" equations state we should, because we decide, as Naty Hoffman, that
|
||||||
// has a multiplier of PI, says Naty Hoffman.
|
// we wish to have a similar color as raw albedo on a perfectly diffuse surface perpendicularly lit
|
||||||
|
// by a white light of intensity 1. But this is an arbitrary normalization of what light intensity "means".
|
||||||
// (see http://blog.selfshadow.com/publications/s2013-shading-course/hoffman/s2013_pbs_physics_math_notes.pdf
|
// (see http://blog.selfshadow.com/publications/s2013-shading-course/hoffman/s2013_pbs_physics_math_notes.pdf
|
||||||
// page 23 paragraph "Punctual light sources")
|
// page 23 paragraph "Punctual light sources")
|
||||||
return vec4(specular, 0.f);
|
return vec4(specular, 0.f);
|
||||||
|
|
|
@ -253,6 +253,7 @@ glm::vec2 getFacingDir2D(const glm::mat4& m);
|
||||||
|
|
||||||
inline bool isNaN(const glm::vec3& value) { return isNaN(value.x) || isNaN(value.y) || isNaN(value.z); }
|
inline bool isNaN(const glm::vec3& value) { return isNaN(value.x) || isNaN(value.y) || isNaN(value.z); }
|
||||||
inline bool isNaN(const glm::quat& value) { return isNaN(value.w) || isNaN(value.x) || isNaN(value.y) || isNaN(value.z); }
|
inline bool isNaN(const glm::quat& value) { return isNaN(value.w) || isNaN(value.x) || isNaN(value.y) || isNaN(value.z); }
|
||||||
|
inline bool isNaN(const glm::mat3& value) { return isNaN(value * glm::vec3(1.0f)); }
|
||||||
|
|
||||||
glm::mat4 orthoInverse(const glm::mat4& m);
|
glm::mat4 orthoInverse(const glm::mat4& m);
|
||||||
|
|
||||||
|
|
|
@ -464,6 +464,36 @@ glm::vec3 SpatiallyNestable::localToWorldDimensions(const glm::vec3& dimensions,
|
||||||
return dimensions;
|
return dimensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpatiallyNestable::setWorldTransform(const glm::vec3& position, const glm::quat& orientation) {
|
||||||
|
// guard against introducing NaN into the transform
|
||||||
|
if (isNaN(orientation) || isNaN(position)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
bool success = true;
|
||||||
|
Transform parentTransform = getParentTransform(success);
|
||||||
|
_transformLock.withWriteLock([&] {
|
||||||
|
Transform myWorldTransform;
|
||||||
|
Transform::mult(myWorldTransform, parentTransform, _transform);
|
||||||
|
if (myWorldTransform.getRotation() != orientation) {
|
||||||
|
changed = true;
|
||||||
|
myWorldTransform.setRotation(orientation);
|
||||||
|
}
|
||||||
|
if (myWorldTransform.getTranslation() != position) {
|
||||||
|
changed = true;
|
||||||
|
myWorldTransform.setTranslation(position);
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
|
||||||
|
_translationChanged = usecTimestampNow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (success && changed) {
|
||||||
|
locationChanged(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getWorldPosition(bool& success) const {
|
glm::vec3 SpatiallyNestable::getWorldPosition(bool& success) const {
|
||||||
return getTransform(success).getTranslation();
|
return getTransform(success).getTranslation();
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,7 @@ public:
|
||||||
|
|
||||||
virtual Transform getParentTransform(bool& success, int depth = 0) const;
|
virtual Transform getParentTransform(bool& success, int depth = 0) const;
|
||||||
|
|
||||||
|
void setWorldTransform(const glm::vec3& position, const glm::quat& orientation);
|
||||||
virtual glm::vec3 getWorldPosition(bool& success) const;
|
virtual glm::vec3 getWorldPosition(bool& success) const;
|
||||||
virtual glm::vec3 getWorldPosition() const;
|
virtual glm::vec3 getWorldPosition() const;
|
||||||
virtual void setWorldPosition(const glm::vec3& position, bool& success, bool tellPhysics = true);
|
virtual void setWorldPosition(const glm::vec3& position, bool& success, bool tellPhysics = true);
|
||||||
|
|
46
libraries/ui/src/DesktopPreviewProvider.cpp
Normal file
46
libraries/ui/src/DesktopPreviewProvider.cpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#include "DesktopPreviewProvider.h"
|
||||||
|
#include <PathUtils.h>
|
||||||
|
#include <QMetaEnum>
|
||||||
|
#include <QtPlugin>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
DesktopPreviewProvider::DesktopPreviewProvider() {
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const char* DesktopPreviewProvider::imagePaths[];
|
||||||
|
|
||||||
|
QSharedPointer<DesktopPreviewProvider> DesktopPreviewProvider::getInstance() {
|
||||||
|
static QSharedPointer<DesktopPreviewProvider> instance = DependencyManager::get<DesktopPreviewProvider>();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage DesktopPreviewProvider::getPreviewDisabledImage(bool vsyncEnabled) const {
|
||||||
|
|
||||||
|
auto imageIndex = vsyncEnabled ? VSYNC : m_previewDisabledReason;
|
||||||
|
assert(imageIndex >= 0 && imageIndex <= VSYNC);
|
||||||
|
|
||||||
|
return !m_previewDisabled[imageIndex].isNull() ? m_previewDisabled[imageIndex] : loadPreviewImage(m_previewDisabled[imageIndex], PathUtils::resourcesPath() + imagePaths[imageIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreviewProvider::setPreviewDisabledReason(PreviewDisabledReasons reason) {
|
||||||
|
if (reason == VSYNC) {
|
||||||
|
qDebug() << "Preview disabled reason can't be forced to " << QMetaEnum::fromType<DesktopPreviewProvider::PreviewDisabledReasons>().valueToKey(reason);
|
||||||
|
return; // Not settable via this interface, as VSYNC is controlled by HMD plugin..
|
||||||
|
}
|
||||||
|
|
||||||
|
m_previewDisabledReason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreviewProvider::setPreviewDisabledReason(const QString& reasonString) {
|
||||||
|
PreviewDisabledReasons reason = USER;
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
reason = (PreviewDisabledReasons) QMetaEnum::fromType<DesktopPreviewProvider::PreviewDisabledReasons>().keyToValue(reasonString.toLatin1().data(), &ok);
|
||||||
|
if (ok) {
|
||||||
|
setPreviewDisabledReason(reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage& DesktopPreviewProvider::loadPreviewImage(QImage& image, const QString& path) const {
|
||||||
|
return image = QImage(path).mirrored().convertToFormat(QImage::Format_RGBA8888);
|
||||||
|
}
|
47
libraries/ui/src/DesktopPreviewProvider.h
Normal file
47
libraries/ui/src/DesktopPreviewProvider.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
//
|
||||||
|
// Created by Alexander Ivash on 2018/01/08
|
||||||
|
// Copyright 2018 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
class DesktopPreviewProvider : public QObject, public Dependency {
|
||||||
|
SINGLETON_DEPENDENCY
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
DesktopPreviewProvider();
|
||||||
|
DesktopPreviewProvider(const DesktopPreviewProvider& other) = delete;
|
||||||
|
|
||||||
|
constexpr static const char* imagePaths[] = {
|
||||||
|
"images/preview-disabled.png", // USER
|
||||||
|
"images/preview-privacy.png", // SECURE_SCREEN
|
||||||
|
"images/preview.png", // VSYNC
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum PreviewDisabledReasons {
|
||||||
|
USER = 0,
|
||||||
|
SECURE_SCREEN,
|
||||||
|
VSYNC // Not settable via this interface, as VSYNC is controlled by HMD plugin..
|
||||||
|
};
|
||||||
|
Q_ENUM(PreviewDisabledReasons)
|
||||||
|
|
||||||
|
static QSharedPointer<DesktopPreviewProvider> getInstance();
|
||||||
|
|
||||||
|
QImage getPreviewDisabledImage(bool vsyncEnabled) const;
|
||||||
|
void setPreviewDisabledReason(PreviewDisabledReasons reason);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setPreviewDisabledReason(const QString& reason);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QImage& loadPreviewImage(QImage& image, const QString& path) const;
|
||||||
|
|
||||||
|
PreviewDisabledReasons m_previewDisabledReason = { USER };
|
||||||
|
|
||||||
|
mutable QImage m_previewDisabled[3];
|
||||||
|
};
|
|
@ -562,9 +562,11 @@
|
||||||
break;
|
break;
|
||||||
case 'disableHmdPreview':
|
case 'disableHmdPreview':
|
||||||
isHmdPreviewDisabled = Menu.isOptionChecked("Disable Preview");
|
isHmdPreviewDisabled = Menu.isOptionChecked("Disable Preview");
|
||||||
|
DesktopPreviewProvider.setPreviewDisabledReason("SECURE_SCREEN");
|
||||||
Menu.setIsOptionChecked("Disable Preview", true);
|
Menu.setIsOptionChecked("Disable Preview", true);
|
||||||
break;
|
break;
|
||||||
case 'maybeEnableHmdPreview':
|
case 'maybeEnableHmdPreview':
|
||||||
|
DesktopPreviewProvider.setPreviewDisabledReason("USER");
|
||||||
Menu.setIsOptionChecked("Disable Preview", isHmdPreviewDisabled);
|
Menu.setIsOptionChecked("Disable Preview", isHmdPreviewDisabled);
|
||||||
break;
|
break;
|
||||||
case 'passphraseReset':
|
case 'passphraseReset':
|
||||||
|
@ -635,7 +637,11 @@
|
||||||
// -Called when the TabletScriptingInterface::screenChanged() signal is emitted. The "type" argument can be either the string
|
// -Called when the TabletScriptingInterface::screenChanged() signal is emitted. The "type" argument can be either the string
|
||||||
// value of "Home", "Web", "Menu", "QML", or "Closed". The "url" argument is only valid for Web and QML.
|
// value of "Home", "Web", "Menu", "QML", or "Closed". The "url" argument is only valid for Web and QML.
|
||||||
function onTabletScreenChanged(type, url) {
|
function onTabletScreenChanged(type, url) {
|
||||||
onWalletScreen = (type === "QML" && url === WALLET_QML_SOURCE);
|
var onWalletScreenNow = (type === "QML" && url === WALLET_QML_SOURCE);
|
||||||
|
if (!onWalletScreenNow && onWalletScreen) {
|
||||||
|
DesktopPreviewProvider.setPreviewDisabledReason("USER");
|
||||||
|
}
|
||||||
|
onWalletScreen = onWalletScreenNow;
|
||||||
wireEventBridge(onWalletScreen);
|
wireEventBridge(onWalletScreen);
|
||||||
// Change button to active when window is first openend, false otherwise.
|
// Change button to active when window is first openend, false otherwise.
|
||||||
if (button) {
|
if (button) {
|
||||||
|
|
|
@ -44,7 +44,12 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
this.highVarianceCount = 0;
|
this.highVarianceCount = 0;
|
||||||
this.veryhighVarianceCount = 0;
|
this.veryhighVarianceCount = 0;
|
||||||
this.tabletID = null;
|
this.tabletID = null;
|
||||||
|
this.TABLET_UI_UUIDS = [];
|
||||||
this.blacklist = [];
|
this.blacklist = [];
|
||||||
|
this.leftPointerDoesHover = true;
|
||||||
|
this.leftPointerDoesHoverChanged = false;
|
||||||
|
this.rightPointerDoesHover = true;
|
||||||
|
this.rightPointerDoesHoverChanged = false;
|
||||||
this.pointerManager = new PointerManager();
|
this.pointerManager = new PointerManager();
|
||||||
|
|
||||||
// a module can occupy one or more "activity" slots while it's running. If all the required slots for a module are
|
// a module can occupy one or more "activity" slots while it's running. If all the required slots for a module are
|
||||||
|
@ -122,6 +127,10 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
return getControllerWorldLocation(Controller.Standard.RightHand, true);
|
return getControllerWorldLocation(Controller.Standard.RightHand, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.isTabletID = function (uuid) {
|
||||||
|
return _this.TABLET_UI_UUIDS.indexOf(uuid) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
this.updateTimings = function () {
|
this.updateTimings = function () {
|
||||||
_this.intervalCount++;
|
_this.intervalCount++;
|
||||||
var thisInterval = Date.now();
|
var thisInterval = Date.now();
|
||||||
|
@ -148,11 +157,35 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
this.setIgnorePointerItems = function() {
|
this.setIgnorePointerItems = function() {
|
||||||
if (HMD.tabletID !== this.tabletID) {
|
if (HMD.tabletID !== this.tabletID) {
|
||||||
this.tabletID = HMD.tabletID;
|
this.tabletID = HMD.tabletID;
|
||||||
|
this.TABLET_UI_UUIDS = [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID, HMD.homeButtonHighlightID];
|
||||||
Pointers.setIgnoreItems(_this.leftPointer, _this.blacklist);
|
Pointers.setIgnoreItems(_this.leftPointer, _this.blacklist);
|
||||||
Pointers.setIgnoreItems(_this.rightPointer, _this.blacklist);
|
Pointers.setIgnoreItems(_this.rightPointer, _this.blacklist);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.updateDoesHover = function(handLaser, doesHover) {
|
||||||
|
if (handLaser.doesHover !== undefined) {
|
||||||
|
if (handLaser.hand === LEFT_HAND && _this.leftPointerDoesHover !== doesHover) {
|
||||||
|
_this.leftPointerDoesHover = doesHover;
|
||||||
|
_this.leftPointerDoesHoverChanged = true;
|
||||||
|
} else if (handLaser.hand === RIGHT_HAND && _this.rightPointerDoesHover !== doesHover) {
|
||||||
|
_this.rightPointerDoesHover = doesHover;
|
||||||
|
_this.rightPointerDoesHoverChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateHovering = function () {
|
||||||
|
if (_this.leftPointerDoesHoverChanged) {
|
||||||
|
Pointers.setDoesHover(_this.leftPointer, _this.leftPointerDoesHover);
|
||||||
|
_this.leftPointerDoesHoverChanged = false;
|
||||||
|
}
|
||||||
|
if (_this.rightPointerDoesHoverChanged) {
|
||||||
|
Pointers.setDoesHover(_this.rightPointer, _this.rightPointerDoesHover);
|
||||||
|
_this.rightPointerDoesHoverChanged = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.update = function () {
|
this.update = function () {
|
||||||
try {
|
try {
|
||||||
_this.updateInternal();
|
_this.updateInternal();
|
||||||
|
@ -324,6 +357,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
_this.runningPluginNames[orderedPluginName] = true;
|
_this.runningPluginNames[orderedPluginName] = true;
|
||||||
_this.markSlots(candidatePlugin, orderedPluginName);
|
_this.markSlots(candidatePlugin, orderedPluginName);
|
||||||
_this.pointerManager.makePointerVisible(candidatePlugin.parameters.handLaser);
|
_this.pointerManager.makePointerVisible(candidatePlugin.parameters.handLaser);
|
||||||
|
_this.updateDoesHover(candidatePlugin.parameters.handLaser,
|
||||||
|
candidatePlugin.parameters.handLaser.doesHover);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
print("controllerDispatcher running " + orderedPluginName);
|
print("controllerDispatcher running " + orderedPluginName);
|
||||||
}
|
}
|
||||||
|
@ -354,12 +389,15 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
Script.beginProfileRange("dispatch.run." + runningPluginName);
|
Script.beginProfileRange("dispatch.run." + runningPluginName);
|
||||||
}
|
}
|
||||||
var runningness = plugin.run(controllerData, deltaTime);
|
var runningness = plugin.run(controllerData, deltaTime);
|
||||||
if (!runningness.active) {
|
if (runningness.active) {
|
||||||
|
_this.updateDoesHover(plugin.parameters.handLaser, plugin.parameters.handLaser.doesHover);
|
||||||
|
} else {
|
||||||
// plugin is finished running, for now. remove it from the list
|
// plugin is finished running, for now. remove it from the list
|
||||||
// of running plugins and mark its activity-slots as "not in use"
|
// of running plugins and mark its activity-slots as "not in use"
|
||||||
delete _this.runningPluginNames[runningPluginName];
|
delete _this.runningPluginNames[runningPluginName];
|
||||||
_this.markSlots(plugin, false);
|
_this.markSlots(plugin, false);
|
||||||
_this.pointerManager.makePointerInvisible(plugin.parameters.handLaser);
|
_this.pointerManager.makePointerInvisible(plugin.parameters.handLaser);
|
||||||
|
_this.updateDoesHover(plugin.parameters.handLaser, true);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
print("controllerDispatcher stopping " + runningPluginName);
|
print("controllerDispatcher stopping " + runningPluginName);
|
||||||
}
|
}
|
||||||
|
@ -372,6 +410,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_this.pointerManager.updatePointersRenderState(controllerData.triggerClicks, controllerData.triggerValues);
|
_this.pointerManager.updatePointersRenderState(controllerData.triggerClicks, controllerData.triggerValues);
|
||||||
|
_this.updateHovering();
|
||||||
|
|
||||||
if (PROFILE) {
|
if (PROFILE) {
|
||||||
Script.endProfileRange("dispatch.run");
|
Script.endProfileRange("dispatch.run");
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,20 +370,23 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.isReady = function (controllerData) {
|
this.isReady = function (controllerData) {
|
||||||
if (this.notPointingAtEntity(controllerData)) {
|
if (HMD.active) {
|
||||||
return makeRunningValues(false, [], []);
|
if (this.notPointingAtEntity(controllerData)) {
|
||||||
}
|
return makeRunningValues(false, [], []);
|
||||||
|
}
|
||||||
|
|
||||||
this.distanceHolding = false;
|
this.distanceHolding = false;
|
||||||
this.distanceRotating = false;
|
this.distanceRotating = false;
|
||||||
|
|
||||||
if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) {
|
if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) {
|
||||||
this.prepareDistanceRotatingData(controllerData);
|
this.prepareDistanceRotatingData(controllerData);
|
||||||
return makeRunningValues(true, [], []);
|
return makeRunningValues(true, [], []);
|
||||||
} else {
|
} else {
|
||||||
this.destroyContextOverlay();
|
this.destroyContextOverlay();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return makeRunningValues(false, [], []);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.run = function (controllerData) {
|
this.run = function (controllerData) {
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
|
|
||||||
this.isReady = function (controllerData) {
|
this.isReady = function (controllerData) {
|
||||||
var otherModuleRunning = this.getOtherModule().running;
|
var otherModuleRunning = this.getOtherModule().running;
|
||||||
if (!otherModuleRunning) {
|
if (!otherModuleRunning && HMD.active) {
|
||||||
if (this.processLaser(controllerData)) {
|
if (this.processLaser(controllerData)) {
|
||||||
this.running = true;
|
this.running = true;
|
||||||
return ControllerDispatcherUtils.makeRunningValues(true, [], []);
|
return ControllerDispatcherUtils.makeRunningValues(true, [], []);
|
||||||
|
|
|
@ -87,41 +87,89 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
return MyAvatar.getDominantHand() === "right" ? 1 : 0;
|
return MyAvatar.getDominantHand() === "right" ? 1 : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.dominantHandOverride = false;
|
this.letOtherHandRunFirst = function (controllerData, pointingAt) {
|
||||||
|
// If both hands are ready to run, let the other hand run first if it is the dominant hand so that it gets the
|
||||||
|
// highlight.
|
||||||
|
var isOtherTriggerPressed = controllerData.triggerValues[this.otherHand] > TRIGGER_OFF_VALUE;
|
||||||
|
var isLetOtherHandRunFirst = !this.getOtherModule().running
|
||||||
|
&& this.getDominantHand() === this.otherHand
|
||||||
|
&& (this.parameters.handLaser.allwaysOn || isOtherTriggerPressed);
|
||||||
|
if (isLetOtherHandRunFirst) {
|
||||||
|
var otherHandPointingAt = controllerData.rayPicks[this.otherHand].objectID;
|
||||||
|
if (this.isTabletID(otherHandPointingAt)) {
|
||||||
|
otherHandPointingAt = HMD.tabletID;
|
||||||
|
}
|
||||||
|
isLetOtherHandRunFirst = pointingAt === otherHandPointingAt;
|
||||||
|
}
|
||||||
|
return isLetOtherHandRunFirst;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.hoverItem = null;
|
||||||
|
|
||||||
|
this.isTabletID = function (uuid) {
|
||||||
|
return [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID, HMD.homeButtonHighlightID].indexOf(uuid) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
this.isReady = function(controllerData) {
|
this.isReady = function(controllerData) {
|
||||||
var otherModuleRunning = this.getOtherModule().running;
|
if (this.isPointingAtOverlay(controllerData) || this.isPointingAtWebEntity(controllerData)) {
|
||||||
otherModuleRunning = otherModuleRunning && this.getDominantHand() !== this.hand; // Auto-swap to dominant hand.
|
|
||||||
var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE
|
|
||||||
&& controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE;
|
|
||||||
if ((!otherModuleRunning || isTriggerPressed)
|
|
||||||
&& (this.isPointingAtOverlay(controllerData) || this.isPointingAtWebEntity(controllerData))) {
|
|
||||||
this.updateAllwaysOn();
|
this.updateAllwaysOn();
|
||||||
if (isTriggerPressed) {
|
|
||||||
this.dominantHandOverride = true; // Override dominant hand.
|
var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE;
|
||||||
this.getOtherModule().dominantHandOverride = false;
|
|
||||||
}
|
|
||||||
if (this.parameters.handLaser.allwaysOn || isTriggerPressed) {
|
if (this.parameters.handLaser.allwaysOn || isTriggerPressed) {
|
||||||
return makeRunningValues(true, [], []);
|
var pointingAt = controllerData.rayPicks[this.hand].objectID;
|
||||||
|
if (this.isTabletID(pointingAt)) {
|
||||||
|
pointingAt = HMD.tabletID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.letOtherHandRunFirst(controllerData, pointingAt)) {
|
||||||
|
|
||||||
|
if (pointingAt !== this.getOtherModule().hoverItem) {
|
||||||
|
this.parameters.handLaser.doesHover = true;
|
||||||
|
this.hoverItem = pointingAt;
|
||||||
|
} else {
|
||||||
|
this.parameters.handLaser.doesHover = false;
|
||||||
|
this.hoverItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return makeRunningValues(true, [], []);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.parameters.handLaser.doesHover = false;
|
||||||
|
this.hoverItem = null;
|
||||||
|
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.run = function(controllerData, deltaTime) {
|
this.run = function(controllerData, deltaTime) {
|
||||||
var otherModuleRunning = this.getOtherModule().running;
|
|
||||||
otherModuleRunning = otherModuleRunning && this.getDominantHand() !== this.hand; // Auto-swap to dominant hand.
|
|
||||||
otherModuleRunning = otherModuleRunning || this.getOtherModule().dominantHandOverride; // Override dominant hand.
|
|
||||||
var grabModuleNeedsToRun = this.grabModuleWantsNearbyOverlay(controllerData);
|
var grabModuleNeedsToRun = this.grabModuleWantsNearbyOverlay(controllerData);
|
||||||
if (!otherModuleRunning && !grabModuleNeedsToRun && (controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE
|
var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE;
|
||||||
|| this.parameters.handLaser.allwaysOn
|
if (!grabModuleNeedsToRun && (isTriggerPressed || this.parameters.handLaser.allwaysOn
|
||||||
&& (this.isPointingAtOverlay(controllerData) || this.isPointingAtWebEntity(controllerData)))) {
|
&& (this.isPointingAtOverlay(controllerData) || this.isPointingAtWebEntity(controllerData)))) {
|
||||||
this.running = true;
|
this.running = true;
|
||||||
|
|
||||||
|
var pointingAt = controllerData.rayPicks[this.hand].objectID;
|
||||||
|
if (this.isTabletID(pointingAt)) {
|
||||||
|
pointingAt = HMD.tabletID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pointingAt !== this.getOtherModule().hoverItem || isTriggerPressed) {
|
||||||
|
this.parameters.handLaser.doesHover = true;
|
||||||
|
this.hoverItem = pointingAt;
|
||||||
|
} else {
|
||||||
|
this.parameters.handLaser.doesHover = false;
|
||||||
|
this.hoverItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
return makeRunningValues(true, [], []);
|
return makeRunningValues(true, [], []);
|
||||||
}
|
}
|
||||||
this.deleteContextOverlay();
|
this.deleteContextOverlay();
|
||||||
this.running = false;
|
this.running = false;
|
||||||
this.dominantHandOverride = false;
|
|
||||||
|
this.parameters.handLaser.doesHover = false;
|
||||||
|
this.hoverItem = null;
|
||||||
|
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -448,7 +448,7 @@ var toolBar = (function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
addButton("importEntitiesButton", "assets-01.svg", function() {
|
addButton("importEntitiesButton", "assets-01.svg", function() {
|
||||||
Window.openFileChanged.connect(onFileOpenChanged);
|
Window.browseChanged.connect(onFileOpenChanged);
|
||||||
Window.browseAsync("Select Model to Import", "", "*.json");
|
Window.browseAsync("Select Model to Import", "", "*.json");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1497,7 +1497,7 @@ function onFileOpenChanged(filename) {
|
||||||
// disconnect the event, otherwise the requests will stack up
|
// disconnect the event, otherwise the requests will stack up
|
||||||
try {
|
try {
|
||||||
// Not all calls to onFileOpenChanged() connect an event.
|
// Not all calls to onFileOpenChanged() connect an event.
|
||||||
Window.openFileChanged.disconnect(onFileOpenChanged);
|
Window.browseChanged.disconnect(onFileOpenChanged);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Ignore.
|
// Ignore.
|
||||||
}
|
}
|
||||||
|
@ -1549,7 +1549,7 @@ function handeMenuEvent(menuItem) {
|
||||||
}
|
}
|
||||||
} else if (menuItem === "Import Entities" || menuItem === "Import Entities from URL") {
|
} else if (menuItem === "Import Entities" || menuItem === "Import Entities from URL") {
|
||||||
if (menuItem === "Import Entities") {
|
if (menuItem === "Import Entities") {
|
||||||
Window.openFileChanged.connect(onFileOpenChanged);
|
Window.browseChanged.connect(onFileOpenChanged);
|
||||||
Window.browseAsync("Select Model to Import", "", "*.json");
|
Window.browseAsync("Select Model to Import", "", "*.json");
|
||||||
} else {
|
} else {
|
||||||
Window.promptTextChanged.connect(onPromptTextChanged);
|
Window.promptTextChanged.connect(onPromptTextChanged);
|
||||||
|
|
|
@ -43,7 +43,7 @@ var activeTimer = false; // used to cancel active timer if a user plays an amima
|
||||||
var activeEmote = false; // to keep track of the currently playing emote
|
var activeEmote = false; // to keep track of the currently playing emote
|
||||||
|
|
||||||
button = tablet.addButton({
|
button = tablet.addButton({
|
||||||
//icon: "icons/tablet-icons/emote.svg", // TODO - we need graphics for this
|
icon: "icons/tablet-icons/EmoteAppIcon.svg",
|
||||||
text: EMOTE_LABEL,
|
text: EMOTE_LABEL,
|
||||||
sortOrder: EMOTE_APP_SORT_ORDER
|
sortOrder: EMOTE_APP_SORT_ORDER
|
||||||
});
|
});
|
||||||
|
|
|
@ -44,11 +44,11 @@
|
||||||
input[type=button] {
|
input[type=button] {
|
||||||
font-family: 'Raleway';
|
font-family: 'Raleway';
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 13px;
|
font-size: 20px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
height: 28px;
|
height: 105px;
|
||||||
min-width: 120px;
|
min-width: 190px;
|
||||||
padding: 0px 18px;
|
padding: 0px 18px;
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
@ -98,14 +98,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p>Click an emotion to Emote:<p>
|
<p>Click an emotion to Emote:<p>
|
||||||
<p><input type="button" class="emote-button white" value="Crying"></p>
|
<p><input type="button" class="emote-button white" value="Crying">
|
||||||
<p><input type="button" class="emote-button white" value="Surprised"></p>
|
<input type="button" class="emote-button white" value="Surprised"></p>
|
||||||
<p><input type="button" class="emote-button white" value="Dancing"></p>
|
<p><input type="button" class="emote-button white" value="Dancing">
|
||||||
<p><input type="button" class="emote-button white" value="Cheering"></p>
|
<input type="button" class="emote-button white" value="Cheering"></p>
|
||||||
<p><input type="button" class="emote-button white" value="Waving"></p>
|
<p><input type="button" class="emote-button white" value="Waving">
|
||||||
<p><input type="button" class="emote-button white" value="Fall"></p>
|
<input type="button" class="emote-button white" value="Fall"></p>
|
||||||
<p><input type="button" class="emote-button white" value="Pointing"></p>
|
<p><input type="button" class="emote-button white" value="Pointing">
|
||||||
<p><input type="button" class="emote-button white" value="Clapping"></p>
|
<input type="button" class="emote-button white" value="Clapping"></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||||
|
|
|
@ -539,8 +539,14 @@
|
||||||
return startingUp;
|
return startingUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDomainConnectionRefused(reason) {
|
function onDomainConnectionRefused(reason, reasonCode) {
|
||||||
createNotification("Connection refused: " + reason, NotificationType.CONNECTION_REFUSED);
|
// the "login error" reason means that the DS couldn't decrypt the username signature
|
||||||
|
// since this eventually resolves itself for good actors we don't need to show a notification for it
|
||||||
|
var LOGIN_ERROR_REASON_CODE = 2;
|
||||||
|
|
||||||
|
if (reasonCode != LOGIN_ERROR_REASON_CODE) {
|
||||||
|
createNotification("Connection refused: " + reason, NotificationType.CONNECTION_REFUSED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onEditError(msg) {
|
function onEditError(msg) {
|
||||||
|
|
Loading…
Reference in a new issue