mirror of
https://github.com/overte-org/overte.git
synced 2025-04-18 07:56:25 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into stagingSetting
This commit is contained in:
commit
3e95484c4c
32 changed files with 321 additions and 638 deletions
|
@ -22,8 +22,7 @@ RowLayout {
|
|||
property var sample: null;
|
||||
property bool isPlaying: false;
|
||||
function createSampleSound() {
|
||||
var SOUND = Qt.resolvedUrl("../../../sounds/sample.wav");
|
||||
sound = SoundCache.getSound(SOUND);
|
||||
sound = ApplicationInterface.getSampleSound();
|
||||
sample = null;
|
||||
}
|
||||
function playSound() {
|
||||
|
|
Binary file not shown.
|
@ -691,7 +691,6 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
|||
DependencyManager::set<CloseEventSender>();
|
||||
DependencyManager::set<ResourceManager>();
|
||||
DependencyManager::set<SelectionScriptingInterface>();
|
||||
DependencyManager::set<ContextOverlayInterface>();
|
||||
DependencyManager::set<Ledger>();
|
||||
DependencyManager::set<Wallet>();
|
||||
DependencyManager::set<WalletScriptingInterface>();
|
||||
|
@ -759,7 +758,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
_notifiedPacketVersionMismatchThisDomain(false),
|
||||
_maxOctreePPS(maxOctreePacketsPerSecond.get()),
|
||||
_lastFaceTrackerUpdate(0),
|
||||
_snapshotSound(nullptr)
|
||||
_snapshotSound(nullptr),
|
||||
_sampleSound(nullptr)
|
||||
|
||||
{
|
||||
auto steamClient = PluginManager::getInstance()->getSteamClientPlugin();
|
||||
setProperty(hifi::properties::STEAM, (steamClient && steamClient->isRunning()));
|
||||
|
@ -804,7 +805,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
installNativeEventFilter(&MyNativeEventFilter::getInstance());
|
||||
#endif
|
||||
|
||||
|
||||
_logger = new FileLogger(this);
|
||||
qInstallMessageHandler(messageHandler);
|
||||
|
||||
|
@ -981,6 +981,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
connect(myAvatar.get(), &MyAvatar::positionGoneTo,
|
||||
DependencyManager::get<AddressManager>().data(), &AddressManager::storeCurrentAddress);
|
||||
|
||||
// Inititalize sample before registering
|
||||
QFileInfo infSample = QFileInfo(PathUtils::resourcesPath() + "sounds/sample.wav");
|
||||
_sampleSound = DependencyManager::get<SoundCache>()->getSound(QUrl::fromLocalFile(infSample.absoluteFilePath()));
|
||||
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
|
||||
scriptEngines->registerScriptInitializer([this](ScriptEnginePointer engine){
|
||||
registerScriptEngineWithApplicationServices(engine);
|
||||
|
@ -1182,7 +1186,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// allow you to move an entity around in your hand
|
||||
_entityEditSender.setPacketsPerSecond(3000); // super high!!
|
||||
|
||||
// Overlays need to exist before we set the ContextOverlayInterface dependency
|
||||
_overlays.init(); // do this before scripts load
|
||||
DependencyManager::set<ContextOverlayInterface>();
|
||||
|
||||
// Make sure we don't time out during slow operations at startup
|
||||
updateHeartbeat();
|
||||
|
||||
|
@ -1472,53 +1479,19 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
}
|
||||
});
|
||||
|
||||
// If the user clicks somewhere where there is NO entity at all, we will release focus
|
||||
connect(getEntities().data(), &EntityTreeRenderer::mousePressOffEntity, [=]() {
|
||||
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||
});
|
||||
|
||||
// Keyboard focus handling for Web overlays.
|
||||
auto overlays = &(qApp->getOverlays());
|
||||
|
||||
connect(overlays, &Overlays::mousePressOnOverlay, [=](const OverlayID& overlayID, const PointerEvent& event) {
|
||||
auto thisOverlay = std::dynamic_pointer_cast<Web3DOverlay>(overlays->getOverlay(overlayID));
|
||||
// Only Web overlays can have keyboard focus.
|
||||
if (thisOverlay) {
|
||||
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||
setKeyboardFocusOverlay(overlayID);
|
||||
}
|
||||
});
|
||||
|
||||
connect(overlays, &Overlays::overlayDeleted, [=](const OverlayID& overlayID) {
|
||||
if (overlayID == _keyboardFocusedOverlay.get()) {
|
||||
setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID);
|
||||
}
|
||||
});
|
||||
|
||||
connect(overlays, &Overlays::mousePressOffOverlay, [=]() {
|
||||
setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID);
|
||||
});
|
||||
|
||||
connect(this, &Application::aboutToQuit, [=]() {
|
||||
setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID);
|
||||
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||
});
|
||||
|
||||
connect(overlays,
|
||||
SIGNAL(mousePressOnOverlay(const OverlayID&, const PointerEvent&)),
|
||||
DependencyManager::get<ContextOverlayInterface>().data(),
|
||||
SLOT(contextOverlays_mousePressOnOverlay(const OverlayID&, const PointerEvent&)));
|
||||
|
||||
connect(overlays,
|
||||
SIGNAL(hoverEnterOverlay(const OverlayID&, const PointerEvent&)),
|
||||
DependencyManager::get<ContextOverlayInterface>().data(),
|
||||
SLOT(contextOverlays_hoverEnterOverlay(const OverlayID&, const PointerEvent&)));
|
||||
|
||||
connect(overlays,
|
||||
SIGNAL(hoverLeaveOverlay(const OverlayID&, const PointerEvent&)),
|
||||
DependencyManager::get<ContextOverlayInterface>().data(),
|
||||
SLOT(contextOverlays_hoverLeaveOverlay(const OverlayID&, const PointerEvent&)));
|
||||
|
||||
// Add periodic checks to send user activity data
|
||||
static int CHECK_NEARBY_AVATARS_INTERVAL_MS = 10000;
|
||||
static int NEARBY_AVATAR_RADIUS_METERS = 10;
|
||||
|
@ -1787,9 +1760,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
return entityServerNode && !isPhysicsEnabled();
|
||||
});
|
||||
|
||||
QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav");
|
||||
_snapshotSound = DependencyManager::get<SoundCache>()->getSound(QUrl::fromLocalFile(inf.absoluteFilePath()));
|
||||
|
||||
QFileInfo infSnap = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav");
|
||||
_snapshotSound = DependencyManager::get<SoundCache>()->getSound(QUrl::fromLocalFile(infSnap.absoluteFilePath()));
|
||||
|
||||
QVariant testProperty = property(hifi::properties::TEST);
|
||||
qDebug() << testProperty;
|
||||
if (testProperty.isValid()) {
|
||||
|
@ -4202,6 +4175,7 @@ void Application::initDisplay() {
|
|||
}
|
||||
|
||||
void Application::init() {
|
||||
|
||||
// Make sure Login state is up to date
|
||||
DependencyManager::get<DialogsManager>()->toggleLoginDialog();
|
||||
|
||||
|
@ -4554,14 +4528,9 @@ QUuid Application::getKeyboardFocusEntity() const {
|
|||
return _keyboardFocusedEntity.get();
|
||||
}
|
||||
|
||||
void Application::setKeyboardFocusEntity(QUuid id) {
|
||||
EntityItemID entityItemID(id);
|
||||
setKeyboardFocusEntity(entityItemID);
|
||||
}
|
||||
|
||||
static const float FOCUS_HIGHLIGHT_EXPANSION_FACTOR = 1.05f;
|
||||
|
||||
void Application::setKeyboardFocusEntity(EntityItemID entityItemID) {
|
||||
void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) {
|
||||
if (_keyboardFocusedEntity.get() != entityItemID) {
|
||||
_keyboardFocusedEntity.set(entityItemID);
|
||||
|
||||
|
@ -4598,7 +4567,7 @@ OverlayID Application::getKeyboardFocusOverlay() {
|
|||
return _keyboardFocusedOverlay.get();
|
||||
}
|
||||
|
||||
void Application::setKeyboardFocusOverlay(OverlayID overlayID) {
|
||||
void Application::setKeyboardFocusOverlay(const OverlayID& overlayID) {
|
||||
if (overlayID != _keyboardFocusedOverlay.get()) {
|
||||
_keyboardFocusedOverlay.set(overlayID);
|
||||
|
||||
|
@ -6810,6 +6779,10 @@ void Application::loadScriptURLDialog() const {
|
|||
});
|
||||
}
|
||||
|
||||
SharedSoundPointer Application::getSampleSound() const {
|
||||
return _sampleSound;
|
||||
}
|
||||
|
||||
void Application::loadLODToolsDialog() {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet(SYSTEM_TABLET));
|
||||
|
@ -7432,51 +7405,6 @@ bool Application::isForeground() const {
|
|||
return _isForeground && !_window->isMinimized();
|
||||
}
|
||||
|
||||
void Application::sendMousePressOnEntity(QUuid id, PointerEvent event) {
|
||||
EntityItemID entityItemID(id);
|
||||
emit getEntities()->mousePressOnEntity(entityItemID, event);
|
||||
}
|
||||
|
||||
void Application::sendMouseMoveOnEntity(QUuid id, PointerEvent event) {
|
||||
EntityItemID entityItemID(id);
|
||||
emit getEntities()->mouseMoveOnEntity(entityItemID, event);
|
||||
}
|
||||
|
||||
void Application::sendMouseReleaseOnEntity(QUuid id, PointerEvent event) {
|
||||
EntityItemID entityItemID(id);
|
||||
emit getEntities()->mouseReleaseOnEntity(entityItemID, event);
|
||||
}
|
||||
|
||||
void Application::sendClickDownOnEntity(QUuid id, PointerEvent event) {
|
||||
EntityItemID entityItemID(id);
|
||||
emit getEntities()->clickDownOnEntity(entityItemID, event);
|
||||
}
|
||||
|
||||
void Application::sendHoldingClickOnEntity(QUuid id, PointerEvent event) {
|
||||
EntityItemID entityItemID(id);
|
||||
emit getEntities()->holdingClickOnEntity(entityItemID, event);
|
||||
}
|
||||
|
||||
void Application::sendClickReleaseOnEntity(QUuid id, PointerEvent event) {
|
||||
EntityItemID entityItemID(id);
|
||||
emit getEntities()->clickReleaseOnEntity(entityItemID, event);
|
||||
}
|
||||
|
||||
void Application::sendHoverEnterEntity(QUuid id, PointerEvent event) {
|
||||
EntityItemID entityItemID(id);
|
||||
emit getEntities()->hoverEnterEntity(entityItemID, event);
|
||||
}
|
||||
|
||||
void Application::sendHoverOverEntity(QUuid id, PointerEvent event) {
|
||||
EntityItemID entityItemID(id);
|
||||
emit getEntities()->hoverOverEntity(entityItemID, event);
|
||||
}
|
||||
|
||||
void Application::sendHoverLeaveEntity(QUuid id, PointerEvent event) {
|
||||
EntityItemID entityItemID(id);
|
||||
emit getEntities()->hoverLeaveEntity(entityItemID, event);
|
||||
}
|
||||
|
||||
// FIXME? perhaps two, one for the main thread and one for the offscreen UI rendering thread?
|
||||
static const int UI_RESERVED_THREADS = 1;
|
||||
// Windows won't let you have all the cores
|
||||
|
|
|
@ -277,18 +277,6 @@ public:
|
|||
gpu::TexturePointer getDefaultSkyboxTexture() const { return _defaultSkyboxTexture; }
|
||||
gpu::TexturePointer getDefaultSkyboxAmbientTexture() const { return _defaultSkyboxAmbientTexture; }
|
||||
|
||||
Q_INVOKABLE void sendMousePressOnEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendMouseMoveOnEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendMouseReleaseOnEntity(QUuid id, PointerEvent event);
|
||||
|
||||
Q_INVOKABLE void sendClickDownOnEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendHoldingClickOnEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendClickReleaseOnEntity(QUuid id, PointerEvent event);
|
||||
|
||||
Q_INVOKABLE void sendHoverEnterEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendHoverOverEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendHoverLeaveEntity(QUuid id, PointerEvent event);
|
||||
|
||||
OverlayID getTabletScreenID() const;
|
||||
OverlayID getTabletHomeButtonID() const;
|
||||
QUuid getTabletFrameID() const; // may be an entity or an overlay
|
||||
|
@ -326,6 +314,7 @@ public slots:
|
|||
void toggleEntityScriptServerLogDialog();
|
||||
Q_INVOKABLE void showAssetServerWidget(QString filePath = "");
|
||||
Q_INVOKABLE void loadAddAvatarBookmarkDialog() const;
|
||||
Q_INVOKABLE SharedSoundPointer getSampleSound() const;
|
||||
|
||||
void showDialog(const QUrl& widgetUrl, const QUrl& tabletUrl, const QString& name) const;
|
||||
|
||||
|
@ -388,11 +377,10 @@ public slots:
|
|||
void setKeyboardFocusHighlight(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions);
|
||||
|
||||
QUuid getKeyboardFocusEntity() const; // thread-safe
|
||||
void setKeyboardFocusEntity(QUuid id);
|
||||
void setKeyboardFocusEntity(EntityItemID entityItemID);
|
||||
void setKeyboardFocusEntity(const EntityItemID& entityItemID);
|
||||
|
||||
OverlayID getKeyboardFocusOverlay();
|
||||
void setKeyboardFocusOverlay(OverlayID overlayID);
|
||||
void setKeyboardFocusOverlay(const OverlayID& overlayID);
|
||||
|
||||
void addAssetToWorldMessageClose();
|
||||
|
||||
|
@ -702,6 +690,7 @@ private:
|
|||
FileScriptingInterface* _fileDownload;
|
||||
AudioInjectorPointer _snapshotSoundInjector;
|
||||
SharedSoundPointer _snapshotSound;
|
||||
SharedSoundPointer _sampleSound;
|
||||
|
||||
DisplayPluginPointer _autoSwitchDisplayModeSupportedHMDPlugin;
|
||||
QString _autoSwitchDisplayModeSupportedHMDPluginName;
|
||||
|
|
|
@ -43,10 +43,10 @@ ContextOverlayInterface::ContextOverlayInterface() {
|
|||
_entityPropertyFlags += PROP_REGISTRATION_POINT;
|
||||
_entityPropertyFlags += PROP_CERTIFICATE_ID;
|
||||
|
||||
auto entityTreeRenderer = DependencyManager::get<EntityTreeRenderer>().data();
|
||||
connect(entityTreeRenderer, SIGNAL(mousePressOnEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(createOrDestroyContextOverlay(const EntityItemID&, const PointerEvent&)));
|
||||
connect(entityTreeRenderer, SIGNAL(hoverEnterEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(contextOverlays_hoverEnterEntity(const EntityItemID&, const PointerEvent&)));
|
||||
connect(entityTreeRenderer, SIGNAL(hoverLeaveEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(contextOverlays_hoverLeaveEntity(const EntityItemID&, const PointerEvent&)));
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>().data();
|
||||
connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, &ContextOverlayInterface::createOrDestroyContextOverlay);
|
||||
connect(entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity, this, &ContextOverlayInterface::contextOverlays_hoverEnterEntity);
|
||||
connect(entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity, this, &ContextOverlayInterface::contextOverlays_hoverLeaveEntity);
|
||||
connect(_tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"), &TabletProxy::tabletShownChanged, this, [&]() {
|
||||
if (_contextOverlayJustClicked && _hmdScriptingInterface->isMounted()) {
|
||||
QUuid tabletFrameID = _hmdScriptingInterface->getCurrentTabletFrameID();
|
||||
|
@ -59,9 +59,12 @@ ContextOverlayInterface::ContextOverlayInterface() {
|
|||
_contextOverlayJustClicked = false;
|
||||
}
|
||||
});
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>().data();
|
||||
connect(entityScriptingInterface, &EntityScriptingInterface::deletingEntity, this, &ContextOverlayInterface::deletingEntity);
|
||||
|
||||
connect(&qApp->getOverlays(), &Overlays::mousePressOnOverlay, this, &ContextOverlayInterface::contextOverlays_mousePressOnOverlay);
|
||||
connect(&qApp->getOverlays(), &Overlays::hoverEnterOverlay, this, &ContextOverlayInterface::contextOverlays_hoverEnterOverlay);
|
||||
connect(&qApp->getOverlays(), &Overlays::hoverLeaveOverlay, this, &ContextOverlayInterface::contextOverlays_hoverLeaveOverlay);
|
||||
|
||||
connect(_selectionScriptingInterface.data(), &SelectionScriptingInterface::selectedItemsListChanged, &_selectionToSceneHandler, &SelectionToSceneHandler::selectedItemsListChanged);
|
||||
}
|
||||
|
||||
|
|
|
@ -717,39 +717,34 @@ bool Overlays::isAddedOverlay(OverlayID id) {
|
|||
}
|
||||
|
||||
void Overlays::sendMousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
QMetaObject::invokeMethod(this, "mousePressOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event));
|
||||
mousePressEvent(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendMouseReleaseOnOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
QMetaObject::invokeMethod(this, "mouseReleaseOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event));
|
||||
mouseReleaseEvent(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendMouseMoveOnOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
QMetaObject::invokeMethod(this, "mouseMoveOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event));
|
||||
mouseMoveEvent(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendHoverEnterOverlay(const OverlayID& id, const PointerEvent& event) {
|
||||
QMetaObject::invokeMethod(this, "hoverEnterOverlay", Q_ARG(OverlayID, id), Q_ARG(PointerEvent, event));
|
||||
void Overlays::sendHoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
emit hoverEnterOverlay(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendHoverOverOverlay(const OverlayID& id, const PointerEvent& event) {
|
||||
QMetaObject::invokeMethod(this, "hoverOverOverlay", Q_ARG(OverlayID, id), Q_ARG(PointerEvent, event));
|
||||
void Overlays::sendHoverOverOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
emit hoverOverOverlay(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendHoverLeaveOverlay(const OverlayID& id, const PointerEvent& event) {
|
||||
QMetaObject::invokeMethod(this, "hoverLeaveOverlay", Q_ARG(OverlayID, id), Q_ARG(PointerEvent, event));
|
||||
void Overlays::sendHoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
hoverLeaveEvent(overlayID, event);
|
||||
}
|
||||
|
||||
OverlayID Overlays::getKeyboardFocusOverlay() {
|
||||
return qApp->getKeyboardFocusOverlay();
|
||||
}
|
||||
|
||||
void Overlays::setKeyboardFocusOverlay(OverlayID id) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setKeyboardFocusOverlay", Q_ARG(OverlayID, id));
|
||||
return;
|
||||
}
|
||||
|
||||
void Overlays::setKeyboardFocusOverlay(const OverlayID& id) {
|
||||
qApp->setKeyboardFocusOverlay(id);
|
||||
}
|
||||
|
||||
|
@ -884,13 +879,35 @@ bool Overlays::mousePressEvent(QMouseEvent* event) {
|
|||
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
||||
|
||||
PointerEvent pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press);
|
||||
emit mousePressOnOverlay(_currentClickingOnOverlayID, pointerEvent);
|
||||
mousePressEvent(_currentClickingOnOverlayID, pointerEvent);
|
||||
return true;
|
||||
}
|
||||
// if we didn't press on an overlay, disable overlay keyboard focus
|
||||
setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID);
|
||||
// emit to scripts
|
||||
emit mousePressOffOverlay();
|
||||
return false;
|
||||
}
|
||||
|
||||
void Overlays::mousePressEvent(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
// TODO: generalize this to allow any overlay to recieve events
|
||||
std::shared_ptr<Web3DOverlay> thisOverlay;
|
||||
if (getOverlayType(overlayID) == "web3d") {
|
||||
thisOverlay = std::static_pointer_cast<Web3DOverlay>(getOverlay(overlayID));
|
||||
}
|
||||
if (thisOverlay) {
|
||||
// Focus keyboard on web overlays
|
||||
DependencyManager::get<EntityScriptingInterface>()->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||
setKeyboardFocusOverlay(overlayID);
|
||||
|
||||
// Send to web overlay
|
||||
QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event));
|
||||
}
|
||||
|
||||
// emit to scripts
|
||||
emit mousePressOnOverlay(overlayID, event);
|
||||
}
|
||||
|
||||
bool Overlays::mouseDoublePressEvent(QMouseEvent* event) {
|
||||
PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent");
|
||||
|
||||
|
@ -900,13 +917,30 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) {
|
|||
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
||||
|
||||
auto pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press);
|
||||
// emit to scripts
|
||||
emit mouseDoublePressOnOverlay(_currentClickingOnOverlayID, pointerEvent);
|
||||
return true;
|
||||
}
|
||||
// emit to scripts
|
||||
emit mouseDoublePressOffOverlay();
|
||||
return false;
|
||||
}
|
||||
|
||||
void Overlays::hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
// TODO: generalize this to allow any overlay to recieve events
|
||||
std::shared_ptr<Web3DOverlay> thisOverlay;
|
||||
if (getOverlayType(overlayID) == "web3d") {
|
||||
thisOverlay = std::static_pointer_cast<Web3DOverlay>(getOverlay(overlayID));
|
||||
}
|
||||
if (thisOverlay) {
|
||||
// Send to web overlay
|
||||
QMetaObject::invokeMethod(thisOverlay.get(), "hoverLeaveOverlay", Q_ARG(PointerEvent, event));
|
||||
}
|
||||
|
||||
// emit to scripts
|
||||
emit hoverLeaveOverlay(overlayID, event);
|
||||
}
|
||||
|
||||
bool Overlays::mouseReleaseEvent(QMouseEvent* event) {
|
||||
PerformanceTimer perfTimer("Overlays::mouseReleaseEvent");
|
||||
|
||||
|
@ -914,13 +948,28 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) {
|
|||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
|
||||
if (rayPickResult.intersects) {
|
||||
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release);
|
||||
emit mouseReleaseOnOverlay(rayPickResult.overlayID, pointerEvent);
|
||||
mouseReleaseEvent(rayPickResult.overlayID, pointerEvent);
|
||||
}
|
||||
|
||||
_currentClickingOnOverlayID = UNKNOWN_OVERLAY_ID;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Overlays::mouseReleaseEvent(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
// TODO: generalize this to allow any overlay to recieve events
|
||||
std::shared_ptr<Web3DOverlay> thisOverlay;
|
||||
if (getOverlayType(overlayID) == "web3d") {
|
||||
thisOverlay = std::static_pointer_cast<Web3DOverlay>(getOverlay(overlayID));
|
||||
}
|
||||
if (thisOverlay) {
|
||||
// Send to web overlay
|
||||
QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event));
|
||||
}
|
||||
|
||||
// emit to scripts
|
||||
emit mouseReleaseOnOverlay(overlayID, event);
|
||||
}
|
||||
|
||||
bool Overlays::mouseMoveEvent(QMouseEvent* event) {
|
||||
PerformanceTimer perfTimer("Overlays::mouseMoveEvent");
|
||||
|
||||
|
@ -928,12 +977,12 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) {
|
|||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
|
||||
if (rayPickResult.intersects) {
|
||||
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move);
|
||||
emit mouseMoveOnOverlay(rayPickResult.overlayID, pointerEvent);
|
||||
mouseMoveEvent(rayPickResult.overlayID, pointerEvent);
|
||||
|
||||
// If previously hovering over a different overlay then leave hover on that overlay.
|
||||
if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID && rayPickResult.overlayID != _currentHoverOverOverlayID) {
|
||||
auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move);
|
||||
emit hoverLeaveOverlay(_currentHoverOverOverlayID, pointerEvent);
|
||||
hoverLeaveEvent(_currentHoverOverOverlayID, pointerEvent);
|
||||
}
|
||||
|
||||
// If hovering over a new overlay then enter hover on that overlay.
|
||||
|
@ -949,7 +998,7 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) {
|
|||
// If previously hovering an overlay then leave hover.
|
||||
if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID) {
|
||||
auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move);
|
||||
emit hoverLeaveOverlay(_currentHoverOverOverlayID, pointerEvent);
|
||||
hoverLeaveEvent(_currentHoverOverOverlayID, pointerEvent);
|
||||
|
||||
_currentHoverOverOverlayID = UNKNOWN_OVERLAY_ID;
|
||||
}
|
||||
|
@ -957,6 +1006,21 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void Overlays::mouseMoveEvent(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
// TODO: generalize this to allow any overlay to recieve events
|
||||
std::shared_ptr<Web3DOverlay> thisOverlay;
|
||||
if (getOverlayType(overlayID) == "web3d") {
|
||||
thisOverlay = std::static_pointer_cast<Web3DOverlay>(getOverlay(overlayID));
|
||||
}
|
||||
if (thisOverlay) {
|
||||
// Send to web overlay
|
||||
QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event));
|
||||
}
|
||||
|
||||
// emit to scripts
|
||||
emit mouseMoveOnOverlay(overlayID, event);
|
||||
}
|
||||
|
||||
QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
||||
QVector<QUuid> result;
|
||||
//if (QThread::currentThread() != thread()) {
|
||||
|
|
|
@ -107,6 +107,11 @@ public:
|
|||
bool mouseReleaseEvent(QMouseEvent* event);
|
||||
bool mouseMoveEvent(QMouseEvent* event);
|
||||
|
||||
void mousePressEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void mouseMoveEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void mouseReleaseEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
|
||||
void cleanupAllOverlays();
|
||||
|
||||
public slots:
|
||||
|
@ -298,12 +303,12 @@ public slots:
|
|||
void sendMouseReleaseOnOverlay(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void sendMouseMoveOnOverlay(const OverlayID& overlayID, const PointerEvent& event);
|
||||
|
||||
void sendHoverEnterOverlay(const OverlayID& id, const PointerEvent& event);
|
||||
void sendHoverOverOverlay(const OverlayID& id, const PointerEvent& event);
|
||||
void sendHoverLeaveOverlay(const OverlayID& id, const PointerEvent& event);
|
||||
void sendHoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void sendHoverOverOverlay(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void sendHoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event);
|
||||
|
||||
OverlayID getKeyboardFocusOverlay();
|
||||
void setKeyboardFocusOverlay(OverlayID id);
|
||||
void setKeyboardFocusOverlay(const OverlayID& id);
|
||||
|
||||
signals:
|
||||
/**jsdoc
|
||||
|
|
|
@ -125,11 +125,7 @@ void Web3DOverlay::destroyWebSurface() {
|
|||
}
|
||||
|
||||
_webSurface->pause();
|
||||
auto overlays = &(qApp->getOverlays());
|
||||
QObject::disconnect(overlays, &Overlays::mousePressOnOverlay, this, nullptr);
|
||||
QObject::disconnect(overlays, &Overlays::mouseReleaseOnOverlay, this, nullptr);
|
||||
QObject::disconnect(overlays, &Overlays::mouseMoveOnOverlay, this, nullptr);
|
||||
QObject::disconnect(overlays, &Overlays::hoverLeaveOverlay, this, nullptr);
|
||||
|
||||
QObject::disconnect(this, &Web3DOverlay::scriptEventReceived, _webSurface.data(), &OffscreenQmlSurface::emitScriptEvent);
|
||||
QObject::disconnect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived);
|
||||
DependencyManager::get<OffscreenQmlSurfaceCache>()->release(QML, _webSurface);
|
||||
|
@ -160,35 +156,17 @@ void Web3DOverlay::buildWebSurface() {
|
|||
_webSurface->resume();
|
||||
});
|
||||
|
||||
auto selfOverlayID = getOverlayID();
|
||||
std::weak_ptr<Web3DOverlay> weakSelf = std::dynamic_pointer_cast<Web3DOverlay>(qApp->getOverlays().getOverlay(selfOverlayID));
|
||||
auto forwardPointerEvent = [=](OverlayID overlayID, const PointerEvent& event) {
|
||||
auto self = weakSelf.lock();
|
||||
if (self && overlayID == selfOverlayID) {
|
||||
self->handlePointerEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
auto overlays = &(qApp->getOverlays());
|
||||
QObject::connect(overlays, &Overlays::mousePressOnOverlay, this, forwardPointerEvent);
|
||||
QObject::connect(overlays, &Overlays::mouseReleaseOnOverlay, this, forwardPointerEvent);
|
||||
QObject::connect(overlays, &Overlays::mouseMoveOnOverlay, this, forwardPointerEvent);
|
||||
QObject::connect(overlays, &Overlays::hoverLeaveOverlay, this, [=](OverlayID overlayID, const PointerEvent& event) {
|
||||
auto self = weakSelf.lock();
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
if (overlayID == selfOverlayID && (self->_pressed || (!self->_activeTouchPoints.empty() && self->_touchBeginAccepted))) {
|
||||
PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(),
|
||||
event.getButton(), event.getButtons(), event.getKeyboardModifiers());
|
||||
forwardPointerEvent(overlayID, endEvent);
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(this, &Web3DOverlay::scriptEventReceived, _webSurface.data(), &OffscreenQmlSurface::emitScriptEvent);
|
||||
QObject::connect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived);
|
||||
}
|
||||
|
||||
void Web3DOverlay::hoverLeaveOverlay(const PointerEvent& event) {
|
||||
if ((_pressed || (!_activeTouchPoints.empty() && _touchBeginAccepted))) {
|
||||
PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(),
|
||||
event.getButton(), event.getButtons(), event.getKeyboardModifiers());
|
||||
handlePointerEvent(endEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void Web3DOverlay::update(float deltatime) {
|
||||
if (_webSurface) {
|
||||
|
|
|
@ -39,7 +39,8 @@ public:
|
|||
|
||||
QObject* getEventHandler();
|
||||
void setProxyWindow(QWindow* proxyWindow);
|
||||
void handlePointerEvent(const PointerEvent& event);
|
||||
Q_INVOKABLE void hoverLeaveOverlay(const PointerEvent& event);
|
||||
Q_INVOKABLE void handlePointerEvent(const PointerEvent& event);
|
||||
void handlePointerEventAsTouch(const PointerEvent& event);
|
||||
void handlePointerEventAsMouse(const PointerEvent& event);
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ class SoundCache : public ResourceCache, public Dependency {
|
|||
|
||||
public:
|
||||
Q_INVOKABLE SharedSoundPointer getSound(const QUrl& url);
|
||||
|
||||
protected:
|
||||
virtual QSharedPointer<Resource> createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
|
||||
const void* extra) override;
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "EntitiesRendererLogging.h"
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
#include "RenderableWebEntityItem.h"
|
||||
|
||||
size_t std::hash<EntityItemID>::operator()(const EntityItemID& id) const { return qHash(id); }
|
||||
std::function<bool()> EntityTreeRenderer::_entitiesShouldFadeFunction;
|
||||
|
||||
|
@ -55,6 +57,32 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
|
|||
EntityRenderer::initEntityRenderers();
|
||||
_currentHoverOverEntityID = UNKNOWN_ENTITY_ID;
|
||||
_currentClickingOnEntityID = UNKNOWN_ENTITY_ID;
|
||||
|
||||
// Forward mouse events to web entities
|
||||
auto handlePointerEvent = [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
|
||||
auto entity = getEntity(entityID);
|
||||
if (entity && entity->getType() == EntityTypes::Web) {
|
||||
thisEntity = std::static_pointer_cast<render::entities::WebEntityRenderer>(renderableForEntityId(entityID));
|
||||
}
|
||||
if (thisEntity) {
|
||||
QMetaObject::invokeMethod(thisEntity.get(), "handlePointerEvent", Q_ARG(PointerEvent, event));
|
||||
}
|
||||
};
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, handlePointerEvent);
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, handlePointerEvent);
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, handlePointerEvent);
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
|
||||
auto entity = getEntity(entityID);
|
||||
if (entity && entity->getType() == EntityTypes::Web) {
|
||||
thisEntity = std::static_pointer_cast<render::entities::WebEntityRenderer>(renderableForEntityId(entityID));
|
||||
}
|
||||
if (thisEntity) {
|
||||
QMetaObject::invokeMethod(thisEntity.get(), "hoverLeaveEntity", Q_ARG(PointerEvent, event));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
EntityTreeRenderer::~EntityTreeRenderer() {
|
||||
|
@ -78,13 +106,49 @@ render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& i
|
|||
int EntityTreeRenderer::_entitiesScriptEngineCount = 0;
|
||||
|
||||
void EntityTreeRenderer::resetEntitiesScriptEngine() {
|
||||
auto oldEngine = _entitiesScriptEngine;
|
||||
_entitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT,
|
||||
QString("about:Entities %1").arg(++_entitiesScriptEngineCount));
|
||||
_scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine);
|
||||
_entitiesScriptEngine->runInThread();
|
||||
auto entitiesScriptEngineProvider = qSharedPointerCast<EntitiesScriptEngineProvider>(_entitiesScriptEngine);
|
||||
DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(entitiesScriptEngineProvider);
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
entityScriptingInterface->setEntitiesScriptEngine(entitiesScriptEngineProvider);
|
||||
|
||||
// Connect mouse events to entity script callbacks
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event);
|
||||
// FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event);
|
||||
});
|
||||
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event);
|
||||
});
|
||||
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event);
|
||||
});
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::clear() {
|
||||
|
@ -264,8 +328,7 @@ void EntityTreeRenderer::update(bool simulate) {
|
|||
// not yet released the hold then this is still considered a holdingClickOnEntity event
|
||||
// and we want to simulate this message here as well as in mouse move
|
||||
if (_lastPointerEventValid && !_currentClickingOnEntityID.isInvalidID()) {
|
||||
emit holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent);
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", _lastPointerEvent);
|
||||
emit DependencyManager::get<EntityScriptingInterface>()->holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,19 +498,6 @@ void EntityTreeRenderer::processEraseMessage(ReceivedMessage& message, const Sha
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityScriptingInterface) {
|
||||
|
||||
connect(this, &EntityTreeRenderer::mousePressOnEntity, entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity);
|
||||
connect(this, &EntityTreeRenderer::mouseMoveOnEntity, entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity);
|
||||
connect(this, &EntityTreeRenderer::mouseReleaseOnEntity, entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity);
|
||||
|
||||
connect(this, &EntityTreeRenderer::clickDownOnEntity, entityScriptingInterface, &EntityScriptingInterface::clickDownOnEntity);
|
||||
connect(this, &EntityTreeRenderer::holdingClickOnEntity, entityScriptingInterface, &EntityScriptingInterface::holdingClickOnEntity);
|
||||
connect(this, &EntityTreeRenderer::clickReleaseOnEntity, entityScriptingInterface, &EntityScriptingInterface::clickReleaseOnEntity);
|
||||
|
||||
connect(this, &EntityTreeRenderer::hoverEnterEntity, entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity);
|
||||
connect(this, &EntityTreeRenderer::hoverOverEntity, entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity);
|
||||
connect(this, &EntityTreeRenderer::hoverLeaveEntity, entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity);
|
||||
|
||||
connect(this, &EntityTreeRenderer::enterEntity, entityScriptingInterface, &EntityScriptingInterface::enterEntity);
|
||||
connect(this, &EntityTreeRenderer::leaveEntity, entityScriptingInterface, &EntityScriptingInterface::leaveEntity);
|
||||
connect(this, &EntityTreeRenderer::collisionWithEntity, entityScriptingInterface, &EntityScriptingInterface::collisionWithEntity);
|
||||
|
@ -516,13 +566,11 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) {
|
|||
}
|
||||
|
||||
PerformanceTimer perfTimer("EntityTreeRenderer::mousePressEvent");
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
PickRay ray = _viewState->computePickRay(event->x(), event->y());
|
||||
RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID);
|
||||
if (rayPickResult.intersects) {
|
||||
//qCDebug(entitiesrenderer) << "mousePressEvent over entity:" << rayPickResult.entityID;
|
||||
|
||||
auto entity = getTree()->findEntityByEntityItemID(rayPickResult.entityID);
|
||||
auto properties = entity->getProperties();
|
||||
if (rayPickResult.intersects && rayPickResult.entity) {
|
||||
auto properties = rayPickResult.entity->getProperties();
|
||||
QString urlString = properties.getHref();
|
||||
QUrl url = QUrl(urlString, QUrl::StrictMode);
|
||||
if (url.isValid() && !url.isEmpty()){
|
||||
|
@ -536,23 +584,16 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) {
|
|||
toPointerButton(*event), toPointerButtons(*event),
|
||||
Qt::NoModifier); // TODO -- check for modifier keys?
|
||||
|
||||
emit mousePressOnEntity(rayPickResult.entityID, pointerEvent);
|
||||
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mousePressOnEntity", pointerEvent);
|
||||
}
|
||||
emit entityScriptingInterface->mousePressOnEntity(rayPickResult.entityID, pointerEvent);
|
||||
|
||||
_currentClickingOnEntityID = rayPickResult.entityID;
|
||||
emit clickDownOnEntity(_currentClickingOnEntityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "clickDownOnEntity", pointerEvent);
|
||||
}
|
||||
emit entityScriptingInterface->clickDownOnEntity(_currentClickingOnEntityID, pointerEvent);
|
||||
|
||||
_lastPointerEvent = pointerEvent;
|
||||
_lastPointerEventValid = true;
|
||||
|
||||
} else {
|
||||
emit mousePressOffEntity();
|
||||
emit entityScriptingInterface->mousePressOffEntity();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,34 +605,25 @@ void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) {
|
|||
}
|
||||
|
||||
PerformanceTimer perfTimer("EntityTreeRenderer::mouseDoublePressEvent");
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
PickRay ray = _viewState->computePickRay(event->x(), event->y());
|
||||
RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID);
|
||||
if (rayPickResult.intersects) {
|
||||
//qCDebug(entitiesrenderer) << "mouseDoublePressEvent over entity:" << rayPickResult.entityID;
|
||||
|
||||
if (rayPickResult.intersects && rayPickResult.entity) {
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Press, MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier);
|
||||
|
||||
emit mouseDoublePressOnEntity(rayPickResult.entityID, pointerEvent);
|
||||
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseDoublePressOnEntity", pointerEvent);
|
||||
}
|
||||
emit entityScriptingInterface->mouseDoublePressOnEntity(rayPickResult.entityID, pointerEvent);
|
||||
|
||||
_currentClickingOnEntityID = rayPickResult.entityID;
|
||||
emit clickDownOnEntity(_currentClickingOnEntityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "doubleclickOnEntity", pointerEvent);
|
||||
}
|
||||
emit entityScriptingInterface->clickDownOnEntity(_currentClickingOnEntityID, pointerEvent);
|
||||
|
||||
_lastPointerEvent = pointerEvent;
|
||||
_lastPointerEventValid = true;
|
||||
|
||||
} else {
|
||||
emit mouseDoublePressOffEntity();
|
||||
emit entityScriptingInterface->mouseDoublePressOffEntity();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -603,9 +635,10 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) {
|
|||
}
|
||||
|
||||
PerformanceTimer perfTimer("EntityTreeRenderer::mouseReleaseEvent");
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
PickRay ray = _viewState->computePickRay(event->x(), event->y());
|
||||
RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID);
|
||||
if (rayPickResult.intersects) {
|
||||
if (rayPickResult.intersects && rayPickResult.entity) {
|
||||
//qCDebug(entitiesrenderer) << "mouseReleaseEvent over entity:" << rayPickResult.entityID;
|
||||
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
|
@ -615,31 +648,23 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) {
|
|||
toPointerButton(*event), toPointerButtons(*event),
|
||||
Qt::NoModifier); // TODO -- check for modifier keys?
|
||||
|
||||
emit mouseReleaseOnEntity(rayPickResult.entityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseReleaseOnEntity", pointerEvent);
|
||||
}
|
||||
emit entityScriptingInterface->mouseReleaseOnEntity(rayPickResult.entityID, pointerEvent);
|
||||
|
||||
_lastPointerEvent = pointerEvent;
|
||||
_lastPointerEventValid = true;
|
||||
}
|
||||
|
||||
// Even if we're no longer intersecting with an entity, if we started clicking on it, and now
|
||||
// we're releasing the button, then this is considered a clickOn event
|
||||
// we're releasing the button, then this is considered a clickReleaseOn event
|
||||
if (!_currentClickingOnEntityID.isInvalidID()) {
|
||||
|
||||
auto entity = getTree()->findEntityByID(_currentClickingOnEntityID);
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult);
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Release, MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event),
|
||||
Qt::NoModifier); // TODO -- check for modifier keys?
|
||||
|
||||
emit clickReleaseOnEntity(_currentClickingOnEntityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "clickReleaseOnEntity", pointerEvent);
|
||||
}
|
||||
emit entityScriptingInterface->clickReleaseOnEntity(_currentClickingOnEntityID, pointerEvent);
|
||||
}
|
||||
|
||||
// makes it the unknown ID, we just released so we can't be clicking on anything
|
||||
|
@ -654,9 +679,10 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
|||
}
|
||||
|
||||
PerformanceTimer perfTimer("EntityTreeRenderer::mouseMoveEvent");
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
PickRay ray = _viewState->computePickRay(event->x(), event->y());
|
||||
RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID);
|
||||
if (rayPickResult.intersects) {
|
||||
if (rayPickResult.intersects && rayPickResult.entity) {
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
|
@ -664,48 +690,32 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
|||
toPointerButton(*event), toPointerButtons(*event),
|
||||
Qt::NoModifier); // TODO -- check for modifier keys?
|
||||
|
||||
emit mouseMoveOnEntity(rayPickResult.entityID, pointerEvent);
|
||||
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveEvent", pointerEvent);
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveOnEntity", pointerEvent);
|
||||
}
|
||||
emit entityScriptingInterface->mouseMoveOnEntity(rayPickResult.entityID, pointerEvent);
|
||||
|
||||
// handle the hover logic...
|
||||
|
||||
// if we were previously hovering over an entity, and this new entity is not the same as our previous entity
|
||||
// then we need to send the hover leave.
|
||||
if (!_currentHoverOverEntityID.isInvalidID() && rayPickResult.entityID != _currentHoverOverEntityID) {
|
||||
|
||||
auto entity = getTree()->findEntityByID(_currentHoverOverEntityID);
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult);
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event),
|
||||
Qt::NoModifier); // TODO -- check for modifier keys?
|
||||
|
||||
emit hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", pointerEvent);
|
||||
}
|
||||
emit entityScriptingInterface->hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent);
|
||||
}
|
||||
|
||||
// If the new hover entity does not match the previous hover entity then we are entering the new one
|
||||
// this is true if the _currentHoverOverEntityID is known or unknown
|
||||
if (rayPickResult.entityID != _currentHoverOverEntityID) {
|
||||
emit hoverEnterEntity(rayPickResult.entityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverEnterEntity", pointerEvent);
|
||||
}
|
||||
emit entityScriptingInterface->hoverEnterEntity(rayPickResult.entityID, pointerEvent);
|
||||
}
|
||||
|
||||
// and finally, no matter what, if we're intersecting an entity then we're definitely hovering over it, and
|
||||
// we should send our hover over event
|
||||
emit hoverOverEntity(rayPickResult.entityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverOverEntity", pointerEvent);
|
||||
}
|
||||
emit entityScriptingInterface->hoverOverEntity(rayPickResult.entityID, pointerEvent);
|
||||
|
||||
// remember what we're hovering over
|
||||
_currentHoverOverEntityID = rayPickResult.entityID;
|
||||
|
@ -718,38 +728,18 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
|||
// if we were previously hovering over an entity, and we're no longer hovering over any entity then we need to
|
||||
// send the hover leave for our previous entity
|
||||
if (!_currentHoverOverEntityID.isInvalidID()) {
|
||||
|
||||
auto entity = getTree()->findEntityByID(_currentHoverOverEntityID);
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult);
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event),
|
||||
Qt::NoModifier); // TODO -- check for modifier keys?
|
||||
|
||||
emit hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", pointerEvent);
|
||||
}
|
||||
emit entityScriptingInterface->hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent);
|
||||
_currentHoverOverEntityID = UNKNOWN_ENTITY_ID; // makes it the unknown ID
|
||||
}
|
||||
}
|
||||
|
||||
// Even if we're no longer intersecting with an entity, if we started clicking on an entity and we have
|
||||
// not yet released the hold then this is still considered a holdingClickOnEntity event
|
||||
if (!_currentClickingOnEntityID.isInvalidID()) {
|
||||
|
||||
auto entity = getTree()->findEntityByID(_currentClickingOnEntityID);
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event),
|
||||
Qt::NoModifier); // TODO -- check for modifier keys?
|
||||
|
||||
emit holdingClickOnEntity(_currentClickingOnEntityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", pointerEvent);
|
||||
_lastPointerEvent = pointerEvent;
|
||||
_lastPointerEventValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,21 +117,6 @@ public:
|
|||
void onEntityChanged(const EntityItemID& id);
|
||||
|
||||
signals:
|
||||
void mousePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void mouseDoublePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void mouseMoveOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void mouseReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void mousePressOffEntity();
|
||||
void mouseDoublePressOffEntity();
|
||||
|
||||
void clickDownOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void holdingClickOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void clickReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
|
||||
void hoverEnterEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void hoverOverEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void hoverLeaveEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
|
||||
void enterEntity(const EntityItemID& entityItemID);
|
||||
void leaveEntity(const EntityItemID& entityItemID);
|
||||
void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <ui/TabletScriptingInterface.h>
|
||||
#include <EntityScriptingInterface.h>
|
||||
|
||||
#include "EntityTreeRenderer.h"
|
||||
#include "EntitiesRendererLogging.h"
|
||||
|
||||
|
||||
|
@ -86,6 +85,10 @@ bool WebEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointe
|
|||
return true;
|
||||
}
|
||||
|
||||
if (_lastLocked != entity->getLocked()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -136,6 +139,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
|||
}
|
||||
|
||||
_lastDPI = entity->getDPI();
|
||||
_lastLocked = entity->getLocked();
|
||||
|
||||
glm::vec2 windowSize = getWindowSize(entity);
|
||||
_webSurface->resize(QSize(windowSize.x, windowSize.y));
|
||||
|
@ -234,38 +238,6 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) {
|
|||
emit entities->webEventReceived(entityItemID, message);
|
||||
});
|
||||
|
||||
auto forwardPointerEvent = [=](const EntityItemID& entityItemID, const PointerEvent& event) {
|
||||
if (entityItemID == entity->getID()) {
|
||||
handlePointerEvent(entity, event);
|
||||
}
|
||||
};
|
||||
|
||||
auto renderer = DependencyManager::get<EntityTreeRenderer>();
|
||||
QObject::connect(renderer.data(), &EntityTreeRenderer::mousePressOnEntity, this, forwardPointerEvent);
|
||||
QObject::connect(renderer.data(), &EntityTreeRenderer::mouseReleaseOnEntity, this, forwardPointerEvent);
|
||||
QObject::connect(renderer.data(), &EntityTreeRenderer::mouseMoveOnEntity, this, forwardPointerEvent);
|
||||
QObject::connect(renderer.data(), &EntityTreeRenderer::hoverLeaveEntity, this,
|
||||
[=](const EntityItemID& entityItemID, const PointerEvent& event) {
|
||||
if (this->_pressed && entity->getID() == entityItemID) {
|
||||
// If the user mouses off the entity while the button is down, simulate a touch end.
|
||||
QTouchEvent::TouchPoint point;
|
||||
point.setId(event.getID());
|
||||
point.setState(Qt::TouchPointReleased);
|
||||
glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _lastDPI);
|
||||
QPointF windowPoint(windowPos.x, windowPos.y);
|
||||
point.setScenePos(windowPoint);
|
||||
point.setPos(windowPoint);
|
||||
QList<QTouchEvent::TouchPoint> touchPoints;
|
||||
touchPoints.push_back(point);
|
||||
QTouchEvent* touchEvent = new QTouchEvent(QEvent::TouchEnd, nullptr,
|
||||
Qt::NoModifier, Qt::TouchPointReleased, touchPoints);
|
||||
touchEvent->setWindow(_webSurface->getWindow());
|
||||
touchEvent->setDevice(&_touchDevice);
|
||||
touchEvent->setTarget(_webSurface->getRootItem());
|
||||
QCoreApplication::postEvent(_webSurface->getWindow(), touchEvent);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -295,13 +267,6 @@ void WebEntityRenderer::destroyWebSurface() {
|
|||
}
|
||||
|
||||
webSurface->pause();
|
||||
auto renderer = DependencyManager::get<EntityTreeRenderer>();
|
||||
if (renderer) {
|
||||
QObject::disconnect(renderer.data(), &EntityTreeRenderer::mousePressOnEntity, this, nullptr);
|
||||
QObject::disconnect(renderer.data(), &EntityTreeRenderer::mouseReleaseOnEntity, this, nullptr);
|
||||
QObject::disconnect(renderer.data(), &EntityTreeRenderer::mouseMoveOnEntity, this, nullptr);
|
||||
QObject::disconnect(renderer.data(), &EntityTreeRenderer::hoverLeaveEntity, this, nullptr);
|
||||
}
|
||||
webSurface.reset();
|
||||
}
|
||||
}
|
||||
|
@ -347,13 +312,34 @@ void WebEntityRenderer::loadSourceURL() {
|
|||
}
|
||||
}
|
||||
|
||||
void WebEntityRenderer::handlePointerEvent(const TypedEntityPointer& entity, const PointerEvent& event) {
|
||||
void WebEntityRenderer::hoverLeaveEntity(const PointerEvent& event) {
|
||||
if (!_lastLocked && _webSurface && _pressed) {
|
||||
// If the user mouses off the entity while the button is down, simulate a touch end.
|
||||
QTouchEvent::TouchPoint point;
|
||||
point.setId(event.getID());
|
||||
point.setState(Qt::TouchPointReleased);
|
||||
glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _lastDPI);
|
||||
QPointF windowPoint(windowPos.x, windowPos.y);
|
||||
point.setScenePos(windowPoint);
|
||||
point.setPos(windowPoint);
|
||||
QList<QTouchEvent::TouchPoint> touchPoints;
|
||||
touchPoints.push_back(point);
|
||||
QTouchEvent* touchEvent = new QTouchEvent(QEvent::TouchEnd, nullptr,
|
||||
Qt::NoModifier, Qt::TouchPointReleased, touchPoints);
|
||||
touchEvent->setWindow(_webSurface->getWindow());
|
||||
touchEvent->setDevice(&_touchDevice);
|
||||
touchEvent->setTarget(_webSurface->getRootItem());
|
||||
QCoreApplication::postEvent(_webSurface->getWindow(), touchEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void WebEntityRenderer::handlePointerEvent(const PointerEvent& event) {
|
||||
// Ignore mouse interaction if we're locked
|
||||
if (entity->getLocked() || !_webSurface) {
|
||||
if (_lastLocked || !_webSurface) {
|
||||
return;
|
||||
}
|
||||
|
||||
glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * entity->getDPI());
|
||||
glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _lastDPI);
|
||||
QPointF windowPoint(windowPos.x, windowPos.y);
|
||||
if (event.getType() == PointerEvent::Move) {
|
||||
// Forward a mouse move event to webSurface
|
||||
|
|
|
@ -18,12 +18,16 @@ class PointerEvent;
|
|||
namespace render { namespace entities {
|
||||
|
||||
class WebEntityRenderer : public TypedEntityRenderer<WebEntityItem> {
|
||||
Q_OBJECT
|
||||
using Parent = TypedEntityRenderer<WebEntityItem>;
|
||||
friend class EntityRenderer;
|
||||
|
||||
public:
|
||||
WebEntityRenderer(const EntityItemPointer& entity);
|
||||
|
||||
Q_INVOKABLE void hoverLeaveEntity(const PointerEvent& event);
|
||||
Q_INVOKABLE void handlePointerEvent(const PointerEvent& event);
|
||||
|
||||
protected:
|
||||
virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override;
|
||||
virtual bool needsRenderUpdate() const override;
|
||||
|
@ -44,9 +48,6 @@ private:
|
|||
bool hasWebSurface();
|
||||
void loadSourceURL();
|
||||
glm::vec2 getWindowSize(const TypedEntityPointer& entity) const;
|
||||
void handlePointerEvent(const TypedEntityPointer& entity, const PointerEvent& event);
|
||||
|
||||
private:
|
||||
|
||||
int _geometryId{ 0 };
|
||||
enum contentType {
|
||||
|
@ -60,6 +61,7 @@ private:
|
|||
bool _pressed{ false };
|
||||
QString _lastSourceUrl;
|
||||
uint16_t _lastDPI;
|
||||
bool _lastLocked;
|
||||
QTimer _timer;
|
||||
uint64_t _lastRenderTime { 0 };
|
||||
Transform _renderTransform;
|
||||
|
|
|
@ -51,6 +51,10 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership
|
|||
connect(nodeList.data(), &NodeList::canRezTmpCertifiedChanged, this, &EntityScriptingInterface::canRezTmpCertifiedChanged);
|
||||
connect(nodeList.data(), &NodeList::canWriteAssetsChanged, this, &EntityScriptingInterface::canWriteAssetsChanged);
|
||||
|
||||
// If the user clicks somewhere where there is no entity at all, we will release focus
|
||||
connect(this, &EntityScriptingInterface::mousePressOffEntity, [=]() {
|
||||
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||
});
|
||||
|
||||
auto& packetReceiver = nodeList->getPacketReceiver();
|
||||
packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket");
|
||||
|
@ -1674,44 +1678,44 @@ QUuid EntityScriptingInterface::getKeyboardFocusEntity() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::setKeyboardFocusEntity(QUuid id) {
|
||||
QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::QueuedConnection, Q_ARG(QUuid, id));
|
||||
void EntityScriptingInterface::setKeyboardFocusEntity(const EntityItemID& id) {
|
||||
QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::DirectConnection, Q_ARG(EntityItemID, id));
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::sendMousePressOnEntity(QUuid id, PointerEvent event) {
|
||||
QMetaObject::invokeMethod(qApp, "sendMousePressOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
|
||||
void EntityScriptingInterface::sendMousePressOnEntity(const EntityItemID& id, const PointerEvent& event) {
|
||||
emit mousePressOnEntity(id, event);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::sendMouseMoveOnEntity(QUuid id, PointerEvent event) {
|
||||
QMetaObject::invokeMethod(qApp, "sendMouseMoveOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
|
||||
void EntityScriptingInterface::sendMouseMoveOnEntity(const EntityItemID& id, const PointerEvent& event) {
|
||||
emit mouseMoveOnEntity(id, event);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::sendMouseReleaseOnEntity(QUuid id, PointerEvent event) {
|
||||
QMetaObject::invokeMethod(qApp, "sendMouseReleaseOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
|
||||
void EntityScriptingInterface::sendMouseReleaseOnEntity(const EntityItemID& id, const PointerEvent& event) {
|
||||
emit mouseReleaseOnEntity(id, event);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::sendClickDownOnEntity(QUuid id, PointerEvent event) {
|
||||
QMetaObject::invokeMethod(qApp, "sendClickDownOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
|
||||
void EntityScriptingInterface::sendClickDownOnEntity(const EntityItemID& id, const PointerEvent& event) {
|
||||
emit clickDownOnEntity(id, event);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::sendHoldingClickOnEntity(QUuid id, PointerEvent event) {
|
||||
QMetaObject::invokeMethod(qApp, "sendHoldingClickOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
|
||||
void EntityScriptingInterface::sendHoldingClickOnEntity(const EntityItemID& id, const PointerEvent& event) {
|
||||
emit holdingClickOnEntity(id, event);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::sendClickReleaseOnEntity(QUuid id, PointerEvent event) {
|
||||
QMetaObject::invokeMethod(qApp, "sendClickReleaseOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
|
||||
void EntityScriptingInterface::sendClickReleaseOnEntity(const EntityItemID& id, const PointerEvent& event) {
|
||||
emit clickReleaseOnEntity(id, event);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::sendHoverEnterEntity(QUuid id, PointerEvent event) {
|
||||
QMetaObject::invokeMethod(qApp, "sendHoverEnterEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
|
||||
void EntityScriptingInterface::sendHoverEnterEntity(const EntityItemID& id, const PointerEvent& event) {
|
||||
emit hoverEnterEntity(id, event);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::sendHoverOverEntity(QUuid id, PointerEvent event) {
|
||||
QMetaObject::invokeMethod(qApp, "sendHoverOverEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
|
||||
void EntityScriptingInterface::sendHoverOverEntity(const EntityItemID& id, const PointerEvent& event) {
|
||||
emit hoverOverEntity(id, event);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::sendHoverLeaveEntity(QUuid id, PointerEvent event) {
|
||||
QMetaObject::invokeMethod(qApp, "sendHoverLeaveEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
|
||||
void EntityScriptingInterface::sendHoverLeaveEntity(const EntityItemID& id, const PointerEvent& event) {
|
||||
emit hoverLeaveEntity(id, event);
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::wantsHandControllerPointerEvents(QUuid id) {
|
||||
|
|
|
@ -380,19 +380,19 @@ public slots:
|
|||
Q_INVOKABLE QString getNestableType(QUuid id);
|
||||
|
||||
Q_INVOKABLE QUuid getKeyboardFocusEntity() const;
|
||||
Q_INVOKABLE void setKeyboardFocusEntity(QUuid id);
|
||||
Q_INVOKABLE void setKeyboardFocusEntity(const EntityItemID& id);
|
||||
|
||||
Q_INVOKABLE void sendMousePressOnEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendMouseMoveOnEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendMouseReleaseOnEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendMousePressOnEntity(const EntityItemID& id, const PointerEvent& event);
|
||||
Q_INVOKABLE void sendMouseMoveOnEntity(const EntityItemID& id, const PointerEvent& event);
|
||||
Q_INVOKABLE void sendMouseReleaseOnEntity(const EntityItemID& id, const PointerEvent& event);
|
||||
|
||||
Q_INVOKABLE void sendClickDownOnEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendHoldingClickOnEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendClickReleaseOnEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendClickDownOnEntity(const EntityItemID& id, const PointerEvent& event);
|
||||
Q_INVOKABLE void sendHoldingClickOnEntity(const EntityItemID& id, const PointerEvent& event);
|
||||
Q_INVOKABLE void sendClickReleaseOnEntity(const EntityItemID& id, const PointerEvent& event);
|
||||
|
||||
Q_INVOKABLE void sendHoverEnterEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendHoverOverEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendHoverLeaveEntity(QUuid id, PointerEvent event);
|
||||
Q_INVOKABLE void sendHoverEnterEntity(const EntityItemID& id, const PointerEvent& event);
|
||||
Q_INVOKABLE void sendHoverOverEntity(const EntityItemID& id, const PointerEvent& event);
|
||||
Q_INVOKABLE void sendHoverLeaveEntity(const EntityItemID& id, const PointerEvent& event);
|
||||
|
||||
Q_INVOKABLE bool wantsHandControllerPointerEvents(QUuid id);
|
||||
|
||||
|
@ -439,8 +439,11 @@ signals:
|
|||
void canWriteAssetsChanged(bool canWriteAssets);
|
||||
|
||||
void mousePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void mouseDoublePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void mouseMoveOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void mouseReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void mousePressOffEntity();
|
||||
void mouseDoublePressOffEntity();
|
||||
|
||||
void clickDownOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
void holdingClickOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
|
|
|
@ -511,12 +511,19 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
|
||||
auto keyLight = lightAndShadow.first;
|
||||
|
||||
model::LightPointer keyAmbientLight;
|
||||
if (lightStage && lightStage->_currentFrame._ambientLights.size()) {
|
||||
keyAmbientLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front());
|
||||
}
|
||||
bool hasAmbientMap = (keyAmbientLight != nullptr);
|
||||
|
||||
// Setup the global directional pass pipeline
|
||||
{
|
||||
if (deferredLightingEffect->_shadowMapEnabled) {
|
||||
|
||||
// If the keylight has an ambient Map then use the Skybox version of the pass
|
||||
// otherwise use the ambient sphere version
|
||||
if (keyLight->getAmbientMap()) {
|
||||
if (hasAmbientMap) {
|
||||
program = deferredLightingEffect->_directionalSkyboxLightShadow;
|
||||
locations = deferredLightingEffect->_directionalSkyboxLightShadowLocations;
|
||||
} else {
|
||||
|
@ -526,7 +533,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
} else {
|
||||
// If the keylight has an ambient Map then use the Skybox version of the pass
|
||||
// otherwise use the ambient sphere version
|
||||
if (keyLight->getAmbientMap()) {
|
||||
if (hasAmbientMap) {
|
||||
program = deferredLightingEffect->_directionalSkyboxLight;
|
||||
locations = deferredLightingEffect->_directionalSkyboxLightLocations;
|
||||
} else {
|
||||
|
|
|
@ -138,7 +138,7 @@ void main(void) {
|
|||
}
|
||||
|
||||
// Mix with background at far range
|
||||
const float BLEND_DISTANCE = 30000.0;
|
||||
const float BLEND_DISTANCE = 27000.0;
|
||||
if (distance > BLEND_DISTANCE) {
|
||||
outFragColor = mix(potentialFragColor, fragColor, hazeParams.backgroundBlendValue);
|
||||
} else {
|
||||
|
|
|
@ -97,7 +97,6 @@ static const bool HIFI_AUTOREFRESH_FILE_SCRIPTS { true };
|
|||
Q_DECLARE_METATYPE(QScriptEngine::FunctionSignature)
|
||||
int functionSignatureMetaID = qRegisterMetaType<QScriptEngine::FunctionSignature>();
|
||||
|
||||
Q_DECLARE_METATYPE(ScriptEnginePointer)
|
||||
int scriptEnginePointerMetaID = qRegisterMetaType<ScriptEnginePointer>();
|
||||
|
||||
Q_LOGGING_CATEGORY(scriptengineScript, "hifi.scriptengine.script")
|
||||
|
|
|
@ -55,6 +55,8 @@ static const int DEFAULT_ENTITY_PPS_PER_SCRIPT = 900;
|
|||
|
||||
class ScriptEngines;
|
||||
|
||||
Q_DECLARE_METATYPE(ScriptEnginePointer)
|
||||
|
||||
class CallbackData {
|
||||
public:
|
||||
QScriptValue function;
|
||||
|
|
|
@ -119,6 +119,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
this.actionID = null; // action this script created...
|
||||
this.entityWithContextOverlay = false;
|
||||
this.contextOverlayTimer = false;
|
||||
this.previousCollisionStatus = false;
|
||||
this.reticleMinX = MARGIN;
|
||||
this.reticleMaxX;
|
||||
this.reticleMinY = MARGIN;
|
||||
|
@ -342,7 +343,9 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
if (this.madeDynamic) {
|
||||
var props = {};
|
||||
props.dynamic = false;
|
||||
props.collisionless = this.previousCollisionStatus;
|
||||
props.localVelocity = {x: 0, y: 0, z: 0};
|
||||
props.localRotation = {x: 0, y: 0, z: 0};
|
||||
Entities.editEntity(this.grabbedThingID, props);
|
||||
this.madeDynamic = false;
|
||||
}
|
||||
|
@ -507,10 +510,12 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
if (entityIsGrabbable(targetProps)) {
|
||||
if (!entityIsDistanceGrabbable(targetProps)) {
|
||||
targetProps.dynamic = true;
|
||||
this.previousCollisionStatus = targetProps.collisionless;
|
||||
targetProps.collisionless = true;
|
||||
Entities.editEntity(entityID, targetProps);
|
||||
this.madeDynamic = true;
|
||||
}
|
||||
|
||||
|
||||
if (!this.distanceRotating) {
|
||||
this.grabbedThingID = entityID;
|
||||
this.grabbedDistance = rayPickInfo.distance;
|
||||
|
|
|
@ -1373,7 +1373,7 @@ function loaded() {
|
|||
elShape.addEventListener('change', createEmitTextPropertyUpdateFunction('shape'));
|
||||
|
||||
elWebSourceURL.addEventListener('change', createEmitTextPropertyUpdateFunction('sourceUrl'));
|
||||
elWebDPI.addEventListener('change', createEmitNumberPropertyUpdateFunction('dpi'));
|
||||
elWebDPI.addEventListener('change', createEmitNumberPropertyUpdateFunction('dpi', 0));
|
||||
|
||||
elModelURL.addEventListener('change', createEmitTextPropertyUpdateFunction('modelURL'));
|
||||
elShapeType.addEventListener('change', createEmitTextPropertyUpdateFunction('shapeType'));
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,89 +0,0 @@
|
|||
//
|
||||
// spawnStopwatch.js
|
||||
//
|
||||
// Created by Ryan Huffman on 1/20/17.
|
||||
// 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
|
||||
//
|
||||
|
||||
var forward = Quat.getFront(MyAvatar.orientation);
|
||||
Vec3.print("Forward: ", forward);
|
||||
var positionToSpawn = Vec3.sum(MyAvatar.position, Vec3.multiply(3, forward));
|
||||
var scale = 0.5;
|
||||
positionToSpawn.y += 0.5;
|
||||
|
||||
var stopwatchID = Entities.addEntity({
|
||||
type: "Model",
|
||||
name: "stopwatch/base",
|
||||
position: positionToSpawn,
|
||||
modelURL: Script.resolvePath("models/Stopwatch.fbx"),
|
||||
dimensions: Vec3.multiply(scale, {"x":4.129462242126465,"y":1.058512806892395,"z":5.773681640625}),
|
||||
rotation: Quat.multiply(MyAvatar.orientation, Quat.fromPitchYawRollDegrees(90, 0, 0))
|
||||
});
|
||||
|
||||
var secondHandID = Entities.addEntity({
|
||||
type: "Model",
|
||||
name: "stopwatch/seconds",
|
||||
parentID: stopwatchID,
|
||||
localPosition: Vec3.multiply(scale, {"x":-0.004985813982784748,"y":0.39391064643859863,"z":0.8312804698944092}),
|
||||
dimensions: Vec3.multiply(scale, {"x":0.14095762372016907,"y":0.02546107769012451,"z":1.6077008247375488}),
|
||||
registrationPoint: {"x":0.5,"y":0.5,"z":1},
|
||||
modelURL: Script.resolvePath("models/Stopwatch-sec-hand.fbx"),
|
||||
});
|
||||
|
||||
var minuteHandID = Entities.addEntity({
|
||||
type: "Model",
|
||||
name: "stopwatch/minutes",
|
||||
parentID: stopwatchID,
|
||||
localPosition: Vec3.multiply(scale, {"x":-0.0023056098725646734,"y":0.3308190703392029,"z":0.21810021996498108}),
|
||||
dimensions: Vec3.multiply(scale, {"x":0.045471154153347015,"y":0.015412690117955208,"z":0.22930574417114258}),
|
||||
registrationPoint: {"x":0.5,"y":0.5,"z":1},
|
||||
modelURL: Script.resolvePath("models/Stopwatch-min-hand.fbx"),
|
||||
});
|
||||
|
||||
var startStopButtonID = Entities.addEntity({
|
||||
type: "Model",
|
||||
name: "stopwatch/startStop",
|
||||
parentID: stopwatchID,
|
||||
dimensions: Vec3.multiply(scale, { x: 0.8, y: 0.8, z: 1.0 }),
|
||||
localPosition: Vec3.multiply(scale, { x: 0, y: -0.1, z: -2.06 }),
|
||||
modelURL: Script.resolvePath("models/transparent-box.fbx")
|
||||
});
|
||||
|
||||
var resetButtonID = Entities.addEntity({
|
||||
type: "Model",
|
||||
name: "stopwatch/startStop",
|
||||
parentID: stopwatchID,
|
||||
dimensions: Vec3.multiply(scale, { x: 0.6, y: 0.6, z: 0.8 }),
|
||||
localPosition: Vec3.multiply(scale, { x: -1.5, y: -0.1, z: -1.2 }),
|
||||
localRotation: Quat.fromVec3Degrees({ x: 0, y: 36, z: 0 }),
|
||||
modelURL: Script.resolvePath("models/transparent-box.fbx")
|
||||
});
|
||||
|
||||
Entities.editEntity(stopwatchID, {
|
||||
userData: JSON.stringify({
|
||||
secondHandID: secondHandID,
|
||||
minuteHandID: minuteHandID
|
||||
}),
|
||||
serverScripts: Script.resolvePath("stopwatchServer.js")
|
||||
});
|
||||
|
||||
Entities.editEntity(startStopButtonID, {
|
||||
userData: JSON.stringify({
|
||||
stopwatchID: stopwatchID,
|
||||
grabbableKey: { wantsTrigger: true }
|
||||
}),
|
||||
script: Script.resolvePath("stopwatchStartStop.js")
|
||||
});
|
||||
|
||||
Entities.editEntity(resetButtonID, {
|
||||
userData: JSON.stringify({
|
||||
stopwatchID: stopwatchID,
|
||||
grabbableKey: { wantsTrigger: true }
|
||||
}),
|
||||
script: Script.resolvePath("stopwatchReset.js")
|
||||
});
|
||||
|
||||
Script.stop()
|
|
@ -1,22 +0,0 @@
|
|||
//
|
||||
// stopwatchReset.js
|
||||
//
|
||||
// Created by David Rowe on 26 May 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 () {
|
||||
this.preload = function (entityID) {
|
||||
var properties = Entities.getEntityProperties(entityID, "userData");
|
||||
this.messageChannel = "STOPWATCH-" + JSON.parse(properties.userData).stopwatchID;
|
||||
};
|
||||
function click() {
|
||||
Messages.sendMessage(this.messageChannel, "reset");
|
||||
}
|
||||
this.startNearTrigger = click;
|
||||
this.startFarTrigger = click;
|
||||
this.clickDownOnEntity = click;
|
||||
});
|
|
@ -1,132 +0,0 @@
|
|||
//
|
||||
// stopwatchServer.js
|
||||
//
|
||||
// Created by Ryan Huffman on 1/20/17.
|
||||
// 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 self = this;
|
||||
|
||||
self.equipped = false;
|
||||
self.isActive = false;
|
||||
self.seconds = 0;
|
||||
|
||||
self.secondHandID = null;
|
||||
self.minuteHandID = null;
|
||||
|
||||
self.tickSound = SoundCache.getSound(Script.resolvePath("sounds/tick.wav"));
|
||||
self.tickInjector = null;
|
||||
self.tickIntervalID = null;
|
||||
|
||||
self.chimeSound = SoundCache.getSound(Script.resolvePath("sounds/chime.wav"));
|
||||
|
||||
self.preload = function(entityID) {
|
||||
print("Preloading stopwatch: ", entityID);
|
||||
self.entityID = entityID;
|
||||
self.messageChannel = "STOPWATCH-" + entityID;
|
||||
|
||||
var userData = Entities.getEntityProperties(self.entityID, 'userData').userData;
|
||||
var data = JSON.parse(userData);
|
||||
self.secondHandID = data.secondHandID;
|
||||
self.minuteHandID = data.minuteHandID;
|
||||
|
||||
self.resetTimer();
|
||||
|
||||
Messages.subscribe(self.messageChannel);
|
||||
Messages.messageReceived.connect(this, self.messageReceived);
|
||||
};
|
||||
self.unload = function() {
|
||||
print("Unloading stopwatch:", self.entityID);
|
||||
self.resetTimer();
|
||||
Messages.unsubscribe(self.messageChannel);
|
||||
Messages.messageReceived.disconnect(this, self.messageReceived);
|
||||
};
|
||||
self.messageReceived = function(channel, message, sender) {
|
||||
print("Message received", channel, sender, message);
|
||||
if (channel === self.messageChannel) {
|
||||
switch (message) {
|
||||
case "startStop":
|
||||
if (self.isActive) {
|
||||
self.stopTimer();
|
||||
} else {
|
||||
self.startTimer();
|
||||
}
|
||||
break;
|
||||
case "reset":
|
||||
self.stopTimer();
|
||||
self.resetTimer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
self.getStopwatchPosition = function() {
|
||||
return Entities.getEntityProperties(self.entityID, "position").position;
|
||||
};
|
||||
self.resetTimer = function() {
|
||||
print("Resetting stopwatch");
|
||||
Entities.editEntity(self.secondHandID, {
|
||||
localRotation: Quat.fromPitchYawRollDegrees(0, 0, 0),
|
||||
angularVelocity: { x: 0, y: 0, z: 0 },
|
||||
});
|
||||
Entities.editEntity(self.minuteHandID, {
|
||||
localRotation: Quat.fromPitchYawRollDegrees(0, 0, 0),
|
||||
angularVelocity: { x: 0, y: 0, z: 0 },
|
||||
});
|
||||
self.seconds = 0;
|
||||
};
|
||||
self.startTimer = function() {
|
||||
print("Starting stopwatch");
|
||||
if (!self.tickInjector) {
|
||||
self.tickInjector = Audio.playSound(self.tickSound, {
|
||||
position: self.getStopwatchPosition(),
|
||||
volume: 0.7,
|
||||
loop: true
|
||||
});
|
||||
} else {
|
||||
self.tickInjector.restart();
|
||||
}
|
||||
|
||||
self.tickIntervalID = Script.setInterval(function() {
|
||||
if (self.tickInjector) {
|
||||
self.tickInjector.setOptions({
|
||||
position: self.getStopwatchPosition(),
|
||||
volume: 0.7,
|
||||
loop: true
|
||||
});
|
||||
}
|
||||
self.seconds++;
|
||||
const degreesPerTick = -360 / 60;
|
||||
Entities.editEntity(self.secondHandID, {
|
||||
localRotation: Quat.fromPitchYawRollDegrees(0, self.seconds * degreesPerTick, 0),
|
||||
});
|
||||
|
||||
if (self.seconds % 60 == 0) {
|
||||
Entities.editEntity(self.minuteHandID, {
|
||||
localRotation: Quat.fromPitchYawRollDegrees(0, (self.seconds / 60) * degreesPerTick, 0),
|
||||
});
|
||||
Audio.playSound(self.chimeSound, {
|
||||
position: self.getStopwatchPosition(),
|
||||
volume: 1.0,
|
||||
loop: false
|
||||
});
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
self.isActive = true;
|
||||
};
|
||||
self.stopTimer = function () {
|
||||
print("Stopping stopwatch");
|
||||
if (self.tickInjector) {
|
||||
self.tickInjector.stop();
|
||||
}
|
||||
if (self.tickIntervalID !== null) {
|
||||
Script.clearInterval(self.tickIntervalID);
|
||||
self.tickIntervalID = null;
|
||||
}
|
||||
self.isActive = false;
|
||||
};
|
||||
});
|
|
@ -1,23 +0,0 @@
|
|||
//
|
||||
// stopwatchStartStop.js
|
||||
//
|
||||
// Created by David Rowe on 26 May 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 messageChannel;
|
||||
this.preload = function (entityID) {
|
||||
var properties = Entities.getEntityProperties(entityID, "userData");
|
||||
this.messageChannel = "STOPWATCH-" + JSON.parse(properties.userData).stopwatchID;
|
||||
};
|
||||
function click() {
|
||||
Messages.sendMessage(this.messageChannel, "startStop");
|
||||
}
|
||||
this.startNearTrigger = click;
|
||||
this.startFarTrigger = click;
|
||||
this.clickDownOnEntity = click;
|
||||
});
|
Loading…
Reference in a new issue