mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 14:03:55 +02:00
fixing merge conflicts
This commit is contained in:
commit
f58a018c64
25 changed files with 847 additions and 170 deletions
66
interface/resources/icons/tablet-icons/finger-paint-a.svg
Normal file
66
interface/resources/icons/tablet-icons/finger-paint-a.svg
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 50 50"
|
||||
style="enable-background:new 0 0 50 50;"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="finger-paint-a.svg"
|
||||
inkscape:version="0.92.0 r15299"><metadata
|
||||
id="metadata28"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs26" /><sodipodi:namedview
|
||||
pagecolor="#ff0000"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1054"
|
||||
inkscape:window-height="851"
|
||||
id="namedview24"
|
||||
showgrid="false"
|
||||
inkscape:zoom="8.88"
|
||||
inkscape:cx="6.7004505"
|
||||
inkscape:cy="25"
|
||||
inkscape:window-x="120"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="Layer_1" /><style
|
||||
type="text/css"
|
||||
id="style10">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style><g
|
||||
id="Layer_2" /><g
|
||||
id="g15"
|
||||
style="fill:#000000;fill-opacity:1"><path
|
||||
class="st0"
|
||||
d="M18.3,19.6c0.7,0.1,1.2,0.5,1.4,1.1c0.4,1.3,2,5.6,2.4,6.9c2.2,0,7.9,0.1,9.9,0.1c0.2,0,0.6,0,0.8,0.1 c0.5,0.1,0.8,0.4,1.1,0.9c0.1,0.2,0.2,0.4,0.2,0.6c0.8,2.9,0.7,2,1.5,4.9c0.8,3,0.1,5.7-2.3,7.7c-1.9,1.6-3.6,2.3-5.7,1.9 c-0.6-0.1-1.2-0.3-1.8-0.5c-3.6-1.5-7.3-2.9-10.9-4.3c-0.9-0.4-1.4-1.2-1.3-2c0.1-0.9,0.9-1.5,1.8-1.6c0.1,0,0.3,0,0.4,0 c0.2,0,0.4,0.1,0.7,0.2c1.6,0.6,2.6,1.4,4.2,2c0,0,0,0,0,0c0,0,0.1,0,0.2,0c-0.1-0.2-0.1-0.4-0.2-0.6c-1.4-4.9-2.9-9.8-4.3-14.7 c-0.2-0.7-0.3-1.4,0.2-2c0.4-0.6,1-0.8,1.7-0.8C18.2,19.5,18.2,19.5,18.3,19.6 M18.9,16.3c-0.1,0-0.3,0-0.4-0.1 c-1.9-0.2-3.6,0.6-4.7,2.1c-1.5,2-0.9,4.1-0.7,4.8c0.9,3,1.8,6,2.6,9c-0.1,0-0.3,0-0.4,0c-2.5,0-4.6,1.9-5,4.3 c-0.2,1.2,0.1,2.4,0.7,3.4c0.6,1,1.5,1.7,2.7,2.2c1.2,0.5,2.4,0.9,3.6,1.4c2.4,0.9,4.9,1.9,7.3,2.9c0.9,0.4,1.7,0.6,2.5,0.7 c3.9,0.7,6.7-1.2,8.5-2.7c3.4-2.8,4.6-6.7,3.4-11.1c-0.5-1.7-0.6-2.1-0.8-2.7c-0.1-0.4-0.3-1-0.7-2.2c-0.1-0.4-0.2-0.7-0.4-1.1 c-0.7-1.5-1.8-2.5-3.4-2.7c-0.6-0.1-1.2-0.1-1.8-0.1c-1.2,0-3.4,0-5.4,0c-0.6,0-1.3-0.1-1.9-0.1c-0.2-0.6-0.5-1.3-0.7-2 c-0.4-1.1-0.7-2.1-0.9-2.6C22.3,17.9,20.8,16.7,18.9,16.3L18.9,16.3z"
|
||||
id="path13"
|
||||
style="fill:#000000;fill-opacity:1" /></g><path
|
||||
class="st0"
|
||||
d="M35.1,4.3c0.5,0,1,0,1.5,0c0.6,0,1.3-0.4,1.3-1.1c0-0.6-0.5-1.2-1.2-1.2c-0.5,0-1,0-1.5,0 c-0.6,0-1.3,0.4-1.3,1.1C33.9,3.6,34.4,4.3,35.1,4.3L35.1,4.3z"
|
||||
id="path17"
|
||||
style="fill:#000000;fill-opacity:1" /><path
|
||||
class="st0"
|
||||
d="M32,7.7c-1.2-0.8-0.9-2.1,0.1-3c1.2-1-0.6-2.6-1.7-1.6c-1,0.8-1.6,2-1.6,3.2c0,1.4,0.8,2.5,2,3.2 c0.5,0.3,1.4,0.1,1.7-0.4C32.8,8.7,32.5,8.1,32,7.7L32,7.7z"
|
||||
id="path19"
|
||||
style="fill:#000000;fill-opacity:1" /><path
|
||||
class="st0"
|
||||
d="M35.4,9.6c-1.4-0.7-2.6,1.3-1.2,1.9c1,0.5,1.8,1.2,2,2.1c0,0,0,0.2,0,0.2c0,0.1,0,0.2,0,0.3c0,0,0,0.2-0.1,0.2 c0,0,0,0,0,0.1c0,0-0.1,0.1-0.1,0.1c-0.2,0.3-0.6,0.6-1,0.8c-1.3,0.5-2.8,0.2-4.1-0.2c-1.4-0.5-2.7-1.1-4.1-1.7 c-3.2-1.3-6.6-2.6-10.1-2.5c-2.8,0.1-6.1,1.1-7.4,3.5c-1.1,2.1-0.4,4.5,1.4,5.8c0-0.8,0.4-1.7,0.9-2.3c-0.7-0.9-0.7-2.2,0.3-3.1 c1.9-1.9,5.3-1.9,7.8-1.4c3.1,0.6,5.9,2,8.8,3.2c2.8,1.1,6.5,2.1,9-0.2C39.9,14.2,38,10.8,35.4,9.6z"
|
||||
id="path21"
|
||||
style="fill:#000000;fill-opacity:1" /></svg>
|
After Width: | Height: | Size: 3.9 KiB |
30
interface/resources/icons/tablet-icons/finger-paint-i.svg
Normal file
30
interface/resources/icons/tablet-icons/finger-paint-i.svg
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.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 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g id="Layer_2">
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M18.3,19.6c0.7,0.1,1.2,0.5,1.4,1.1c0.4,1.3,2,5.6,2.4,6.9c2.2,0,7.9,0.1,9.9,0.1c0.2,0,0.6,0,0.8,0.1
|
||||
c0.5,0.1,0.8,0.4,1.1,0.9c0.1,0.2,0.2,0.4,0.2,0.6c0.8,2.9,0.7,2,1.5,4.9c0.8,3,0.1,5.7-2.3,7.7c-1.9,1.6-3.6,2.3-5.7,1.9
|
||||
c-0.6-0.1-1.2-0.3-1.8-0.5c-3.6-1.5-7.3-2.9-10.9-4.3c-0.9-0.4-1.4-1.2-1.3-2c0.1-0.9,0.9-1.5,1.8-1.6c0.1,0,0.3,0,0.4,0
|
||||
c0.2,0,0.4,0.1,0.7,0.2c1.6,0.6,2.6,1.4,4.2,2c0,0,0,0,0,0c0,0,0.1,0,0.2,0c-0.1-0.2-0.1-0.4-0.2-0.6c-1.4-4.9-2.9-9.8-4.3-14.7
|
||||
c-0.2-0.7-0.3-1.4,0.2-2c0.4-0.6,1-0.8,1.7-0.8C18.2,19.5,18.2,19.5,18.3,19.6 M18.9,16.3c-0.1,0-0.3,0-0.4-0.1
|
||||
c-1.9-0.2-3.6,0.6-4.7,2.1c-1.5,2-0.9,4.1-0.7,4.8c0.9,3,1.8,6,2.6,9c-0.1,0-0.3,0-0.4,0c-2.5,0-4.6,1.9-5,4.3
|
||||
c-0.2,1.2,0.1,2.4,0.7,3.4c0.6,1,1.5,1.7,2.7,2.2c1.2,0.5,2.4,0.9,3.6,1.4c2.4,0.9,4.9,1.9,7.3,2.9c0.9,0.4,1.7,0.6,2.5,0.7
|
||||
c3.9,0.7,6.7-1.2,8.5-2.7c3.4-2.8,4.6-6.7,3.4-11.1c-0.5-1.7-0.6-2.1-0.8-2.7c-0.1-0.4-0.3-1-0.7-2.2c-0.1-0.4-0.2-0.7-0.4-1.1
|
||||
c-0.7-1.5-1.8-2.5-3.4-2.7c-0.6-0.1-1.2-0.1-1.8-0.1c-1.2,0-3.4,0-5.4,0c-0.6,0-1.3-0.1-1.9-0.1c-0.2-0.6-0.5-1.3-0.7-2
|
||||
c-0.4-1.1-0.7-2.1-0.9-2.6C22.3,17.9,20.8,16.7,18.9,16.3L18.9,16.3z"/>
|
||||
</g>
|
||||
<path class="st0" d="M35.1,4.3c0.5,0,1,0,1.5,0c0.6,0,1.3-0.4,1.3-1.1c0-0.6-0.5-1.2-1.2-1.2c-0.5,0-1,0-1.5,0
|
||||
c-0.6,0-1.3,0.4-1.3,1.1C33.9,3.6,34.4,4.3,35.1,4.3L35.1,4.3z"/>
|
||||
<path class="st0" d="M32,7.7c-1.2-0.8-0.9-2.1,0.1-3c1.2-1-0.6-2.6-1.7-1.6c-1,0.8-1.6,2-1.6,3.2c0,1.4,0.8,2.5,2,3.2
|
||||
c0.5,0.3,1.4,0.1,1.7-0.4C32.8,8.7,32.5,8.1,32,7.7L32,7.7z"/>
|
||||
<path class="st0" d="M35.4,9.6c-1.4-0.7-2.6,1.3-1.2,1.9c1,0.5,1.8,1.2,2,2.1c0,0,0,0.2,0,0.2c0,0.1,0,0.2,0,0.3c0,0,0,0.2-0.1,0.2
|
||||
c0,0,0,0,0,0.1c0,0-0.1,0.1-0.1,0.1c-0.2,0.3-0.6,0.6-1,0.8c-1.3,0.5-2.8,0.2-4.1-0.2c-1.4-0.5-2.7-1.1-4.1-1.7
|
||||
c-3.2-1.3-6.6-2.6-10.1-2.5c-2.8,0.1-6.1,1.1-7.4,3.5c-1.1,2.1-0.4,4.5,1.4,5.8c0-0.8,0.4-1.7,0.9-2.3c-0.7-0.9-0.7-2.2,0.3-3.1
|
||||
c1.9-1.9,5.3-1.9,7.8-1.4c3.1,0.6,5.9,2,8.8,3.2c2.8,1.1,6.5,2.1,9-0.2C39.9,14.2,38,10.8,35.4,9.6z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
|
@ -170,6 +170,7 @@
|
|||
#include "ui/StandAloneJSConsole.h"
|
||||
#include "ui/Stats.h"
|
||||
#include "ui/UpdateDialog.h"
|
||||
#include "ui/overlays/Overlays.h"
|
||||
#include "Util.h"
|
||||
#include "InterfaceParentFinder.h"
|
||||
|
||||
|
@ -528,7 +529,7 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
// to take care of highlighting keyboard focused items, rather than
|
||||
// continuing to overburden Application.cpp
|
||||
std::shared_ptr<Cube3DOverlay> _keyboardFocusHighlight{ nullptr };
|
||||
int _keyboardFocusHighlightID{ -1 };
|
||||
OverlayID _keyboardFocusHighlightID{ UNKNOWN_OVERLAY_ID };
|
||||
|
||||
|
||||
// FIXME hack access to the internal share context for the Chromium helper
|
||||
|
@ -1235,12 +1236,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// Keyboard focus handling for Web overlays.
|
||||
auto overlays = &(qApp->getOverlays());
|
||||
|
||||
connect(overlays, &Overlays::mousePressOnOverlay, [=](unsigned int overlayID, const PointerEvent& event) {
|
||||
connect(overlays, &Overlays::mousePressOnOverlay, [=](OverlayID overlayID, const PointerEvent& event) {
|
||||
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||
setKeyboardFocusOverlay(overlayID);
|
||||
});
|
||||
|
||||
connect(overlays, &Overlays::overlayDeleted, [=](unsigned int overlayID) {
|
||||
connect(overlays, &Overlays::overlayDeleted, [=](OverlayID overlayID) {
|
||||
if (overlayID == _keyboardFocusedOverlay.get()) {
|
||||
setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID);
|
||||
}
|
||||
|
@ -1692,9 +1693,9 @@ void Application::cleanupBeforeQuit() {
|
|||
_applicationStateDevice.reset();
|
||||
|
||||
{
|
||||
if (_keyboardFocusHighlightID > 0) {
|
||||
if (_keyboardFocusHighlightID != UNKNOWN_OVERLAY_ID) {
|
||||
getOverlays().deleteOverlay(_keyboardFocusHighlightID);
|
||||
_keyboardFocusHighlightID = -1;
|
||||
_keyboardFocusHighlightID = UNKNOWN_OVERLAY_ID;
|
||||
}
|
||||
_keyboardFocusHighlight = nullptr;
|
||||
}
|
||||
|
@ -3092,7 +3093,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
|
|||
buttons, event->modifiers());
|
||||
|
||||
if (compositor.getReticleVisible() || !isHMDMode() || !compositor.getReticleOverDesktop() ||
|
||||
getOverlays().getOverlayAtPoint(glm::vec2(transformedPos.x(), transformedPos.y()))) {
|
||||
getOverlays().getOverlayAtPoint(glm::vec2(transformedPos.x(), transformedPos.y())) != UNKNOWN_OVERLAY_ID) {
|
||||
getOverlays().mouseMoveEvent(&mappedEvent);
|
||||
getEntities()->mouseMoveEvent(&mappedEvent);
|
||||
}
|
||||
|
@ -4111,7 +4112,7 @@ void Application::rotationModeChanged() const {
|
|||
|
||||
void Application::setKeyboardFocusHighlight(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions) {
|
||||
// Create focus
|
||||
if (_keyboardFocusHighlightID < 0 || !getOverlays().isAddedOverlay(_keyboardFocusHighlightID)) {
|
||||
if (_keyboardFocusHighlightID == UNKNOWN_OVERLAY_ID || !getOverlays().isAddedOverlay(_keyboardFocusHighlightID)) {
|
||||
_keyboardFocusHighlight = std::make_shared<Cube3DOverlay>();
|
||||
_keyboardFocusHighlight->setAlpha(1.0f);
|
||||
_keyboardFocusHighlight->setBorderSize(1.0f);
|
||||
|
@ -4173,11 +4174,11 @@ void Application::setKeyboardFocusEntity(EntityItemID entityItemID) {
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int Application::getKeyboardFocusOverlay() {
|
||||
OverlayID Application::getKeyboardFocusOverlay() {
|
||||
return _keyboardFocusedOverlay.get();
|
||||
}
|
||||
|
||||
void Application::setKeyboardFocusOverlay(unsigned int overlayID) {
|
||||
void Application::setKeyboardFocusOverlay(OverlayID overlayID) {
|
||||
if (overlayID != _keyboardFocusedOverlay.get()) {
|
||||
_keyboardFocusedOverlay.set(overlayID);
|
||||
|
||||
|
@ -5550,6 +5551,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
|||
auto entityScriptServerLog = DependencyManager::get<EntityScriptServerLogClient>();
|
||||
scriptEngine->registerGlobalObject("EntityScriptServerLog", entityScriptServerLog.data());
|
||||
|
||||
qScriptRegisterMetaType(scriptEngine, OverlayIDtoScriptValue, OverlayIDfromScriptValue);
|
||||
|
||||
// connect this script engines printedMessage signal to the global ScriptEngines these various messages
|
||||
connect(scriptEngine, &ScriptEngine::printedMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onPrintedMessage);
|
||||
connect(scriptEngine, &ScriptEngine::errorMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onErrorMessage);
|
||||
|
@ -6707,6 +6710,12 @@ void Application::updateDisplayMode() {
|
|||
}
|
||||
|
||||
emit activeDisplayPluginChanged();
|
||||
|
||||
if (_displayPlugin->isHmd()) {
|
||||
qCDebug(interfaceapp) << "Entering into HMD Mode";
|
||||
} else {
|
||||
qCDebug(interfaceapp) << "Entering into Desktop Mode";
|
||||
}
|
||||
|
||||
// reset the avatar, to set head and hand palms back to a reasonable default pose.
|
||||
getMyAvatar()->reset(false);
|
||||
|
@ -6883,6 +6892,7 @@ void Application::updateThreadPoolCount() const {
|
|||
}
|
||||
|
||||
void Application::updateSystemTabletMode() {
|
||||
qApp->setProperty(hifi::properties::HMD, isHMDMode());
|
||||
if (isHMDMode()) {
|
||||
DependencyManager::get<TabletScriptingInterface>()->setToolbarMode(getHmdTabletBecomesToolbarSetting());
|
||||
} else {
|
||||
|
@ -6894,3 +6904,13 @@ void Application::toggleMuteAudio() {
|
|||
auto menu = Menu::getInstance();
|
||||
menu->setIsOptionChecked(MenuOption::MuteAudio, !menu->isOptionChecked(MenuOption::MuteAudio));
|
||||
}
|
||||
|
||||
OverlayID Application::getTabletScreenID() {
|
||||
auto HMD = DependencyManager::get<HMDScriptingInterface>();
|
||||
return HMD->getCurrentTabletScreenID();
|
||||
}
|
||||
|
||||
OverlayID Application::getTabletHomeButtonID() {
|
||||
auto HMD = DependencyManager::get<HMDScriptingInterface>();
|
||||
return HMD->getCurrentHomeButtonUUID();
|
||||
}
|
||||
|
|
|
@ -298,6 +298,9 @@ public:
|
|||
Q_INVOKABLE void sendHoverOverEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendHoverLeaveEntity(QUuid id, PointerEvent event);
|
||||
|
||||
OverlayID getTabletScreenID();
|
||||
OverlayID getTabletHomeButtonID();
|
||||
|
||||
signals:
|
||||
void svoImportRequested(const QString& url);
|
||||
|
||||
|
@ -387,8 +390,8 @@ public slots:
|
|||
void setKeyboardFocusEntity(QUuid id);
|
||||
void setKeyboardFocusEntity(EntityItemID entityItemID);
|
||||
|
||||
unsigned int getKeyboardFocusOverlay();
|
||||
void setKeyboardFocusOverlay(unsigned int overlayID);
|
||||
OverlayID getKeyboardFocusOverlay();
|
||||
void setKeyboardFocusOverlay(OverlayID overlayID);
|
||||
|
||||
void addAssetToWorldMessageClose();
|
||||
|
||||
|
@ -618,7 +621,7 @@ private:
|
|||
DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface();
|
||||
|
||||
ThreadSafeValueCache<EntityItemID> _keyboardFocusedEntity;
|
||||
ThreadSafeValueCache<unsigned int> _keyboardFocusedOverlay;
|
||||
ThreadSafeValueCache<OverlayID> _keyboardFocusedOverlay;
|
||||
quint64 _lastAcceptedKeyPress = 0;
|
||||
bool _isForeground = true; // starts out assumed to be in foreground
|
||||
bool _inPaint = false;
|
||||
|
|
|
@ -45,12 +45,20 @@ SpatiallyNestableWeakPointer InterfaceParentFinder::find(QUuid parentID, bool& s
|
|||
success = true;
|
||||
return parent;
|
||||
}
|
||||
|
||||
if (parentID == AVATAR_SELF_ID) {
|
||||
success = true;
|
||||
return avatarManager->getMyAvatar();
|
||||
}
|
||||
|
||||
// search overlays
|
||||
auto& overlays = qApp->getOverlays();
|
||||
auto overlay = overlays.getOverlay(parentID);
|
||||
parent = std::dynamic_pointer_cast<SpatiallyNestable>(overlay); // this will return nullptr for non-3d overlays
|
||||
if (!parent.expired()) {
|
||||
success = true;
|
||||
return parent;
|
||||
}
|
||||
|
||||
success = false;
|
||||
return parent;
|
||||
}
|
||||
|
|
|
@ -808,7 +808,7 @@ void MyAvatar::saveData() {
|
|||
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
||||
_avatarEntitiesLock.withReadLock([&] {
|
||||
for (auto entityID : _avatarEntityData.keys()) {
|
||||
if (hmdInterface->getCurrentTableUIID() == entityID) {
|
||||
if (hmdInterface->getCurrentTabletUIID() == entityID) {
|
||||
// don't persist the tablet between domains / sessions
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui
|
|||
_calibrationCount(0),
|
||||
_calibrationValues(),
|
||||
_calibrationBillboard(NULL),
|
||||
_calibrationBillboardID(0),
|
||||
_calibrationBillboardID(UNKNOWN_OVERLAY_ID),
|
||||
_calibrationMessage(QString()),
|
||||
_isCalibrated(false)
|
||||
{
|
||||
|
|
|
@ -149,7 +149,7 @@ private:
|
|||
int _calibrationCount;
|
||||
QVector<float> _calibrationValues;
|
||||
TextOverlay* _calibrationBillboard;
|
||||
int _calibrationBillboardID;
|
||||
OverlayID _calibrationBillboardID;
|
||||
QString _calibrationMessage;
|
||||
bool _isCalibrated;
|
||||
void addCalibrationDatum();
|
||||
|
|
|
@ -29,9 +29,9 @@ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Depen
|
|||
Q_PROPERTY(glm::quat orientation READ getOrientation)
|
||||
Q_PROPERTY(bool mounted READ isMounted)
|
||||
Q_PROPERTY(bool showTablet READ getShouldShowTablet)
|
||||
Q_PROPERTY(QUuid tabletID READ getCurrentTableUIID WRITE setCurrentTabletUIID)
|
||||
Q_PROPERTY(unsigned int homeButtonID READ getCurrentHomeButtonUUID WRITE setCurrentHomeButtonUUID)
|
||||
|
||||
Q_PROPERTY(QUuid tabletID READ getCurrentTabletUIID WRITE setCurrentTabletUIID)
|
||||
Q_PROPERTY(QUuid homeButtonID READ getCurrentHomeButtonUUID WRITE setCurrentHomeButtonUUID)
|
||||
Q_PROPERTY(QUuid tabletScreenID READ getCurrentTabletScreenID WRITE setCurrentTabletScreenID)
|
||||
|
||||
public:
|
||||
Q_INVOKABLE glm::vec3 calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction) const;
|
||||
|
@ -91,15 +91,19 @@ public:
|
|||
bool getShouldShowTablet() const { return _showTablet; }
|
||||
|
||||
void setCurrentTabletUIID(QUuid tabletID) { _tabletUIID = tabletID; }
|
||||
QUuid getCurrentTableUIID() const { return _tabletUIID; }
|
||||
QUuid getCurrentTabletUIID() const { return _tabletUIID; }
|
||||
|
||||
void setCurrentHomeButtonUUID(unsigned int homeButtonID) { _homeButtonID = homeButtonID; }
|
||||
unsigned int getCurrentHomeButtonUUID() const { return _homeButtonID; }
|
||||
void setCurrentHomeButtonUUID(QUuid homeButtonID) { _homeButtonID = homeButtonID; }
|
||||
QUuid getCurrentHomeButtonUUID() const { return _homeButtonID; }
|
||||
|
||||
void setCurrentTabletScreenID(QUuid tabletID) { _tabletScreenID = tabletID; }
|
||||
QUuid getCurrentTabletScreenID() const { return _tabletScreenID; }
|
||||
|
||||
private:
|
||||
bool _showTablet { false };
|
||||
QUuid _tabletUIID; // this is the entityID of the WebEntity which is part of (a child of) the tablet-ui.
|
||||
unsigned int _homeButtonID;
|
||||
QUuid _tabletUIID; // this is the entityID of the tablet frame
|
||||
QUuid _tabletScreenID; // this is the overlayID which is part of (a child of) the tablet-ui.
|
||||
QUuid _homeButtonID;
|
||||
QUuid _tabletEntityID;
|
||||
|
||||
// Get the position of the HMD
|
||||
|
|
|
@ -23,6 +23,9 @@ public:
|
|||
Base3DOverlay();
|
||||
Base3DOverlay(const Base3DOverlay* base3DOverlay);
|
||||
|
||||
virtual OverlayID getOverlayID() const override { return OverlayID(getID().toString()); }
|
||||
void setOverlayID(OverlayID overlayID) override { setID(overlayID); }
|
||||
|
||||
// getters
|
||||
virtual bool is3D() const override { return true; }
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ float Overlay::updatePulse() {
|
|||
_pulseDirection *= -1.0f;
|
||||
}
|
||||
_pulse += pulseDelta;
|
||||
|
||||
|
||||
return _pulse;
|
||||
}
|
||||
|
||||
|
@ -204,3 +204,23 @@ void Overlay::removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::
|
|||
render::Item::clearID(_renderItemID);
|
||||
}
|
||||
|
||||
QScriptValue OverlayIDtoScriptValue(QScriptEngine* engine, const OverlayID& id) {
|
||||
return quuidToScriptValue(engine, id);
|
||||
}
|
||||
|
||||
void OverlayIDfromScriptValue(const QScriptValue &object, OverlayID& id) {
|
||||
quuidFromScriptValue(object, id);
|
||||
}
|
||||
|
||||
QVector<OverlayID> qVectorOverlayIDFromScriptValue(const QScriptValue& array) {
|
||||
if (!array.isArray()) {
|
||||
return QVector<OverlayID>();
|
||||
}
|
||||
QVector<OverlayID> newVector;
|
||||
int length = array.property("length").toInteger();
|
||||
newVector.reserve(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
newVector << OverlayID(array.property(i).toString());
|
||||
}
|
||||
return newVector;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,13 @@
|
|||
#include <SharedUtil.h> // for xColor
|
||||
#include <render/Scene.h>
|
||||
|
||||
class OverlayID : public QUuid {
|
||||
public:
|
||||
OverlayID() : QUuid() {}
|
||||
OverlayID(QString v) : QUuid(v) {}
|
||||
OverlayID(QUuid v) : QUuid(v) {}
|
||||
};
|
||||
|
||||
class Overlay : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -32,8 +39,8 @@ public:
|
|||
Overlay(const Overlay* overlay);
|
||||
~Overlay();
|
||||
|
||||
unsigned int getOverlayID() { return _overlayID; }
|
||||
void setOverlayID(unsigned int overlayID) { _overlayID = overlayID; }
|
||||
virtual OverlayID getOverlayID() const { return _overlayID; }
|
||||
virtual void setOverlayID(OverlayID overlayID) { _overlayID = overlayID; }
|
||||
|
||||
virtual void update(float deltatime) {}
|
||||
virtual void render(RenderArgs* args) = 0;
|
||||
|
@ -84,13 +91,14 @@ public:
|
|||
render::ItemID getRenderItemID() const { return _renderItemID; }
|
||||
void setRenderItemID(render::ItemID renderItemID) { _renderItemID = renderItemID; }
|
||||
|
||||
unsigned int getStackOrder() const { return _stackOrder; }
|
||||
void setStackOrder(unsigned int stackOrder) { _stackOrder = stackOrder; }
|
||||
|
||||
protected:
|
||||
float updatePulse();
|
||||
|
||||
render::ItemID _renderItemID{ render::Item::INVALID_ITEM_ID };
|
||||
|
||||
unsigned int _overlayID; // what Overlays.cpp knows this instance as
|
||||
|
||||
bool _isLoaded;
|
||||
float _alpha;
|
||||
|
||||
|
@ -107,15 +115,25 @@ protected:
|
|||
xColor _color;
|
||||
bool _visible; // should the overlay be drawn at all
|
||||
Anchor _anchor;
|
||||
|
||||
unsigned int _stackOrder { 0 };
|
||||
|
||||
private:
|
||||
OverlayID _overlayID; // only used for non-3d overlays
|
||||
};
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay);
|
||||
template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay);
|
||||
template <> const Item::Bound payloadGetBound(const Overlay::Pointer& overlay);
|
||||
template <> int payloadGetLayer(const Overlay::Pointer& overlay);
|
||||
template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args);
|
||||
template <> const ShapeKey shapeGetShapeKey(const Overlay::Pointer& overlay);
|
||||
}
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE(OverlayID);
|
||||
Q_DECLARE_METATYPE(QVector<OverlayID>);
|
||||
QScriptValue OverlayIDtoScriptValue(QScriptEngine* engine, const OverlayID& id);
|
||||
void OverlayIDfromScriptValue(const QScriptValue& object, OverlayID& id);
|
||||
QVector<OverlayID> qVectorOverlayIDFromScriptValue(const QScriptValue& array);
|
||||
|
||||
#endif // hifi_Overlay_h
|
||||
|
|
|
@ -51,13 +51,13 @@ void propertyBindingFromVariant(const QVariant& objectVar, PropertyBinding& valu
|
|||
}
|
||||
|
||||
|
||||
void OverlayPanel::addChild(unsigned int childId) {
|
||||
void OverlayPanel::addChild(OverlayID childId) {
|
||||
if (!_children.contains(childId)) {
|
||||
_children.append(childId);
|
||||
}
|
||||
}
|
||||
|
||||
void OverlayPanel::removeChild(unsigned int childId) {
|
||||
void OverlayPanel::removeChild(OverlayID childId) {
|
||||
if (_children.contains(childId)) {
|
||||
_children.removeOne(childId);
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ QVariant OverlayPanel::getProperty(const QString &property) {
|
|||
if (property == "children") {
|
||||
QVariantList array;
|
||||
for (int i = 0; i < _children.length(); i++) {
|
||||
array.append(_children[i]);
|
||||
array.append(OverlayIDtoScriptValue(nullptr, _children[i]).toVariant());
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "PanelAttachable.h"
|
||||
#include "Billboardable.h"
|
||||
#include "Overlay.h"
|
||||
|
||||
class PropertyBinding {
|
||||
public:
|
||||
|
@ -54,10 +55,10 @@ public:
|
|||
void setAnchorScale(const glm::vec3& scale) { _anchorTransform.setScale(scale); }
|
||||
void setVisible(bool visible) { _visible = visible; }
|
||||
|
||||
const QList<unsigned int>& getChildren() { return _children; }
|
||||
void addChild(unsigned int childId);
|
||||
void removeChild(unsigned int childId);
|
||||
unsigned int popLastChild() { return _children.takeLast(); }
|
||||
const QList<OverlayID>& getChildren() { return _children; }
|
||||
void addChild(OverlayID childId);
|
||||
void removeChild(OverlayID childId);
|
||||
OverlayID popLastChild() { return _children.takeLast(); }
|
||||
|
||||
void setProperties(const QVariantMap& properties);
|
||||
QVariant getProperty(const QString& property);
|
||||
|
@ -74,7 +75,7 @@ private:
|
|||
QUuid _anchorRotationBindEntity;
|
||||
|
||||
bool _visible = true;
|
||||
QList<unsigned int> _children;
|
||||
QList<OverlayID> _children;
|
||||
|
||||
QScriptEngine* _scriptEngine;
|
||||
};
|
||||
|
|
|
@ -39,9 +39,6 @@
|
|||
|
||||
Q_LOGGING_CATEGORY(trace_render_overlays, "trace.render.overlays")
|
||||
|
||||
Overlays::Overlays() :
|
||||
_nextOverlayID(1) {}
|
||||
|
||||
void Overlays::cleanupAllOverlays() {
|
||||
{
|
||||
QWriteLocker lock(&_lock);
|
||||
|
@ -139,7 +136,7 @@ void Overlays::enable() {
|
|||
_enabled = true;
|
||||
}
|
||||
|
||||
Overlay::Pointer Overlays::getOverlay(unsigned int id) const {
|
||||
Overlay::Pointer Overlays::getOverlay(OverlayID id) const {
|
||||
if (_overlaysHUD.contains(id)) {
|
||||
return _overlaysHUD[id];
|
||||
}
|
||||
|
@ -149,7 +146,7 @@ Overlay::Pointer Overlays::getOverlay(unsigned int id) const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned int Overlays::addOverlay(const QString& type, const QVariant& properties) {
|
||||
OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties) {
|
||||
Overlay::Pointer thisOverlay = nullptr;
|
||||
|
||||
if (type == ImageOverlay::TYPE) {
|
||||
|
@ -188,14 +185,14 @@ unsigned int Overlays::addOverlay(const QString& type, const QVariant& propertie
|
|||
thisOverlay->setProperties(properties.toMap());
|
||||
return addOverlay(thisOverlay);
|
||||
}
|
||||
return 0;
|
||||
return UNKNOWN_OVERLAY_ID;
|
||||
}
|
||||
|
||||
unsigned int Overlays::addOverlay(Overlay::Pointer overlay) {
|
||||
OverlayID Overlays::addOverlay(Overlay::Pointer overlay) {
|
||||
QWriteLocker lock(&_lock);
|
||||
unsigned int thisID = _nextOverlayID;
|
||||
OverlayID thisID = OverlayID(QUuid::createUuid());
|
||||
overlay->setOverlayID(thisID);
|
||||
_nextOverlayID++;
|
||||
overlay->setStackOrder(_stackOrder++);
|
||||
if (overlay->is3D()) {
|
||||
_overlaysWorld[thisID] = overlay;
|
||||
|
||||
|
@ -210,22 +207,22 @@ unsigned int Overlays::addOverlay(Overlay::Pointer overlay) {
|
|||
return thisID;
|
||||
}
|
||||
|
||||
unsigned int Overlays::cloneOverlay(unsigned int id) {
|
||||
OverlayID Overlays::cloneOverlay(OverlayID id) {
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
|
||||
if (thisOverlay) {
|
||||
unsigned int cloneId = addOverlay(Overlay::Pointer(thisOverlay->createClone()));
|
||||
OverlayID cloneId = addOverlay(Overlay::Pointer(thisOverlay->createClone()));
|
||||
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(thisOverlay);
|
||||
if (attachable && attachable->getParentPanel()) {
|
||||
attachable->getParentPanel()->addChild(cloneId);
|
||||
}
|
||||
return cloneId;
|
||||
}
|
||||
|
||||
return 0; // Not found
|
||||
}
|
||||
|
||||
return UNKNOWN_OVERLAY_ID; // Not found
|
||||
}
|
||||
|
||||
bool Overlays::editOverlay(unsigned int id, const QVariant& properties) {
|
||||
bool Overlays::editOverlay(OverlayID id, const QVariant& properties) {
|
||||
QWriteLocker lock(&_lock);
|
||||
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
|
@ -242,13 +239,7 @@ bool Overlays::editOverlays(const QVariant& propertiesById) {
|
|||
bool success = true;
|
||||
QWriteLocker lock(&_lock);
|
||||
for (const auto& key : map.keys()) {
|
||||
bool convertSuccess;
|
||||
unsigned int id = key.toUInt(&convertSuccess);
|
||||
if (!convertSuccess) {
|
||||
success = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
OverlayID id = OverlayID(key);
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
if (!thisOverlay) {
|
||||
success = false;
|
||||
|
@ -260,7 +251,7 @@ bool Overlays::editOverlays(const QVariant& propertiesById) {
|
|||
return success;
|
||||
}
|
||||
|
||||
void Overlays::deleteOverlay(unsigned int id) {
|
||||
void Overlays::deleteOverlay(OverlayID id) {
|
||||
Overlay::Pointer overlayToDelete;
|
||||
|
||||
{
|
||||
|
@ -286,7 +277,7 @@ void Overlays::deleteOverlay(unsigned int id) {
|
|||
emit overlayDeleted(id);
|
||||
}
|
||||
|
||||
QString Overlays::getOverlayType(unsigned int overlayId) const {
|
||||
QString Overlays::getOverlayType(OverlayID overlayId) const {
|
||||
Overlay::Pointer overlay = getOverlay(overlayId);
|
||||
if (overlay) {
|
||||
return overlay->getType();
|
||||
|
@ -294,7 +285,7 @@ QString Overlays::getOverlayType(unsigned int overlayId) const {
|
|||
return "";
|
||||
}
|
||||
|
||||
QObject* Overlays::getOverlayObject(unsigned int id) {
|
||||
QObject* Overlays::getOverlayObject(OverlayID id) {
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
if (thisOverlay) {
|
||||
return qobject_cast<QObject*>(&(*thisOverlay));
|
||||
|
@ -302,7 +293,7 @@ QObject* Overlays::getOverlayObject(unsigned int id) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned int Overlays::getParentPanel(unsigned int childId) const {
|
||||
OverlayID Overlays::getParentPanel(OverlayID childId) const {
|
||||
Overlay::Pointer overlay = getOverlay(childId);
|
||||
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(overlay);
|
||||
if (attachable) {
|
||||
|
@ -310,10 +301,10 @@ unsigned int Overlays::getParentPanel(unsigned int childId) const {
|
|||
} else if (_panels.contains(childId)) {
|
||||
return _panels.key(getPanel(childId)->getParentPanel());
|
||||
}
|
||||
return 0;
|
||||
return UNKNOWN_OVERLAY_ID;
|
||||
}
|
||||
|
||||
void Overlays::setParentPanel(unsigned int childId, unsigned int panelId) {
|
||||
void Overlays::setParentPanel(OverlayID childId, OverlayID panelId) {
|
||||
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(getOverlay(childId));
|
||||
if (attachable) {
|
||||
if (_panels.contains(panelId)) {
|
||||
|
@ -343,13 +334,13 @@ void Overlays::setParentPanel(unsigned int childId, unsigned int panelId) {
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
||||
OverlayID Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
||||
glm::vec2 pointCopy = point;
|
||||
QReadLocker lock(&_lock);
|
||||
if (!_enabled) {
|
||||
return 0;
|
||||
return UNKNOWN_OVERLAY_ID;
|
||||
}
|
||||
QMapIterator<unsigned int, Overlay::Pointer> i(_overlaysHUD);
|
||||
QMapIterator<OverlayID, Overlay::Pointer> i(_overlaysHUD);
|
||||
i.toBack();
|
||||
|
||||
const float LARGE_NEGATIVE_FLOAT = -9999999;
|
||||
|
@ -358,10 +349,12 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
|||
BoxFace thisFace;
|
||||
glm::vec3 thisSurfaceNormal;
|
||||
float distance;
|
||||
unsigned int bestStackOrder = 0;
|
||||
OverlayID bestOverlayID = UNKNOWN_OVERLAY_ID;
|
||||
|
||||
while (i.hasPrevious()) {
|
||||
i.previous();
|
||||
unsigned int thisID = i.key();
|
||||
OverlayID thisID = i.key();
|
||||
if (i.value()->is3D()) {
|
||||
auto thisOverlay = std::dynamic_pointer_cast<Base3DOverlay>(i.value());
|
||||
if (thisOverlay && !thisOverlay->getIgnoreRayIntersection()) {
|
||||
|
@ -373,15 +366,18 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
|||
auto thisOverlay = std::dynamic_pointer_cast<Overlay2D>(i.value());
|
||||
if (thisOverlay && thisOverlay->getVisible() && thisOverlay->isLoaded() &&
|
||||
thisOverlay->getBoundingRect().contains(pointCopy.x, pointCopy.y, false)) {
|
||||
return thisID;
|
||||
if (thisOverlay->getStackOrder() > bestStackOrder) {
|
||||
bestOverlayID = thisID;
|
||||
bestStackOrder = thisOverlay->getStackOrder();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // not found
|
||||
return bestOverlayID;
|
||||
}
|
||||
|
||||
OverlayPropertyResult Overlays::getProperty(unsigned int id, const QString& property) {
|
||||
OverlayPropertyResult Overlays::getProperty(OverlayID id, const QString& property) {
|
||||
OverlayPropertyResult result;
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
QReadLocker lock(&_lock);
|
||||
|
@ -406,23 +402,35 @@ void OverlayPropertyResultFromScriptValue(const QScriptValue& object, OverlayPro
|
|||
}
|
||||
|
||||
|
||||
RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) {
|
||||
RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray, bool precisionPicking,
|
||||
const QScriptValue& overlayIDsToInclude,
|
||||
const QScriptValue& overlayIDsToDiscard,
|
||||
bool visibleOnly, bool collidableOnly) {
|
||||
float bestDistance = std::numeric_limits<float>::max();
|
||||
bool bestIsFront = false;
|
||||
const QVector<OverlayID> overlaysToInclude = qVectorOverlayIDFromScriptValue(overlayIDsToInclude);
|
||||
const QVector<OverlayID> overlaysToDiscard = qVectorOverlayIDFromScriptValue(overlayIDsToDiscard);
|
||||
|
||||
RayToOverlayIntersectionResult result;
|
||||
QMapIterator<unsigned int, Overlay::Pointer> i(_overlaysWorld);
|
||||
QMapIterator<OverlayID, Overlay::Pointer> i(_overlaysWorld);
|
||||
i.toBack();
|
||||
while (i.hasPrevious()) {
|
||||
i.previous();
|
||||
unsigned int thisID = i.key();
|
||||
OverlayID thisID = i.key();
|
||||
auto thisOverlay = std::dynamic_pointer_cast<Base3DOverlay>(i.value());
|
||||
|
||||
if ((overlaysToDiscard.size() > 0 && overlaysToDiscard.contains(thisID)) ||
|
||||
(overlaysToInclude.size() > 0 && !overlaysToInclude.contains(thisID))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (thisOverlay && thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) {
|
||||
float thisDistance;
|
||||
BoxFace thisFace;
|
||||
glm::vec3 thisSurfaceNormal;
|
||||
QString thisExtraInfo;
|
||||
if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance,
|
||||
thisFace, thisSurfaceNormal, thisExtraInfo)) {
|
||||
if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance,
|
||||
thisFace, thisSurfaceNormal, thisExtraInfo)) {
|
||||
bool isDrawInFront = thisOverlay->getDrawInFront();
|
||||
if (thisDistance < bestDistance && (!bestIsFront || isDrawInFront)) {
|
||||
bestIsFront = isDrawInFront;
|
||||
|
@ -441,23 +449,23 @@ RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray)
|
|||
return result;
|
||||
}
|
||||
|
||||
RayToOverlayIntersectionResult::RayToOverlayIntersectionResult() :
|
||||
intersects(false),
|
||||
overlayID(-1),
|
||||
RayToOverlayIntersectionResult::RayToOverlayIntersectionResult() :
|
||||
intersects(false),
|
||||
overlayID(UNKNOWN_OVERLAY_ID),
|
||||
distance(0),
|
||||
face(),
|
||||
intersection(),
|
||||
extraInfo()
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
QScriptValue RayToOverlayIntersectionResultToScriptValue(QScriptEngine* engine, const RayToOverlayIntersectionResult& value) {
|
||||
auto obj = engine->newObject();
|
||||
obj.setProperty("intersects", value.intersects);
|
||||
obj.setProperty("overlayID", value.overlayID);
|
||||
obj.setProperty("overlayID", OverlayIDtoScriptValue(engine, value.overlayID));
|
||||
obj.setProperty("distance", value.distance);
|
||||
|
||||
QString faceName = "";
|
||||
QString faceName = "";
|
||||
// handle BoxFace
|
||||
switch (value.face) {
|
||||
case MIN_X_FACE:
|
||||
|
@ -493,7 +501,7 @@ QScriptValue RayToOverlayIntersectionResultToScriptValue(QScriptEngine* engine,
|
|||
void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& objectVar, RayToOverlayIntersectionResult& value) {
|
||||
QVariantMap object = objectVar.toVariant().toMap();
|
||||
value.intersects = object["intersects"].toBool();
|
||||
value.overlayID = object["overlayID"].toInt();
|
||||
value.overlayID = OverlayID(QUuid(object["overlayID"].toString()));
|
||||
value.distance = object["distance"].toFloat();
|
||||
|
||||
QString faceName = object["face"].toString();
|
||||
|
@ -523,7 +531,7 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& objectVar
|
|||
value.extraInfo = object["extraInfo"].toString();
|
||||
}
|
||||
|
||||
bool Overlays::isLoaded(unsigned int id) {
|
||||
bool Overlays::isLoaded(OverlayID id) {
|
||||
QReadLocker lock(&_lock);
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
if (!thisOverlay) {
|
||||
|
@ -532,7 +540,7 @@ bool Overlays::isLoaded(unsigned int id) {
|
|||
return thisOverlay->isLoaded();
|
||||
}
|
||||
|
||||
QSizeF Overlays::textSize(unsigned int id, const QString& text) const {
|
||||
QSizeF Overlays::textSize(OverlayID id, const QString& text) const {
|
||||
Overlay::Pointer thisOverlay = _overlaysHUD[id];
|
||||
if (thisOverlay) {
|
||||
if (auto textOverlay = std::dynamic_pointer_cast<TextOverlay>(thisOverlay)) {
|
||||
|
@ -547,30 +555,29 @@ QSizeF Overlays::textSize(unsigned int id, const QString& text) const {
|
|||
return QSizeF(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
unsigned int Overlays::addPanel(OverlayPanel::Pointer panel) {
|
||||
OverlayID Overlays::addPanel(OverlayPanel::Pointer panel) {
|
||||
QWriteLocker lock(&_lock);
|
||||
|
||||
unsigned int thisID = _nextOverlayID;
|
||||
_nextOverlayID++;
|
||||
OverlayID thisID = QUuid::createUuid();
|
||||
_panels[thisID] = panel;
|
||||
|
||||
return thisID;
|
||||
}
|
||||
|
||||
unsigned int Overlays::addPanel(const QVariant& properties) {
|
||||
OverlayID Overlays::addPanel(const QVariant& properties) {
|
||||
OverlayPanel::Pointer panel = std::make_shared<OverlayPanel>();
|
||||
panel->init(_scriptEngine);
|
||||
panel->setProperties(properties.toMap());
|
||||
return addPanel(panel);
|
||||
}
|
||||
|
||||
void Overlays::editPanel(unsigned int panelId, const QVariant& properties) {
|
||||
void Overlays::editPanel(OverlayID panelId, const QVariant& properties) {
|
||||
if (_panels.contains(panelId)) {
|
||||
_panels[panelId]->setProperties(properties.toMap());
|
||||
}
|
||||
}
|
||||
|
||||
OverlayPropertyResult Overlays::getPanelProperty(unsigned int panelId, const QString& property) {
|
||||
OverlayPropertyResult Overlays::getPanelProperty(OverlayID panelId, const QString& property) {
|
||||
OverlayPropertyResult result;
|
||||
if (_panels.contains(panelId)) {
|
||||
OverlayPanel::Pointer thisPanel = getPanel(panelId);
|
||||
|
@ -581,7 +588,7 @@ OverlayPropertyResult Overlays::getPanelProperty(unsigned int panelId, const QSt
|
|||
}
|
||||
|
||||
|
||||
void Overlays::deletePanel(unsigned int panelId) {
|
||||
void Overlays::deletePanel(OverlayID panelId) {
|
||||
OverlayPanel::Pointer panelToDelete;
|
||||
|
||||
{
|
||||
|
@ -594,7 +601,7 @@ void Overlays::deletePanel(unsigned int panelId) {
|
|||
}
|
||||
|
||||
while (!panelToDelete->getChildren().isEmpty()) {
|
||||
unsigned int childId = panelToDelete->popLastChild();
|
||||
OverlayID childId = panelToDelete->popLastChild();
|
||||
deleteOverlay(childId);
|
||||
deletePanel(childId);
|
||||
}
|
||||
|
@ -602,39 +609,39 @@ void Overlays::deletePanel(unsigned int panelId) {
|
|||
emit panelDeleted(panelId);
|
||||
}
|
||||
|
||||
bool Overlays::isAddedOverlay(unsigned int id) {
|
||||
bool Overlays::isAddedOverlay(OverlayID id) {
|
||||
return _overlaysHUD.contains(id) || _overlaysWorld.contains(id);
|
||||
}
|
||||
|
||||
void Overlays::sendMousePressOnOverlay(unsigned int overlayID, const PointerEvent& event) {
|
||||
void Overlays::sendMousePressOnOverlay(OverlayID overlayID, const PointerEvent& event) {
|
||||
emit mousePressOnOverlay(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendMouseReleaseOnOverlay(unsigned int overlayID, const PointerEvent& event) {
|
||||
void Overlays::sendMouseReleaseOnOverlay(OverlayID overlayID, const PointerEvent& event) {
|
||||
emit mouseReleaseOnOverlay(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendMouseMoveOnOverlay(unsigned int overlayID, const PointerEvent& event) {
|
||||
void Overlays::sendMouseMoveOnOverlay(OverlayID overlayID, const PointerEvent& event) {
|
||||
emit mouseMoveOnOverlay(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendHoverEnterOverlay(unsigned int id, PointerEvent event) {
|
||||
void Overlays::sendHoverEnterOverlay(OverlayID id, PointerEvent event) {
|
||||
emit hoverEnterOverlay(id, event);
|
||||
}
|
||||
|
||||
void Overlays::sendHoverOverOverlay(unsigned int id, PointerEvent event) {
|
||||
void Overlays::sendHoverOverOverlay(OverlayID id, PointerEvent event) {
|
||||
emit hoverOverOverlay(id, event);
|
||||
}
|
||||
|
||||
void Overlays::sendHoverLeaveOverlay(unsigned int id, PointerEvent event) {
|
||||
void Overlays::sendHoverLeaveOverlay(OverlayID id, PointerEvent event) {
|
||||
emit hoverLeaveOverlay(id, event);
|
||||
}
|
||||
|
||||
unsigned int Overlays::getKeyboardFocusOverlay() const {
|
||||
OverlayID Overlays::getKeyboardFocusOverlay() const {
|
||||
return qApp->getKeyboardFocusOverlay();
|
||||
}
|
||||
|
||||
void Overlays::setKeyboardFocusOverlay(unsigned int id) {
|
||||
void Overlays::setKeyboardFocusOverlay(OverlayID id) {
|
||||
qApp->setKeyboardFocusOverlay(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ class RayToOverlayIntersectionResult {
|
|||
public:
|
||||
RayToOverlayIntersectionResult();
|
||||
bool intersects;
|
||||
unsigned int overlayID;
|
||||
OverlayID overlayID;
|
||||
float distance;
|
||||
BoxFace face;
|
||||
glm::vec3 surfaceNormal;
|
||||
|
@ -77,15 +77,15 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R
|
|||
* @namespace Overlays
|
||||
*/
|
||||
|
||||
const unsigned int UNKNOWN_OVERLAY_ID = 0;
|
||||
const OverlayID UNKNOWN_OVERLAY_ID = OverlayID();
|
||||
|
||||
class Overlays : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(unsigned int keyboardFocusOverlay READ getKeyboardFocusOverlay WRITE setKeyboardFocusOverlay)
|
||||
Q_PROPERTY(OverlayID keyboardFocusOverlay READ getKeyboardFocusOverlay WRITE setKeyboardFocusOverlay)
|
||||
|
||||
public:
|
||||
Overlays();
|
||||
Overlays() {};
|
||||
|
||||
void init();
|
||||
void update(float deltatime);
|
||||
|
@ -93,12 +93,12 @@ public:
|
|||
void disable();
|
||||
void enable();
|
||||
|
||||
Overlay::Pointer getOverlay(unsigned int id) const;
|
||||
OverlayPanel::Pointer getPanel(unsigned int id) const { return _panels[id]; }
|
||||
Overlay::Pointer getOverlay(OverlayID id) const;
|
||||
OverlayPanel::Pointer getPanel(OverlayID id) const { return _panels[id]; }
|
||||
|
||||
/// adds an overlay that's already been created
|
||||
unsigned int addOverlay(Overlay* overlay) { return addOverlay(Overlay::Pointer(overlay)); }
|
||||
unsigned int addOverlay(Overlay::Pointer overlay);
|
||||
OverlayID addOverlay(Overlay* overlay) { return addOverlay(Overlay::Pointer(overlay)); }
|
||||
OverlayID addOverlay(Overlay::Pointer overlay);
|
||||
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
|
@ -116,7 +116,7 @@ public slots:
|
|||
* @param {Overlays.OverlayProperties} The properties of the overlay that you want to add.
|
||||
* @return {Overlays.OverlayID} The ID of the newly created overlay.
|
||||
*/
|
||||
unsigned int addOverlay(const QString& type, const QVariant& properties);
|
||||
OverlayID addOverlay(const QString& type, const QVariant& properties);
|
||||
|
||||
/**jsdoc
|
||||
* Create a clone of an existing overlay.
|
||||
|
@ -125,7 +125,7 @@ public slots:
|
|||
* @param {Overlays.OverlayID} overlayID The ID of the overlay to clone.
|
||||
* @return {Overlays.OverlayID} The ID of the new overlay.
|
||||
*/
|
||||
unsigned int cloneOverlay(unsigned int id);
|
||||
OverlayID cloneOverlay(OverlayID id);
|
||||
|
||||
/**jsdoc
|
||||
* Edit an overlay's properties.
|
||||
|
@ -134,7 +134,7 @@ public slots:
|
|||
* @param {Overlays.OverlayID} overlayID The ID of the overlay to edit.
|
||||
* @return {bool} `true` if the overlay was found and edited, otherwise false.
|
||||
*/
|
||||
bool editOverlay(unsigned int id, const QVariant& properties);
|
||||
bool editOverlay(OverlayID id, const QVariant& properties);
|
||||
|
||||
/// edits an overlay updating only the included properties, will return the identified OverlayID in case of
|
||||
/// successful edit, if the input id is for an unknown overlay this function will have no effect
|
||||
|
@ -146,7 +146,7 @@ public slots:
|
|||
* @function Overlays.deleteOverlay
|
||||
* @param {Overlays.OverlayID} overlayID The ID of the overlay to delete.
|
||||
*/
|
||||
void deleteOverlay(unsigned int id);
|
||||
void deleteOverlay(OverlayID id);
|
||||
|
||||
/**jsdoc
|
||||
* Get the type of an overlay.
|
||||
|
@ -155,7 +155,7 @@ public slots:
|
|||
* @param {Overlays.OverlayID} overlayID The ID of the overlay to get the type of.
|
||||
* @return {string} The type of the overlay if found, otherwise the empty string.
|
||||
*/
|
||||
QString getOverlayType(unsigned int overlayId) const;
|
||||
QString getOverlayType(OverlayID overlayId) const;
|
||||
|
||||
/**jsdoc
|
||||
* Get the overlay Script object.
|
||||
|
@ -164,7 +164,7 @@ public slots:
|
|||
* @param {Overlays.OverlayID} overlayID The ID of the overlay to get the script object of.
|
||||
* @return {Object} The script object for the overlay if found.
|
||||
*/
|
||||
QObject* getOverlayObject(unsigned int id);
|
||||
QObject* getOverlayObject(OverlayID id);
|
||||
|
||||
/**jsdoc
|
||||
* Get the ID of the overlay at a particular point on the HUD/screen.
|
||||
|
@ -174,7 +174,7 @@ public slots:
|
|||
* @return {Overlays.OverlayID} The ID of the overlay at the point specified.
|
||||
* If no overlay is found, `0` will be returned.
|
||||
*/
|
||||
unsigned int getOverlayAtPoint(const glm::vec2& point);
|
||||
OverlayID getOverlayAtPoint(const glm::vec2& point);
|
||||
|
||||
/**jsdoc
|
||||
* Get the value of a an overlay's property.
|
||||
|
@ -185,16 +185,26 @@ public slots:
|
|||
* @return {Object} The value of the property. If the overlay or the property could
|
||||
* not be found, `undefined` will be returned.
|
||||
*/
|
||||
OverlayPropertyResult getProperty(unsigned int id, const QString& property);
|
||||
OverlayPropertyResult getProperty(OverlayID id, const QString& property);
|
||||
|
||||
/*jsdoc
|
||||
* Find the closest 3D overlay hit by a pick ray.
|
||||
*
|
||||
* @function Overlays.findRayIntersection
|
||||
* @param {PickRay} The PickRay to use for finding overlays.
|
||||
* @param {bool} Unused; Exists to match Entity interface
|
||||
* @param {List of Overlays.OverlayID} Whitelist for intersection test.
|
||||
* @param {List of Overlays.OverlayID} Blacklist for intersection test.
|
||||
* @param {bool} Unused; Exists to match Entity interface
|
||||
* @param {bool} Unused; Exists to match Entity interface
|
||||
* @return {Overlays.RayToOverlayIntersectionResult} The result of the ray cast.
|
||||
*/
|
||||
RayToOverlayIntersectionResult findRayIntersection(const PickRay& ray);
|
||||
RayToOverlayIntersectionResult findRayIntersection(const PickRay& ray,
|
||||
bool precisionPicking = false,
|
||||
const QScriptValue& overlayIDsToInclude = QScriptValue(),
|
||||
const QScriptValue& overlayIDsToDiscard = QScriptValue(),
|
||||
bool visibleOnly = false,
|
||||
bool collidableOnly = false);
|
||||
|
||||
/**jsdoc
|
||||
* Check whether an overlay's assets have been loaded. For example, if the
|
||||
|
@ -204,7 +214,7 @@ public slots:
|
|||
* @param {Overlays.OverlayID} The ID of the overlay to check.
|
||||
* @return {bool} `true` if the overlay's assets have been loaded, otherwise `false`.
|
||||
*/
|
||||
bool isLoaded(unsigned int id);
|
||||
bool isLoaded(OverlayID id);
|
||||
|
||||
/**jsdoc
|
||||
* Calculates the size of the given text in the specified overlay if it is a text overlay.
|
||||
|
@ -216,7 +226,7 @@ public slots:
|
|||
* @param {string} The string to measure.
|
||||
* @return {Vec2} The size of the text.
|
||||
*/
|
||||
QSizeF textSize(unsigned int id, const QString& text) const;
|
||||
QSizeF textSize(OverlayID id, const QString& text) const;
|
||||
|
||||
/**jsdoc
|
||||
* Get the width of the virtual 2D HUD.
|
||||
|
@ -235,39 +245,39 @@ public slots:
|
|||
float height() const;
|
||||
|
||||
/// return true if there is an overlay with that id else false
|
||||
bool isAddedOverlay(unsigned int id);
|
||||
bool isAddedOverlay(OverlayID id);
|
||||
|
||||
unsigned int getParentPanel(unsigned int childId) const;
|
||||
void setParentPanel(unsigned int childId, unsigned int panelId);
|
||||
OverlayID getParentPanel(OverlayID childId) const;
|
||||
void setParentPanel(OverlayID childId, OverlayID panelId);
|
||||
|
||||
/// adds a panel that has already been created
|
||||
unsigned int addPanel(OverlayPanel::Pointer panel);
|
||||
OverlayID addPanel(OverlayPanel::Pointer panel);
|
||||
|
||||
/// creates and adds a panel based on a set of properties
|
||||
unsigned int addPanel(const QVariant& properties);
|
||||
OverlayID addPanel(const QVariant& properties);
|
||||
|
||||
/// edit the properties of a panel
|
||||
void editPanel(unsigned int panelId, const QVariant& properties);
|
||||
void editPanel(OverlayID panelId, const QVariant& properties);
|
||||
|
||||
/// get a property of a panel
|
||||
OverlayPropertyResult getPanelProperty(unsigned int panelId, const QString& property);
|
||||
OverlayPropertyResult getPanelProperty(OverlayID panelId, const QString& property);
|
||||
|
||||
/// deletes a panel and all child overlays
|
||||
void deletePanel(unsigned int panelId);
|
||||
void deletePanel(OverlayID panelId);
|
||||
|
||||
/// return true if there is a panel with that id else false
|
||||
bool isAddedPanel(unsigned int id) { return _panels.contains(id); }
|
||||
bool isAddedPanel(OverlayID id) { return _panels.contains(id); }
|
||||
|
||||
void sendMousePressOnOverlay(unsigned int overlayID, const PointerEvent& event);
|
||||
void sendMouseReleaseOnOverlay(unsigned int overlayID, const PointerEvent& event);
|
||||
void sendMouseMoveOnOverlay(unsigned int overlayID, const PointerEvent& event);
|
||||
void sendMousePressOnOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void sendMouseReleaseOnOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void sendMouseMoveOnOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
|
||||
void sendHoverEnterOverlay(unsigned int id, PointerEvent event);
|
||||
void sendHoverOverOverlay(unsigned int id, PointerEvent event);
|
||||
void sendHoverLeaveOverlay(unsigned int id, PointerEvent event);
|
||||
void sendHoverEnterOverlay(OverlayID id, PointerEvent event);
|
||||
void sendHoverOverOverlay(OverlayID id, PointerEvent event);
|
||||
void sendHoverLeaveOverlay(OverlayID id, PointerEvent event);
|
||||
|
||||
unsigned int getKeyboardFocusOverlay() const;
|
||||
void setKeyboardFocusOverlay(unsigned int id);
|
||||
OverlayID getKeyboardFocusOverlay() const;
|
||||
void setKeyboardFocusOverlay(OverlayID id);
|
||||
|
||||
signals:
|
||||
/**jsdoc
|
||||
|
@ -276,26 +286,26 @@ signals:
|
|||
* @function Overlays.overlayDeleted
|
||||
* @param {OverlayID} The ID of the overlay that was deleted.
|
||||
*/
|
||||
void overlayDeleted(unsigned int id);
|
||||
void panelDeleted(unsigned int id);
|
||||
void overlayDeleted(OverlayID id);
|
||||
void panelDeleted(OverlayID id);
|
||||
|
||||
void mousePressOnOverlay(unsigned int overlayID, const PointerEvent& event);
|
||||
void mouseReleaseOnOverlay(unsigned int overlayID, const PointerEvent& event);
|
||||
void mouseMoveOnOverlay(unsigned int overlayID, const PointerEvent& event);
|
||||
void mousePressOnOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void mouseReleaseOnOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void mouseMoveOnOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void mousePressOffOverlay();
|
||||
|
||||
void hoverEnterOverlay(unsigned int overlayID, const PointerEvent& event);
|
||||
void hoverOverOverlay(unsigned int overlayID, const PointerEvent& event);
|
||||
void hoverLeaveOverlay(unsigned int overlayID, const PointerEvent& event);
|
||||
void hoverEnterOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void hoverOverOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void hoverLeaveOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
|
||||
private:
|
||||
void cleanupOverlaysToDelete();
|
||||
|
||||
QMap<unsigned int, Overlay::Pointer> _overlaysHUD;
|
||||
QMap<unsigned int, Overlay::Pointer> _overlaysWorld;
|
||||
QMap<unsigned int, OverlayPanel::Pointer> _panels;
|
||||
QMap<OverlayID, Overlay::Pointer> _overlaysHUD;
|
||||
QMap<OverlayID, Overlay::Pointer> _overlaysWorld;
|
||||
QMap<OverlayID, OverlayPanel::Pointer> _panels;
|
||||
QList<Overlay::Pointer> _overlaysToDelete;
|
||||
unsigned int _nextOverlayID;
|
||||
unsigned int _stackOrder { 1 };
|
||||
|
||||
QReadWriteLock _lock;
|
||||
QReadWriteLock _deleteLock;
|
||||
|
@ -305,8 +315,8 @@ private:
|
|||
PointerEvent calculatePointerEvent(Overlay::Pointer overlay, PickRay ray, RayToOverlayIntersectionResult rayPickResult,
|
||||
QMouseEvent* event, PointerEvent::EventType eventType);
|
||||
|
||||
unsigned int _currentClickingOnOverlayID { UNKNOWN_OVERLAY_ID };
|
||||
unsigned int _currentHoverOverOverlayID { UNKNOWN_OVERLAY_ID };
|
||||
OverlayID _currentClickingOnOverlayID { UNKNOWN_OVERLAY_ID };
|
||||
OverlayID _currentHoverOverOverlayID { UNKNOWN_OVERLAY_ID };
|
||||
};
|
||||
|
||||
#endif // hifi_Overlays_h
|
||||
|
|
|
@ -202,7 +202,7 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
_webSurface->getRootItem()->setProperty("scriptURL", _scriptURL);
|
||||
currentContext->makeCurrent(currentSurface);
|
||||
|
||||
auto forwardPointerEvent = [=](unsigned int overlayID, const PointerEvent& event) {
|
||||
auto forwardPointerEvent = [=](OverlayID overlayID, const PointerEvent& event) {
|
||||
if (overlayID == getOverlayID()) {
|
||||
handlePointerEvent(event);
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
_mouseReleaseConnection = connect(&(qApp->getOverlays()), &Overlays::mouseReleaseOnOverlay, forwardPointerEvent);
|
||||
_mouseMoveConnection = connect(&(qApp->getOverlays()), &Overlays::mouseMoveOnOverlay, forwardPointerEvent);
|
||||
_hoverLeaveConnection = connect(&(qApp->getOverlays()), &Overlays::hoverLeaveOverlay,
|
||||
[=](unsigned int overlayID, const PointerEvent& event) {
|
||||
[=](OverlayID overlayID, const PointerEvent& event) {
|
||||
if (this->_pressed && this->getOverlayID() == overlayID) {
|
||||
// If the user mouses off the overlay while the button is down, simulate a touch end.
|
||||
QTouchEvent::TouchPoint point;
|
||||
|
|
|
@ -172,7 +172,7 @@ static const char* WEB_VIEW_SOURCE_URL = "TabletWebView.qml";
|
|||
static const char* VRMENU_SOURCE_URL = "TabletMenu.qml";
|
||||
|
||||
class TabletRootWindow : public QmlWindowClass {
|
||||
virtual QString qmlSource() const { return "hifi/tablet/WindowRoot.qml"; }
|
||||
virtual QString qmlSource() const override { return "hifi/tablet/WindowRoot.qml"; }
|
||||
};
|
||||
|
||||
TabletProxy::TabletProxy(QString name) : _name(name) {
|
||||
|
|
|
@ -480,6 +480,10 @@ var LASER_SEARCH_COLOR_XYZW = {x: 10 / 255, y: 10 / 255, z: 255 / 255, w: LASER_
|
|||
var LASER_TRIGGER_COLOR_XYZW = {x: 250 / 255, y: 10 / 255, z: 10 / 255, w: LASER_ALPHA};
|
||||
var SYSTEM_LASER_DIRECTION = {x: 0, y: 0, z: -1};
|
||||
var systemLaserOn = false;
|
||||
|
||||
var HIFI_POINTER_DISABLE_MESSAGE_CHANNEL = "Hifi-Pointer-Disable";
|
||||
var isPointerEnabled = true;
|
||||
|
||||
function clearSystemLaser() {
|
||||
if (!systemLaserOn) {
|
||||
return;
|
||||
|
@ -542,9 +546,8 @@ function update() {
|
|||
return off();
|
||||
}
|
||||
|
||||
|
||||
// If there's a HUD element at the (newly moved) reticle, just make it visible and bail.
|
||||
if (isPointingAtOverlay(hudPoint2d)) {
|
||||
if (isPointingAtOverlay(hudPoint2d) && isPointerEnabled) {
|
||||
if (HMD.active) {
|
||||
Reticle.depth = hudReticleDistance();
|
||||
|
||||
|
@ -579,9 +582,25 @@ function checkSettings() {
|
|||
}
|
||||
checkSettings();
|
||||
|
||||
// Enable/disable pointer.
|
||||
function handleMessages(channel, message, sender) {
|
||||
if (sender === MyAvatar.sessionUUID && channel === HIFI_POINTER_DISABLE_MESSAGE_CHANNEL) {
|
||||
var data = JSON.parse(message);
|
||||
if (data.pointerEnabled !== undefined) {
|
||||
print("pointerEnabled: " + data.pointerEnabled);
|
||||
isPointerEnabled = data.pointerEnabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Messages.subscribe(HIFI_POINTER_DISABLE_MESSAGE_CHANNEL);
|
||||
Messages.messageReceived.connect(handleMessages);
|
||||
|
||||
var settingsChecker = Script.setInterval(checkSettings, SETTINGS_CHANGE_RECHECK_INTERVAL);
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(function () {
|
||||
Messages.unsubscribe(HIFI_POINTER_DISABLE_MESSAGE_CHANNEL);
|
||||
Messages.messageReceived.disconnect(handleMessages);
|
||||
Script.clearInterval(settingsChecker);
|
||||
Script.update.disconnect(update);
|
||||
OffscreenFlags.navigationFocusDisabled = false;
|
||||
|
|
|
@ -25,6 +25,11 @@ var OVERLAY_RAMP_RATE = 8.0;
|
|||
|
||||
var animStateHandlerID;
|
||||
|
||||
var isPointingIndex = false;
|
||||
var HIFI_POINT_INDEX_MESSAGE_CHANNEL = "Hifi-Point-Index";
|
||||
|
||||
var indexfingerJointNames = ["LeftHandIndex1", "LeftHandIndex2", "LeftHandIndex3", "RightHandIndex1", "RightHandIndex2", "RightHandIndex3"];
|
||||
|
||||
function clamp(val, min, max) {
|
||||
return Math.min(Math.max(val, min), max);
|
||||
}
|
||||
|
@ -43,6 +48,8 @@ function init() {
|
|||
animStateHandler,
|
||||
["leftHandOverlayAlpha", "rightHandOverlayAlpha", "leftHandGraspAlpha", "rightHandGraspAlpha"]
|
||||
);
|
||||
Messages.subscribe(HIFI_POINT_INDEX_MESSAGE_CHANNEL);
|
||||
Messages.messageReceived.connect(handleMessages);
|
||||
}
|
||||
|
||||
function animStateHandler(props) {
|
||||
|
@ -76,11 +83,37 @@ function update(dt) {
|
|||
} else {
|
||||
rightHandOverlayAlpha = clamp(rightHandOverlayAlpha - OVERLAY_RAMP_RATE * dt, 0, 1);
|
||||
}
|
||||
|
||||
// Point index finger.
|
||||
if (isPointingIndex) {
|
||||
var zeroRotation = { x: 0, y: 0, z: 0, w: 1 };
|
||||
for (var i = 0; i < indexfingerJointNames.length; i++) {
|
||||
MyAvatar.setJointRotation(indexfingerJointNames[i], zeroRotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleMessages(channel, message, sender) {
|
||||
if (sender === MyAvatar.sessionUUID && channel === HIFI_POINT_INDEX_MESSAGE_CHANNEL) {
|
||||
var data = JSON.parse(message);
|
||||
if (data.pointIndex !== undefined) {
|
||||
print("pointIndex: " + data.pointIndex);
|
||||
isPointingIndex = data.pointIndex;
|
||||
|
||||
if (!isPointingIndex) {
|
||||
for (var i = 0; i < indexfingerJointNames.length; i++) {
|
||||
MyAvatar.clearJointData(indexfingerJointNames[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function shutdown() {
|
||||
Script.update.disconnect(update);
|
||||
MyAvatar.removeAnimationStateHandler(animStateHandlerID);
|
||||
Messages.unsubscribe(HIFI_POINT_INDEX_MESSAGE_CHANNEL);
|
||||
Messages.messageReceived.disconnect(handleMessages);
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(shutdown);
|
||||
|
|
433
scripts/system/fingerPaint.js
Normal file
433
scripts/system/fingerPaint.js
Normal file
|
@ -0,0 +1,433 @@
|
|||
//
|
||||
// fingerPaint.js
|
||||
//
|
||||
// Created by David Rowe on 15 Feb 2017
|
||||
// Copyright 2017 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 () {
|
||||
var tablet,
|
||||
button,
|
||||
BUTTON_NAME = "PAINT",
|
||||
isFingerPainting = false,
|
||||
leftHand = null,
|
||||
rightHand = null,
|
||||
leftBrush = null,
|
||||
rightBrush = null,
|
||||
CONTROLLER_MAPPING_NAME = "com.highfidelity.fingerPaint",
|
||||
isTabletDisplayed = false,
|
||||
HIFI_POINT_INDEX_MESSAGE_CHANNEL = "Hifi-Point-Index",
|
||||
HIFI_GRAB_DISABLE_MESSAGE_CHANNEL = "Hifi-Grab-Disable",
|
||||
HIFI_POINTER_DISABLE_MESSAGE_CHANNEL = "Hifi-Pointer-Disable";
|
||||
|
||||
function paintBrush(name) {
|
||||
// Paints in 3D.
|
||||
var brushName = name,
|
||||
STROKE_COLOR = { red: 250, green: 0, blue: 0 },
|
||||
ERASE_SEARCH_RADIUS = 0.1, // m
|
||||
isDrawingLine = false,
|
||||
entityID,
|
||||
basePosition,
|
||||
strokePoints,
|
||||
strokeNormals,
|
||||
strokeWidths,
|
||||
timeOfLastPoint,
|
||||
MIN_STROKE_LENGTH = 0.005, // m
|
||||
MIN_STROKE_INTERVAL = 66, // ms
|
||||
MAX_POINTS_PER_LINE = 70; // Hard-coded limit in PolyLineEntityItem.h.
|
||||
|
||||
function strokeNormal() {
|
||||
return Vec3.multiplyQbyV(Camera.getOrientation(), Vec3.UNIT_NEG_Z);
|
||||
}
|
||||
|
||||
function startLine(position, width) {
|
||||
// Start drawing a polyline.
|
||||
|
||||
if (isDrawingLine) {
|
||||
print("ERROR: startLine() called when already drawing line");
|
||||
// Nevertheless, continue on and start a new line.
|
||||
}
|
||||
|
||||
basePosition = position;
|
||||
|
||||
strokePoints = [Vec3.ZERO];
|
||||
strokeNormals = [strokeNormal()];
|
||||
strokeWidths = [width];
|
||||
timeOfLastPoint = Date.now();
|
||||
|
||||
entityID = Entities.addEntity({
|
||||
type: "PolyLine",
|
||||
name: "fingerPainting",
|
||||
color: STROKE_COLOR,
|
||||
position: position,
|
||||
linePoints: strokePoints,
|
||||
normals: strokeNormals,
|
||||
strokeWidths: strokeWidths,
|
||||
dimensions: { x: 10, y: 10, z: 10 }
|
||||
});
|
||||
|
||||
isDrawingLine = true;
|
||||
}
|
||||
|
||||
function drawLine(position, width) {
|
||||
// Add a stroke to the polyline if stroke is a sufficient length.
|
||||
var localPosition,
|
||||
distanceToPrevious,
|
||||
MAX_DISTANCE_TO_PREVIOUS = 1.0;
|
||||
|
||||
if (!isDrawingLine) {
|
||||
print("ERROR: drawLine() called when not drawing line");
|
||||
return;
|
||||
}
|
||||
|
||||
localPosition = Vec3.subtract(position, basePosition);
|
||||
distanceToPrevious = Vec3.distance(localPosition, strokePoints[strokePoints.length - 1]);
|
||||
|
||||
if (distanceToPrevious > MAX_DISTANCE_TO_PREVIOUS) {
|
||||
// Ignore occasional spurious finger tip positions.
|
||||
return;
|
||||
}
|
||||
|
||||
if (distanceToPrevious >= MIN_STROKE_LENGTH
|
||||
&& (Date.now() - timeOfLastPoint) >= MIN_STROKE_INTERVAL
|
||||
&& strokePoints.length < MAX_POINTS_PER_LINE) {
|
||||
strokePoints.push(localPosition);
|
||||
strokeNormals.push(strokeNormal());
|
||||
strokeWidths.push(width);
|
||||
timeOfLastPoint = Date.now();
|
||||
|
||||
Entities.editEntity(entityID, {
|
||||
linePoints: strokePoints,
|
||||
normals: strokeNormals,
|
||||
strokeWidths: strokeWidths
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function finishLine(position, width) {
|
||||
// Finish drawing polyline; delete if it has only 1 point.
|
||||
|
||||
if (!isDrawingLine) {
|
||||
print("ERROR: finishLine() called when not drawing line");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strokePoints.length === 1) {
|
||||
// Delete "empty" line.
|
||||
Entities.deleteEntity(entityID);
|
||||
}
|
||||
|
||||
isDrawingLine = false;
|
||||
}
|
||||
|
||||
function cancelLine() {
|
||||
// Cancel any line being drawn.
|
||||
if (isDrawingLine) {
|
||||
Entities.deleteEntity(entityID);
|
||||
isDrawingLine = false;
|
||||
}
|
||||
}
|
||||
|
||||
function eraseClosestLine(position) {
|
||||
// Erase closest line that is within search radius of finger tip.
|
||||
var entities,
|
||||
entitiesLength,
|
||||
properties,
|
||||
i,
|
||||
pointsLength,
|
||||
j,
|
||||
distance,
|
||||
found = false,
|
||||
foundID,
|
||||
foundDistance = ERASE_SEARCH_RADIUS;
|
||||
|
||||
// Find entities with bounding box within search radius.
|
||||
entities = Entities.findEntities(position, ERASE_SEARCH_RADIUS);
|
||||
|
||||
// Fine polyline entity with closest point within search radius.
|
||||
for (i = 0, entitiesLength = entities.length; i < entitiesLength; i += 1) {
|
||||
properties = Entities.getEntityProperties(entities[i], ["type", "position", "linePoints"]);
|
||||
if (properties.type === "PolyLine") {
|
||||
basePosition = properties.position;
|
||||
for (j = 0, pointsLength = properties.linePoints.length; j < pointsLength; j += 1) {
|
||||
distance = Vec3.distance(position, Vec3.sum(basePosition, properties.linePoints[j]));
|
||||
if (distance <= foundDistance) {
|
||||
found = true;
|
||||
foundID = entities[i];
|
||||
foundDistance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete found entity.
|
||||
if (found) {
|
||||
Entities.deleteEntity(foundID);
|
||||
}
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
cancelLine();
|
||||
}
|
||||
|
||||
return {
|
||||
startLine: startLine,
|
||||
drawLine: drawLine,
|
||||
finishLine: finishLine,
|
||||
cancelLine: cancelLine,
|
||||
eraseClosestLine: eraseClosestLine,
|
||||
tearDown: tearDown
|
||||
};
|
||||
}
|
||||
|
||||
function handController(name) {
|
||||
// Translates controller data into application events.
|
||||
var handName = name,
|
||||
|
||||
triggerPressedCallback,
|
||||
triggerPressingCallback,
|
||||
triggerReleasedCallback,
|
||||
gripPressedCallback,
|
||||
|
||||
rawTriggerValue = 0.0,
|
||||
triggerValue = 0.0,
|
||||
isTriggerPressed = false,
|
||||
TRIGGER_SMOOTH_RATIO = 0.1,
|
||||
TRIGGER_OFF = 0.05,
|
||||
TRIGGER_ON = 0.1,
|
||||
TRIGGER_START_WIDTH_RAMP = 0.15,
|
||||
TRIGGER_FINISH_WIDTH_RAMP = 1.0,
|
||||
TRIGGER_RAMP_WIDTH = TRIGGER_FINISH_WIDTH_RAMP - TRIGGER_START_WIDTH_RAMP,
|
||||
MIN_LINE_WIDTH = 0.005,
|
||||
MAX_LINE_WIDTH = 0.03,
|
||||
RAMP_LINE_WIDTH = MAX_LINE_WIDTH - MIN_LINE_WIDTH,
|
||||
|
||||
rawGripValue = 0.0,
|
||||
gripValue = 0.0,
|
||||
isGripPressed = false,
|
||||
GRIP_SMOOTH_RATIO = 0.1,
|
||||
GRIP_OFF = 0.05,
|
||||
GRIP_ON = 0.1;
|
||||
|
||||
function onTriggerPress(value) {
|
||||
// Controller values are only updated when they change so store latest for use in update.
|
||||
rawTriggerValue = value;
|
||||
}
|
||||
|
||||
function updateTriggerPress(value) {
|
||||
var wasTriggerPressed,
|
||||
fingerTipPosition,
|
||||
lineWidth;
|
||||
|
||||
triggerValue = triggerValue * TRIGGER_SMOOTH_RATIO + rawTriggerValue * (1.0 - TRIGGER_SMOOTH_RATIO);
|
||||
|
||||
wasTriggerPressed = isTriggerPressed;
|
||||
if (isTriggerPressed) {
|
||||
isTriggerPressed = triggerValue > TRIGGER_OFF;
|
||||
} else {
|
||||
isTriggerPressed = triggerValue > TRIGGER_ON;
|
||||
}
|
||||
|
||||
if (wasTriggerPressed || isTriggerPressed) {
|
||||
fingerTipPosition = MyAvatar.getJointPosition(handName === "left" ? "LeftHandIndex4" : "RightHandIndex4");
|
||||
if (triggerValue < TRIGGER_START_WIDTH_RAMP) {
|
||||
lineWidth = MIN_LINE_WIDTH;
|
||||
} else {
|
||||
lineWidth = MIN_LINE_WIDTH
|
||||
+ (triggerValue - TRIGGER_START_WIDTH_RAMP) / TRIGGER_RAMP_WIDTH * RAMP_LINE_WIDTH;
|
||||
}
|
||||
|
||||
if (!wasTriggerPressed && isTriggerPressed) {
|
||||
triggerPressedCallback(fingerTipPosition, lineWidth);
|
||||
} else if (wasTriggerPressed && isTriggerPressed) {
|
||||
triggerPressingCallback(fingerTipPosition, lineWidth);
|
||||
} else {
|
||||
triggerReleasedCallback(fingerTipPosition, lineWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onGripPress(value) {
|
||||
// Controller values are only updated when they change so store latest for use in update.
|
||||
rawGripValue = value;
|
||||
}
|
||||
|
||||
function updateGripPress() {
|
||||
var fingerTipPosition;
|
||||
|
||||
gripValue = gripValue * GRIP_SMOOTH_RATIO + rawGripValue * (1.0 - GRIP_SMOOTH_RATIO);
|
||||
|
||||
if (isGripPressed) {
|
||||
isGripPressed = gripValue > GRIP_OFF;
|
||||
} else {
|
||||
isGripPressed = gripValue > GRIP_ON;
|
||||
if (isGripPressed) {
|
||||
fingerTipPosition = MyAvatar.getJointPosition(handName === "left" ? "LeftHandIndex4" : "RightHandIndex4");
|
||||
gripPressedCallback(fingerTipPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onUpdate() {
|
||||
updateTriggerPress();
|
||||
updateGripPress();
|
||||
}
|
||||
|
||||
function setUp(onTriggerPressed, onTriggerPressing, onTriggerReleased, onGripPressed) {
|
||||
triggerPressedCallback = onTriggerPressed;
|
||||
triggerPressingCallback = onTriggerPressing;
|
||||
triggerReleasedCallback = onTriggerReleased;
|
||||
gripPressedCallback = onGripPressed;
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
return {
|
||||
onTriggerPress: onTriggerPress,
|
||||
onGripPress: onGripPress,
|
||||
onUpdate: onUpdate,
|
||||
setUp: setUp,
|
||||
tearDown: tearDown
|
||||
};
|
||||
}
|
||||
|
||||
function updateHandFunctions() {
|
||||
// Update other scripts' hand functions.
|
||||
var enabled = !isFingerPainting || isTabletDisplayed;
|
||||
|
||||
Messages.sendMessage(HIFI_GRAB_DISABLE_MESSAGE_CHANNEL, JSON.stringify({
|
||||
holdEnabled: enabled,
|
||||
nearGrabEnabled: enabled,
|
||||
farGrabEnabled: enabled
|
||||
}), true);
|
||||
Messages.sendMessage(HIFI_POINTER_DISABLE_MESSAGE_CHANNEL, JSON.stringify({
|
||||
pointerEnabled: enabled
|
||||
}), true);
|
||||
Messages.sendMessage(HIFI_POINT_INDEX_MESSAGE_CHANNEL, JSON.stringify({
|
||||
pointIndex: !enabled
|
||||
}), true);
|
||||
}
|
||||
|
||||
function enableProcessing() {
|
||||
// Connect controller API to handController objects.
|
||||
leftHand = handController("left");
|
||||
rightHand = handController("right");
|
||||
var controllerMapping = Controller.newMapping(CONTROLLER_MAPPING_NAME);
|
||||
controllerMapping.from(Controller.Standard.LT).to(leftHand.onTriggerPress);
|
||||
controllerMapping.from(Controller.Standard.LeftGrip).to(leftHand.onGripPress);
|
||||
controllerMapping.from(Controller.Standard.RT).to(rightHand.onTriggerPress);
|
||||
controllerMapping.from(Controller.Standard.RightGrip).to(rightHand.onGripPress);
|
||||
Controller.enableMapping(CONTROLLER_MAPPING_NAME);
|
||||
|
||||
// Connect handController outputs to paintBrush objects.
|
||||
leftBrush = paintBrush("left");
|
||||
leftHand.setUp(leftBrush.startLine, leftBrush.drawLine, leftBrush.finishLine, leftBrush.eraseClosestLine);
|
||||
rightBrush = paintBrush("right");
|
||||
rightHand.setUp(rightBrush.startLine, rightBrush.drawLine, rightBrush.finishLine, rightBrush.eraseClosestLine);
|
||||
|
||||
// Messages channels for enabling/disabling other scripts' functions.
|
||||
Messages.subscribe(HIFI_POINT_INDEX_MESSAGE_CHANNEL);
|
||||
Messages.subscribe(HIFI_GRAB_DISABLE_MESSAGE_CHANNEL);
|
||||
Messages.subscribe(HIFI_POINTER_DISABLE_MESSAGE_CHANNEL);
|
||||
|
||||
// Update hand controls.
|
||||
Script.update.connect(leftHand.onUpdate);
|
||||
Script.update.connect(rightHand.onUpdate);
|
||||
}
|
||||
|
||||
function disableProcessing() {
|
||||
Script.update.disconnect(leftHand.onUpdate);
|
||||
Script.update.disconnect(rightHand.onUpdate);
|
||||
|
||||
Controller.disableMapping(CONTROLLER_MAPPING_NAME);
|
||||
|
||||
leftBrush.tearDown();
|
||||
leftBrush = null;
|
||||
leftHand.tearDown();
|
||||
leftHand = null;
|
||||
|
||||
rightBrush.tearDown();
|
||||
rightBrush = null;
|
||||
rightHand.tearDown();
|
||||
rightHand = null;
|
||||
|
||||
Messages.unsubscribe(HIFI_POINT_INDEX_MESSAGE_CHANNEL);
|
||||
Messages.unsubscribe(HIFI_GRAB_DISABLE_MESSAGE_CHANNEL);
|
||||
Messages.unsubscribe(HIFI_POINTER_DISABLE_MESSAGE_CHANNEL);
|
||||
}
|
||||
|
||||
function onButtonClicked() {
|
||||
var wasFingerPainting = isFingerPainting;
|
||||
|
||||
isFingerPainting = !isFingerPainting;
|
||||
button.editProperties({ isActive: isFingerPainting });
|
||||
|
||||
print("Finger painting: " + isFingerPainting ? "on" : "off");
|
||||
|
||||
if (wasFingerPainting) {
|
||||
leftBrush.cancelLine();
|
||||
rightBrush.cancelLine();
|
||||
}
|
||||
|
||||
if (isFingerPainting) {
|
||||
enableProcessing();
|
||||
}
|
||||
|
||||
updateHandFunctions();
|
||||
|
||||
if (!isFingerPainting) {
|
||||
disableProcessing();
|
||||
}
|
||||
}
|
||||
|
||||
function onTabletScreenChanged(type, url) {
|
||||
var TABLET_SCREEN_CLOSED = "Closed";
|
||||
|
||||
isTabletDisplayed = type !== TABLET_SCREEN_CLOSED;
|
||||
updateHandFunctions();
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
if (!tablet) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Tablet button.
|
||||
button = tablet.addButton({
|
||||
icon: "icons/tablet-icons/finger-paint-i.svg",
|
||||
activeIcon: "icons/tablet-icons/finger-paint-a.svg",
|
||||
text: BUTTON_NAME,
|
||||
isActive: isFingerPainting
|
||||
});
|
||||
button.clicked.connect(onButtonClicked);
|
||||
|
||||
// Track whether tablet is displayed or not.
|
||||
tablet.screenChanged.connect(onTabletScreenChanged);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
if (!tablet) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isFingerPainting) {
|
||||
isFingerPainting = false;
|
||||
updateHandFunctions();
|
||||
disableProcessing();
|
||||
}
|
||||
|
||||
tablet.screenChanged.disconnect(onTabletScreenChanged);
|
||||
|
||||
button.clicked.disconnect(onButtonClicked);
|
||||
tablet.removeButton(button);
|
||||
}
|
||||
|
||||
setUp();
|
||||
Script.scriptEnding.connect(tearDown);
|
||||
}());
|
|
@ -159,7 +159,7 @@ WebTablet = function (url, width, dpi, hand, clientOnly) {
|
|||
});
|
||||
|
||||
this.receive = function (channel, senderID, senderUUID, localOnly) {
|
||||
if (_this.homeButtonEntity === parseInt(senderID)) {
|
||||
if (_this.homeButtonEntity == senderID) {
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
var onHomeScreen = tablet.onHomeScreen();
|
||||
if (onHomeScreen) {
|
||||
|
@ -219,7 +219,6 @@ WebTablet = function (url, width, dpi, hand, clientOnly) {
|
|||
};
|
||||
|
||||
WebTablet.prototype.setHomeButtonTexture = function() {
|
||||
print(this.homeButtonEntity);
|
||||
Entities.editEntity(this.tabletEntityID, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})});
|
||||
};
|
||||
|
||||
|
@ -385,14 +384,10 @@ WebTablet.prototype.register = function() {
|
|||
WebTablet.prototype.cleanUpOldTabletsOnJoint = function(jointIndex) {
|
||||
var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, jointIndex);
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(AVATAR_SELF_ID, jointIndex));
|
||||
print("cleanup " + children);
|
||||
children.forEach(function(childID) {
|
||||
var props = Entities.getEntityProperties(childID, ["name"]);
|
||||
if (props.name === "WebTablet Tablet") {
|
||||
print("cleaning up " + props.name);
|
||||
Entities.deleteEntity(childID);
|
||||
} else {
|
||||
print("not cleaning up " + props.name);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -3866,6 +3866,12 @@ SelectionDisplay = (function() {
|
|||
var somethingClicked = false;
|
||||
var pickRay = generalComputePickRay(event.x, event.y);
|
||||
|
||||
var result = Overlays.findRayIntersection(pickRay, true, [HMD.tabletScreenID, HMD.homeButtonID]);
|
||||
if (result.intersects) {
|
||||
// mouse clicks on the tablet should override the edit affordances
|
||||
return false;
|
||||
}
|
||||
|
||||
// before we do a ray test for grabbers, disable the ray intersection for our selection box
|
||||
Overlays.editOverlay(selectionBox, {
|
||||
ignoreRayIntersection: true
|
||||
|
@ -3879,10 +3885,9 @@ SelectionDisplay = (function() {
|
|||
Overlays.editOverlay(rollHandle, {
|
||||
ignoreRayIntersection: true
|
||||
});
|
||||
var result = Overlays.findRayIntersection(pickRay);
|
||||
|
||||
result = Overlays.findRayIntersection(pickRay);
|
||||
if (result.intersects) {
|
||||
|
||||
|
||||
if (wantDebug) {
|
||||
print("something intersects... ");
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
UIWebTablet.register();
|
||||
HMD.tabletID = UIWebTablet.tabletEntityID;
|
||||
HMD.homeButtonID = UIWebTablet.homeButtonEntity;
|
||||
HMD.tabletScreenID = UIWebTablet.webOverlayID;
|
||||
}
|
||||
|
||||
function hideTabletUI() {
|
||||
|
@ -48,6 +49,7 @@
|
|||
UIWebTablet = null;
|
||||
HMD.tabletID = null;
|
||||
HMD.homeButtonID = null;
|
||||
HMD.tabletScreenID = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ var BUTTON_SIZE = 32;
|
|||
var PADDING = 3;
|
||||
var BOTTOM_PADDING = 50;
|
||||
//a helper library for creating toolbars
|
||||
Script.include("http://hifi-production.s3.amazonaws.com/tutorials/dice/toolBars.js");
|
||||
Script.include("/~/system/libraries/toolBars.js");
|
||||
|
||||
var toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.toolbars-dice", function(screenSize) {
|
||||
return {
|
||||
|
@ -139,4 +139,4 @@ function scriptEnding() {
|
|||
}
|
||||
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
|
Loading…
Reference in a new issue