mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 05:37:17 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into newUpdateCertLocation
This commit is contained in:
commit
32e5e9986f
21 changed files with 405 additions and 335 deletions
|
@ -312,7 +312,7 @@ if (APPLE)
|
||||||
COMPONENT ${CLIENT_COMPONENT}
|
COMPONENT ${CLIENT_COMPONENT}
|
||||||
)
|
)
|
||||||
|
|
||||||
set(RESOURCES_INSTALL_DIR "${INTERFACE_INSTALL_APP_PATH}/Contents/Resources")
|
set(SCRIPTS_INSTALL_DIR "${INTERFACE_INSTALL_APP_PATH}/Contents/Resources")
|
||||||
set(RESOURCES_DEV_DIR "$<TARGET_FILE_DIR:${TARGET_NAME}>/../Resources")
|
set(RESOURCES_DEV_DIR "$<TARGET_FILE_DIR:${TARGET_NAME}>/../Resources")
|
||||||
|
|
||||||
# copy script files beside the executable
|
# copy script files beside the executable
|
||||||
|
@ -326,13 +326,14 @@ if (APPLE)
|
||||||
fixup_interface()
|
fixup_interface()
|
||||||
|
|
||||||
else()
|
else()
|
||||||
set(RESOURCES_DEV_DIR "$<TARGET_FILE_DIR:${TARGET_NAME}>/resources")
|
set(INTERFACE_EXEC_DIR "$<TARGET_FILE_DIR:${TARGET_NAME}>")
|
||||||
|
set(RESOURCES_DEV_DIR "${INTERFACE_EXEC_DIR}/resources")
|
||||||
|
|
||||||
# copy the resources files beside the executable
|
# copy the resources files beside the executable
|
||||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||||
"${RESOURCES_RCC}"
|
"${RESOURCES_RCC}"
|
||||||
"$<TARGET_FILE_DIR:interface>"
|
"${INTERFACE_EXEC_DIR}"
|
||||||
# FIXME, the edit script code loads HTML from the scripts folder
|
# FIXME, the edit script code loads HTML from the scripts folder
|
||||||
# which in turn relies on CSS that refers to the fonts. In theory
|
# which in turn relies on CSS that refers to the fonts. In theory
|
||||||
# we should be able to modify the CSS to reference the QRC path to
|
# we should be able to modify the CSS to reference the QRC path to
|
||||||
|
@ -340,13 +341,13 @@ else()
|
||||||
# so we have to retain a copy of the fonts outside of the resources binary
|
# so we have to retain a copy of the fonts outside of the resources binary
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||||
"${PROJECT_SOURCE_DIR}/resources/fonts"
|
"${PROJECT_SOURCE_DIR}/resources/fonts"
|
||||||
"$<TARGET_FILE_DIR:${TARGET_NAME}>/resources/fonts"
|
"${RESOURCES_DEV_DIR}/fonts"
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||||
"${CMAKE_SOURCE_DIR}/scripts"
|
"${CMAKE_SOURCE_DIR}/scripts"
|
||||||
"${RESOURCES_DEV_DIR}/scripts"
|
"${INTERFACE_EXEC_DIR}/scripts"
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||||
"${PROJECT_SOURCE_DIR}/resources/serverless/tutorial.json"
|
"${PROJECT_SOURCE_DIR}/resources/serverless/tutorial.json"
|
||||||
"$<TARGET_FILE_DIR:${TARGET_NAME}>/resources/serverless/tutorial.json"
|
"${RESOURCES_DEV_DIR}/serverless/tutorial.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
# link target to external libraries
|
# link target to external libraries
|
||||||
|
@ -363,7 +364,7 @@ else()
|
||||||
PATTERN "*.exp" EXCLUDE
|
PATTERN "*.exp" EXCLUDE
|
||||||
)
|
)
|
||||||
|
|
||||||
set(RESOURCES_INSTALL_DIR "${INTERFACE_INSTALL_DIR}")
|
set(SCRIPTS_INSTALL_DIR "${INTERFACE_INSTALL_DIR}")
|
||||||
|
|
||||||
set(EXECUTABLE_COMPONENT ${CLIENT_COMPONENT})
|
set(EXECUTABLE_COMPONENT ${CLIENT_COMPONENT})
|
||||||
|
|
||||||
|
@ -371,11 +372,11 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (RESOURCES_INSTALL_DIR)
|
if (SCRIPTS_INSTALL_DIR)
|
||||||
# setup install of scripts beside interface executable
|
# setup install of scripts beside interface executable
|
||||||
install(
|
install(
|
||||||
DIRECTORY "${CMAKE_SOURCE_DIR}/scripts/"
|
DIRECTORY "${CMAKE_SOURCE_DIR}/scripts/"
|
||||||
DESTINATION ${RESOURCES_INSTALL_DIR}/scripts
|
DESTINATION ${SCRIPTS_INSTALL_DIR}/scripts
|
||||||
COMPONENT ${CLIENT_COMPONENT}
|
COMPONENT ${CLIENT_COMPONENT}
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -67,6 +67,10 @@ Item {
|
||||||
fill: parent
|
fill: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
QmlHifi.WindowHeader {
|
QmlHifi.WindowHeader {
|
||||||
id: header
|
id: header
|
||||||
iconSource: "../../../icons/goto-i.svg"
|
iconSource: "../../../icons/goto-i.svg"
|
||||||
|
|
|
@ -58,6 +58,10 @@ Item {
|
||||||
width: parent ? parent.width : 0
|
width: parent ? parent.width : 0
|
||||||
height: parent ? parent.height : 0
|
height: parent ? parent.height : 0
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
gradient: Gradient {
|
gradient: Gradient {
|
||||||
GradientStop { position: 0.0; color: android.color.gradientTop }
|
GradientStop { position: 0.0; color: android.color.gradientTop }
|
||||||
GradientStop { position: 1.0; color: android.color.gradientBottom }
|
GradientStop { position: 1.0; color: android.color.gradientBottom }
|
||||||
|
|
|
@ -118,7 +118,7 @@ Item {
|
||||||
tabletRoot.playButtonClickSound();
|
tabletRoot.playButtonClickSound();
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
onEntered: {
|
onPressed: {
|
||||||
button.isEntered = true;
|
button.isEntered = true;
|
||||||
button.entered();
|
button.entered();
|
||||||
if (button.isActive) {
|
if (button.isActive) {
|
||||||
|
@ -127,7 +127,7 @@ Item {
|
||||||
button.state = "hover state";
|
button.state = "hover state";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onExited: {
|
onReleased: {
|
||||||
button.isEntered = false;
|
button.isEntered = false;
|
||||||
button.exited()
|
button.exited()
|
||||||
if (button.isActive) {
|
if (button.isActive) {
|
||||||
|
|
|
@ -71,6 +71,14 @@ Rectangle {
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
newModelDialog.keyboardEnabled = false;
|
newModelDialog.keyboardEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onTextChanged : {
|
||||||
|
if (modelURL.text.length === 0){
|
||||||
|
button1.enabled = false;
|
||||||
|
} else {
|
||||||
|
button1.enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -200,6 +208,7 @@ Rectangle {
|
||||||
id: button1
|
id: button1
|
||||||
text: qsTr("Add")
|
text: qsTr("Add")
|
||||||
z: -1
|
z: -1
|
||||||
|
enabled: false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
newModelDialog.sendToScript({
|
newModelDialog.sendToScript({
|
||||||
method: "newModelDialogAdd",
|
method: "newModelDialogAdd",
|
||||||
|
|
|
@ -7455,7 +7455,7 @@ DisplayPluginPointer Application::getActiveDisplayPlugin() const {
|
||||||
return _displayPlugin;
|
return _displayPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_displayPlugin) {
|
if (!_aboutToQuit && !_displayPlugin) {
|
||||||
const_cast<Application*>(this)->updateDisplayMode();
|
const_cast<Application*>(this)->updateDisplayMode();
|
||||||
Q_ASSERT(_displayPlugin);
|
Q_ASSERT(_displayPlugin);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,13 +78,17 @@ void WindowScriptingInterface::setFocus() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowScriptingInterface::raiseMainWindow() {
|
void WindowScriptingInterface::raise() {
|
||||||
// It's forbidden to call raise() from another thread.
|
// It's forbidden to call raise() from another thread.
|
||||||
qApp->postLambdaEvent([] {
|
qApp->postLambdaEvent([] {
|
||||||
qApp->raise();
|
qApp->raise();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowScriptingInterface::raiseMainWindow() {
|
||||||
|
raise();
|
||||||
|
}
|
||||||
|
|
||||||
/// Display an alert box
|
/// Display an alert box
|
||||||
/// \param const QString& message message to display
|
/// \param const QString& message message to display
|
||||||
/// \return QScriptValue::UndefinedValue
|
/// \return QScriptValue::UndefinedValue
|
||||||
|
|
|
@ -68,9 +68,16 @@ public slots:
|
||||||
*/
|
*/
|
||||||
void setFocus();
|
void setFocus();
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Raise the Interface window if it is minimized. If raised, the window gains focus.
|
||||||
|
* @function Window.raise
|
||||||
|
*/
|
||||||
|
void raise();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Raise the Interface window if it is minimized. If raised, the window gains focus.
|
* Raise the Interface window if it is minimized. If raised, the window gains focus.
|
||||||
* @function Window.raiseMainWindow
|
* @function Window.raiseMainWindow
|
||||||
|
* @deprecated Use {@link Window.raise|raise} instead.
|
||||||
*/
|
*/
|
||||||
void raiseMainWindow();
|
void raiseMainWindow();
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ Overlays::Overlays() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::cleanupAllOverlays() {
|
void Overlays::cleanupAllOverlays() {
|
||||||
|
_shuttingDown = true;
|
||||||
QMap<OverlayID, Overlay::Pointer> overlaysHUD;
|
QMap<OverlayID, Overlay::Pointer> overlaysHUD;
|
||||||
QMap<OverlayID, Overlay::Pointer> overlaysWorld;
|
QMap<OverlayID, Overlay::Pointer> overlaysWorld;
|
||||||
{
|
{
|
||||||
|
@ -147,6 +148,10 @@ void Overlays::enable() {
|
||||||
// Note, can't be invoked by scripts, but can be called by the InterfaceParentFinder
|
// Note, can't be invoked by scripts, but can be called by the InterfaceParentFinder
|
||||||
// class on packet processing threads
|
// class on packet processing threads
|
||||||
Overlay::Pointer Overlays::getOverlay(OverlayID id) const {
|
Overlay::Pointer Overlays::getOverlay(OverlayID id) const {
|
||||||
|
if (_shuttingDown) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
if (_overlaysHUD.contains(id)) {
|
if (_overlaysHUD.contains(id)) {
|
||||||
return _overlaysHUD[id];
|
return _overlaysHUD[id];
|
||||||
|
@ -157,6 +162,10 @@ Overlay::Pointer Overlays::getOverlay(OverlayID id) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties) {
|
OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties) {
|
||||||
|
if (_shuttingDown) {
|
||||||
|
return UNKNOWN_OVERLAY_ID;
|
||||||
|
}
|
||||||
|
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
OverlayID result;
|
OverlayID result;
|
||||||
PROFILE_RANGE(script, __FUNCTION__);
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
|
@ -261,6 +270,10 @@ OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) {
|
OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) {
|
||||||
|
if (_shuttingDown) {
|
||||||
|
return UNKNOWN_OVERLAY_ID;
|
||||||
|
}
|
||||||
|
|
||||||
OverlayID thisID = OverlayID(QUuid::createUuid());
|
OverlayID thisID = OverlayID(QUuid::createUuid());
|
||||||
overlay->setOverlayID(thisID);
|
overlay->setOverlayID(thisID);
|
||||||
overlay->setStackOrder(_stackOrder++);
|
overlay->setStackOrder(_stackOrder++);
|
||||||
|
@ -283,6 +296,10 @@ OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayID Overlays::cloneOverlay(OverlayID id) {
|
OverlayID Overlays::cloneOverlay(OverlayID id) {
|
||||||
|
if (_shuttingDown) {
|
||||||
|
return UNKNOWN_OVERLAY_ID;
|
||||||
|
}
|
||||||
|
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
OverlayID result;
|
OverlayID result;
|
||||||
PROFILE_RANGE(script, __FUNCTION__);
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
|
@ -301,6 +318,10 @@ OverlayID Overlays::cloneOverlay(OverlayID id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Overlays::editOverlay(OverlayID id, const QVariant& properties) {
|
bool Overlays::editOverlay(OverlayID id, const QVariant& properties) {
|
||||||
|
if (_shuttingDown) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto thisOverlay = getOverlay(id);
|
auto thisOverlay = getOverlay(id);
|
||||||
if (!thisOverlay) {
|
if (!thisOverlay) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -320,6 +341,10 @@ bool Overlays::editOverlay(OverlayID id, const QVariant& properties) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Overlays::editOverlays(const QVariant& propertiesById) {
|
bool Overlays::editOverlays(const QVariant& propertiesById) {
|
||||||
|
if (_shuttingDown) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool defer2DOverlays = QThread::currentThread() != thread();
|
bool defer2DOverlays = QThread::currentThread() != thread();
|
||||||
|
|
||||||
QVariantMap deferrred;
|
QVariantMap deferrred;
|
||||||
|
@ -351,6 +376,10 @@ bool Overlays::editOverlays(const QVariant& propertiesById) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::deleteOverlay(OverlayID id) {
|
void Overlays::deleteOverlay(OverlayID id) {
|
||||||
|
if (_shuttingDown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QMetaObject::invokeMethod(this, "deleteOverlay", Q_ARG(OverlayID, id));
|
QMetaObject::invokeMethod(this, "deleteOverlay", Q_ARG(OverlayID, id));
|
||||||
return;
|
return;
|
||||||
|
@ -374,6 +403,9 @@ void Overlays::deleteOverlay(OverlayID id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Overlays::getOverlayType(OverlayID overlayId) {
|
QString Overlays::getOverlayType(OverlayID overlayId) {
|
||||||
|
if (_shuttingDown) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QString result;
|
QString result;
|
||||||
PROFILE_RANGE(script, __FUNCTION__);
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
|
@ -388,8 +420,23 @@ QString Overlays::getOverlayType(OverlayID overlayId) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QObject* Overlays::getOverlayObject(OverlayID id) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
QObject* result;
|
||||||
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
|
BLOCKING_INVOKE_METHOD(this, "getOverlayObject", Q_RETURN_ARG(QObject*, result), Q_ARG(OverlayID, id));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||||
|
if (thisOverlay) {
|
||||||
|
return qobject_cast<QObject*>(&(*thisOverlay));
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
OverlayID Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
OverlayID Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
||||||
if (!_enabled) {
|
if (_shuttingDown || !_enabled) {
|
||||||
return UNKNOWN_OVERLAY_ID;
|
return UNKNOWN_OVERLAY_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -235,6 +235,50 @@ public slots:
|
||||||
*/
|
*/
|
||||||
QString getOverlayType(OverlayID overlayId);
|
QString getOverlayType(OverlayID overlayId);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Get the overlay script object. In particular, this is useful for accessing the event bridge for a <code>web3d</code>
|
||||||
|
* overlay.
|
||||||
|
* @function Overlays.getOverlayObject
|
||||||
|
* @param {Uuid} overlayID - The ID of the overlay to get the script object of.
|
||||||
|
* @returns {object} The script object for the overlay if found.
|
||||||
|
* @example <caption>Receive "hello" messages from a <code>web3d</code> overlay.</caption>
|
||||||
|
* // HTML file: name "web3d.html".
|
||||||
|
* <!DOCTYPE html>
|
||||||
|
* <html>
|
||||||
|
* <head>
|
||||||
|
* <title>HELLO</title>
|
||||||
|
* </head>
|
||||||
|
* <body>
|
||||||
|
* <h1>HELLO</h1></h1>
|
||||||
|
* <script>
|
||||||
|
* setInterval(function () {
|
||||||
|
* EventBridge.emitWebEvent("hello");
|
||||||
|
* }, 2000);
|
||||||
|
* </script>
|
||||||
|
* </body>
|
||||||
|
* </html>
|
||||||
|
*
|
||||||
|
* // Script file.
|
||||||
|
* var web3dOverlay = Overlays.addOverlay("web3d", {
|
||||||
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, {x: 0, y: 0.5, z: -3 })),
|
||||||
|
* rotation: MyAvatar.orientation,
|
||||||
|
* url: Script.resolvePath("web3d.html"),
|
||||||
|
* alpha: 1.0
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* function onWebEventReceived(event) {
|
||||||
|
* print("onWebEventReceived() : " + JSON.stringify(event));
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* overlayObject = Overlays.getOverlayObject(web3dOverlay);
|
||||||
|
* overlayObject.webEventReceived.connect(onWebEventReceived);
|
||||||
|
*
|
||||||
|
* Script.scriptEnding.connect(function () {
|
||||||
|
* Overlays.deleteOverlay(web3dOverlay);
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
QObject* getOverlayObject(OverlayID id);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Get the ID of the 2D overlay at a particular point on the screen or HUD.
|
* Get the ID of the 2D overlay at a particular point on the screen or HUD.
|
||||||
* @function Overlays.getOverlayAtPoint
|
* @function Overlays.getOverlayAtPoint
|
||||||
|
@ -680,6 +724,7 @@ private:
|
||||||
unsigned int _stackOrder { 1 };
|
unsigned int _stackOrder { 1 };
|
||||||
|
|
||||||
bool _enabled = true;
|
bool _enabled = true;
|
||||||
|
std::atomic<bool> _shuttingDown{ false };
|
||||||
|
|
||||||
PointerEvent calculateOverlayPointerEvent(OverlayID overlayID, PickRay ray, RayToOverlayIntersectionResult rayPickResult,
|
PointerEvent calculateOverlayPointerEvent(OverlayID overlayID, PickRay ray, RayToOverlayIntersectionResult rayPickResult,
|
||||||
QMouseEvent* event, PointerEvent::EventType eventType);
|
QMouseEvent* event, PointerEvent::EventType eventType);
|
||||||
|
|
|
@ -39,18 +39,20 @@ void QmlOverlay::buildQmlElement(const QUrl& url) {
|
||||||
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
offscreenUi->load(url, [=](QQmlContext* context, QObject* object) {
|
offscreenUi->load(url, [=](QQmlContext* context, QObject* object) {
|
||||||
QQuickItem* rawPtr = dynamic_cast<QQuickItem*>(object);
|
_qmlElement = dynamic_cast<QQuickItem*>(object);
|
||||||
// Create a shared ptr with a custom deleter lambda, that calls deleteLater
|
connect(_qmlElement, &QObject::destroyed, this, &QmlOverlay::qmlElementDestroyed);
|
||||||
_qmlElement = std::shared_ptr<QQuickItem>(rawPtr, [](QQuickItem* ptr) {
|
|
||||||
if (ptr) {
|
|
||||||
ptr->deleteLater();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlOverlay::qmlElementDestroyed() {
|
||||||
|
_qmlElement = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
QmlOverlay::~QmlOverlay() {
|
QmlOverlay::~QmlOverlay() {
|
||||||
_qmlElement.reset();
|
if (_qmlElement) {
|
||||||
|
_qmlElement->deleteLater();
|
||||||
|
}
|
||||||
|
_qmlElement = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QmlOverlay replaces Overlay's properties with those defined in the QML file used but keeps Overlay2D's properties.
|
// QmlOverlay replaces Overlay's properties with those defined in the QML file used but keeps Overlay2D's properties.
|
||||||
|
@ -62,15 +64,13 @@ void QmlOverlay::setProperties(const QVariantMap& properties) {
|
||||||
|
|
||||||
Overlay2D::setProperties(properties);
|
Overlay2D::setProperties(properties);
|
||||||
auto bounds = _bounds;
|
auto bounds = _bounds;
|
||||||
std::weak_ptr<QQuickItem> weakQmlElement = _qmlElement;
|
|
||||||
// check to see if qmlElement still exists
|
// check to see if qmlElement still exists
|
||||||
auto qmlElement = weakQmlElement.lock();
|
if (_qmlElement) {
|
||||||
if (qmlElement) {
|
_qmlElement->setX(bounds.left());
|
||||||
qmlElement->setX(bounds.left());
|
_qmlElement->setY(bounds.top());
|
||||||
qmlElement->setY(bounds.top());
|
_qmlElement->setWidth(bounds.width());
|
||||||
qmlElement->setWidth(bounds.width());
|
_qmlElement->setHeight(bounds.height());
|
||||||
qmlElement->setHeight(bounds.height());
|
QMetaObject::invokeMethod(_qmlElement, "updatePropertiesFromScript", Qt::DirectConnection, Q_ARG(QVariant, properties));
|
||||||
QMetaObject::invokeMethod(qmlElement.get(), "updatePropertiesFromScript", Qt::DirectConnection, Q_ARG(QVariant, properties));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,11 @@ public:
|
||||||
void render(RenderArgs* args) override;
|
void render(RenderArgs* args) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Q_INVOKABLE void qmlElementDestroyed();
|
||||||
Q_INVOKABLE void buildQmlElement(const QUrl& url);
|
Q_INVOKABLE void buildQmlElement(const QUrl& url);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<QQuickItem> _qmlElement;
|
QQuickItem* _qmlElement{ nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_QmlOverlay_h
|
#endif // hifi_QmlOverlay_h
|
||||||
|
|
|
@ -166,18 +166,30 @@ bool OffscreenSurface::eventFilter(QObject* originalDestination, QEvent* event)
|
||||||
case QEvent::TouchUpdate:
|
case QEvent::TouchUpdate:
|
||||||
case QEvent::TouchEnd: {
|
case QEvent::TouchEnd: {
|
||||||
QTouchEvent *originalEvent = static_cast<QTouchEvent *>(event);
|
QTouchEvent *originalEvent = static_cast<QTouchEvent *>(event);
|
||||||
QTouchEvent fakeEvent(*originalEvent);
|
QEvent::Type fakeMouseEventType = QEvent::None;
|
||||||
auto newTouchPoints = fakeEvent.touchPoints();
|
Qt::MouseButton fakeMouseButton = Qt::LeftButton;
|
||||||
for (size_t i = 0; i < newTouchPoints.size(); ++i) {
|
Qt::MouseButtons fakeMouseButtons = Qt::NoButton;
|
||||||
const auto &originalPoint = originalEvent->touchPoints()[i];
|
switch (event->type()) {
|
||||||
auto &newPoint = newTouchPoints[i];
|
case QEvent::TouchBegin:
|
||||||
newPoint.setPos(originalPoint.pos());
|
fakeMouseEventType = QEvent::MouseButtonPress;
|
||||||
|
fakeMouseButtons = Qt::LeftButton;
|
||||||
|
break;
|
||||||
|
case QEvent::TouchUpdate:
|
||||||
|
fakeMouseEventType = QEvent::MouseMove;
|
||||||
|
fakeMouseButtons = Qt::LeftButton;
|
||||||
|
break;
|
||||||
|
case QEvent::TouchEnd:
|
||||||
|
fakeMouseEventType = QEvent::MouseButtonRelease;
|
||||||
|
fakeMouseButtons = Qt::NoButton;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
fakeEvent.setTouchPoints(newTouchPoints);
|
// Same case as OffscreenUi.cpp::eventFilter: touch events are always being accepted so we now use mouse events and consider one touch, touchPoints()[0].
|
||||||
if (QCoreApplication::sendEvent(_sharedObject->getWindow(), &fakeEvent)) {
|
QMouseEvent fakeMouseEvent(fakeMouseEventType, originalEvent->touchPoints()[0].pos(), fakeMouseButton, fakeMouseButtons, Qt::NoModifier);
|
||||||
qInfo() << __FUNCTION__ << "sent fake touch event:" << fakeEvent.type()
|
fakeMouseEvent.ignore();
|
||||||
<< "_quickWindow handled it... accepted:" << fakeEvent.isAccepted();
|
if (QCoreApplication::sendEvent(_sharedObject->getWindow(), &fakeMouseEvent)) {
|
||||||
return false; //event->isAccepted();
|
/*qInfo() << __FUNCTION__ << "sent fake touch event:" << fakeMouseEvent.type()
|
||||||
|
<< "_quickWindow handled it... accepted:" << fakeMouseEvent.isAccepted();*/
|
||||||
|
return fakeMouseEvent.isAccepted();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ SharedObject::SharedObject() {
|
||||||
_quickWindow->setColor(QColor(255, 255, 255, 0));
|
_quickWindow->setColor(QColor(255, 255, 255, 0));
|
||||||
_quickWindow->setClearBeforeRendering(true);
|
_quickWindow->setClearBeforeRendering(true);
|
||||||
|
|
||||||
|
|
||||||
QObject::connect(qApp, &QCoreApplication::aboutToQuit, this, &SharedObject::onAboutToQuit);
|
QObject::connect(qApp, &QCoreApplication::aboutToQuit, this, &SharedObject::onAboutToQuit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +125,7 @@ void SharedObject::setRootItem(QQuickItem* rootItem) {
|
||||||
_renderThread->setObjectName(objectName());
|
_renderThread->setObjectName(objectName());
|
||||||
_renderThread->start();
|
_renderThread->start();
|
||||||
|
|
||||||
|
|
||||||
// Create event handler for the render thread
|
// Create event handler for the render thread
|
||||||
_renderObject = new RenderEventHandler(this, _renderThread);
|
_renderObject = new RenderEventHandler(this, _renderThread);
|
||||||
QCoreApplication::postEvent(this, new OffscreenEvent(OffscreenEvent::Initialize));
|
QCoreApplication::postEvent(this, new OffscreenEvent(OffscreenEvent::Initialize));
|
||||||
|
@ -152,9 +154,16 @@ void SharedObject::destroy() {
|
||||||
QObject::disconnect(_renderControl);
|
QObject::disconnect(_renderControl);
|
||||||
QObject::disconnect(qApp);
|
QObject::disconnect(qApp);
|
||||||
|
|
||||||
QMutexLocker lock(&_mutex);
|
{
|
||||||
_quit = true;
|
QMutexLocker lock(&_mutex);
|
||||||
QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::Quit));
|
_quit = true;
|
||||||
|
QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::Quit), Qt::HighEventPriority);
|
||||||
|
}
|
||||||
|
// Block until the rendering thread has stopped
|
||||||
|
// FIXME this is undesirable because this is blocking the main thread,
|
||||||
|
// but I haven't found a reliable way to do this only at application
|
||||||
|
// shutdown
|
||||||
|
_renderThread->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -118,9 +118,15 @@ uint32_t Item::fetchMetaSubItemBounds(ItemBounds& subItemBounds, Scene& scene) c
|
||||||
auto numSubs = fetchMetaSubItems(subItems);
|
auto numSubs = fetchMetaSubItems(subItems);
|
||||||
|
|
||||||
for (auto id : subItems) {
|
for (auto id : subItems) {
|
||||||
auto& item = scene.getItem(id);
|
// TODO: Adding an extra check here even thought we shouldn't have too.
|
||||||
if (item.exist()) {
|
// We have cases when the id returned by fetchMetaSubItems is not allocated
|
||||||
subItemBounds.emplace_back(id, item.getBound());
|
if (scene.isAllocatedID(id)) {
|
||||||
|
auto& item = scene.getItem(id);
|
||||||
|
if (item.exist()) {
|
||||||
|
subItemBounds.emplace_back(id, item.getBound());
|
||||||
|
} else {
|
||||||
|
numSubs--;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
numSubs--;
|
numSubs--;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,14 @@ var RADIUS_RATE = 1.0 / 100.0;
|
||||||
var PAN_RATE = 250.0;
|
var PAN_RATE = 250.0;
|
||||||
|
|
||||||
var Y_AXIS = {
|
var Y_AXIS = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 1,
|
y: 1,
|
||||||
z: 0
|
z: 0
|
||||||
};
|
};
|
||||||
var X_AXIS = {
|
var X_AXIS = {
|
||||||
x: 1,
|
x: 1,
|
||||||
y: 0,
|
y: 0,
|
||||||
z: 0
|
z: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
var LOOK_AT_TIME = 500;
|
var LOOK_AT_TIME = 500;
|
||||||
|
@ -56,21 +56,20 @@ var mode = noMode;
|
||||||
var mouseLastX = 0;
|
var mouseLastX = 0;
|
||||||
var mouseLastY = 0;
|
var mouseLastY = 0;
|
||||||
|
|
||||||
|
|
||||||
var center = {
|
var center = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
z: 0
|
z: 0
|
||||||
};
|
};
|
||||||
var position = {
|
var position = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
z: 0
|
z: 0
|
||||||
};
|
};
|
||||||
var vector = {
|
var vector = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
z: 0
|
z: 0
|
||||||
};
|
};
|
||||||
var radius = 0.0;
|
var radius = 0.0;
|
||||||
var azimuth = 0.0;
|
var azimuth = 0.0;
|
||||||
|
@ -83,258 +82,248 @@ var rotatingTowardsTarget = false;
|
||||||
var targetCamOrientation;
|
var targetCamOrientation;
|
||||||
var oldPosition, oldOrientation;
|
var oldPosition, oldOrientation;
|
||||||
|
|
||||||
|
|
||||||
function orientationOf(vector) {
|
function orientationOf(vector) {
|
||||||
var direction,
|
var direction,
|
||||||
yaw,
|
yaw,
|
||||||
pitch;
|
pitch;
|
||||||
|
|
||||||
direction = Vec3.normalize(vector);
|
direction = Vec3.normalize(vector);
|
||||||
yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS);
|
yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS);
|
||||||
pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS);
|
pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS);
|
||||||
return Quat.multiply(yaw, pitch);
|
return Quat.multiply(yaw, pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleRadialMode(dx, dy) {
|
function handleRadialMode(dx, dy) {
|
||||||
azimuth += dx / AZIMUTH_RATE;
|
azimuth += dx / AZIMUTH_RATE;
|
||||||
radius += radius * dy * RADIUS_RATE;
|
radius += radius * dy * RADIUS_RATE;
|
||||||
if (radius < 1) {
|
if (radius < 1) {
|
||||||
radius = 1;
|
radius = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector = {
|
vector = {
|
||||||
x: (Math.cos(altitude) * Math.cos(azimuth)) * radius,
|
x: (Math.cos(altitude) * Math.cos(azimuth)) * radius,
|
||||||
y: Math.sin(altitude) * radius,
|
y: Math.sin(altitude) * radius,
|
||||||
z: (Math.cos(altitude) * Math.sin(azimuth)) * radius
|
z: (Math.cos(altitude) * Math.sin(azimuth)) * radius
|
||||||
};
|
};
|
||||||
position = Vec3.sum(center, vector);
|
position = Vec3.sum(center, vector);
|
||||||
Camera.setPosition(position);
|
Camera.setPosition(position);
|
||||||
Camera.setOrientation(orientationOf(vector));
|
Camera.setOrientation(orientationOf(vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleOrbitMode(dx, dy) {
|
function handleOrbitMode(dx, dy) {
|
||||||
azimuth += dx / AZIMUTH_RATE;
|
azimuth += dx / AZIMUTH_RATE;
|
||||||
altitude += dy / ALTITUDE_RATE;
|
altitude += dy / ALTITUDE_RATE;
|
||||||
if (altitude > PI / 2.0) {
|
if (altitude > PI / 2.0) {
|
||||||
altitude = PI / 2.0;
|
altitude = PI / 2.0;
|
||||||
}
|
}
|
||||||
if (altitude < -PI / 2.0) {
|
if (altitude < -PI / 2.0) {
|
||||||
altitude = -PI / 2.0;
|
altitude = -PI / 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector = {
|
vector = {
|
||||||
x: (Math.cos(altitude) * Math.cos(azimuth)) * radius,
|
x: (Math.cos(altitude) * Math.cos(azimuth)) * radius,
|
||||||
y: Math.sin(altitude) * radius,
|
y: Math.sin(altitude) * radius,
|
||||||
z: (Math.cos(altitude) * Math.sin(azimuth)) * radius
|
z: (Math.cos(altitude) * Math.sin(azimuth)) * radius
|
||||||
};
|
};
|
||||||
position = Vec3.sum(center, vector);
|
position = Vec3.sum(center, vector);
|
||||||
Camera.setPosition(position);
|
Camera.setPosition(position);
|
||||||
Camera.setOrientation(orientationOf(vector));
|
Camera.setOrientation(orientationOf(vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handlePanMode(dx, dy) {
|
function handlePanMode(dx, dy) {
|
||||||
var up = Quat.getUp(Camera.getOrientation());
|
var up = Quat.getUp(Camera.getOrientation());
|
||||||
var right = Quat.getRight(Camera.getOrientation());
|
var right = Quat.getRight(Camera.getOrientation());
|
||||||
var distance = Vec3.length(vector);
|
var distance = Vec3.length(vector);
|
||||||
|
|
||||||
var dv = Vec3.sum(Vec3.multiply(up, distance * dy / PAN_RATE), Vec3.multiply(right, -distance * dx / PAN_RATE));
|
var dv = Vec3.sum(Vec3.multiply(up, distance * dy / PAN_RATE), Vec3.multiply(right, -distance * dx / PAN_RATE));
|
||||||
|
|
||||||
center = Vec3.sum(center, dv);
|
center = Vec3.sum(center, dv);
|
||||||
position = Vec3.sum(position, dv);
|
position = Vec3.sum(position, dv);
|
||||||
|
|
||||||
Camera.setPosition(position);
|
Camera.setPosition(position);
|
||||||
Camera.setOrientation(orientationOf(vector));
|
Camera.setOrientation(orientationOf(vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveCameraState() {
|
function saveCameraState() {
|
||||||
oldMode = Camera.mode;
|
oldMode = Camera.mode;
|
||||||
oldPosition = Camera.getPosition();
|
oldPosition = Camera.getPosition();
|
||||||
oldOrientation = Camera.getOrientation();
|
oldOrientation = Camera.getOrientation();
|
||||||
|
|
||||||
Camera.mode = "independent";
|
Camera.mode = "independent";
|
||||||
Camera.setPosition(oldPosition);
|
Camera.setPosition(oldPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreCameraState() {
|
function restoreCameraState() {
|
||||||
Camera.mode = oldMode;
|
Camera.mode = oldMode;
|
||||||
Camera.setPosition(oldPosition);
|
Camera.setPosition(oldPosition);
|
||||||
Camera.setOrientation(oldOrientation);
|
Camera.setOrientation(oldOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleModes() {
|
function handleModes() {
|
||||||
var newMode = (mode == noMode) ? noMode : detachedMode;
|
var newMode = (mode == noMode) ? noMode : detachedMode;
|
||||||
if (alt) {
|
if (alt) {
|
||||||
if (control) {
|
if (control) {
|
||||||
if (shift) {
|
if (shift) {
|
||||||
newMode = panningMode;
|
newMode = panningMode;
|
||||||
} else {
|
} else {
|
||||||
newMode = orbitMode;
|
newMode = orbitMode;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newMode = radialMode;
|
newMode = radialMode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// if entering detachMode
|
// if entering detachMode
|
||||||
if (newMode == detachedMode && mode != detachedMode) {
|
if (newMode == detachedMode && mode != detachedMode) {
|
||||||
avatarPosition = MyAvatar.position;
|
avatarPosition = MyAvatar.position;
|
||||||
avatarOrientation = MyAvatar.orientation;
|
avatarOrientation = MyAvatar.orientation;
|
||||||
}
|
}
|
||||||
// if leaving detachMode
|
// if leaving detachMode
|
||||||
if (mode == detachedMode && newMode == detachedMode &&
|
if (mode == detachedMode && newMode == detachedMode &&
|
||||||
(avatarPosition.x != MyAvatar.position.x ||
|
(avatarPosition.x != MyAvatar.position.x ||
|
||||||
avatarPosition.y != MyAvatar.position.y ||
|
avatarPosition.y != MyAvatar.position.y ||
|
||||||
avatarPosition.z != MyAvatar.position.z ||
|
avatarPosition.z != MyAvatar.position.z ||
|
||||||
avatarOrientation.x != MyAvatar.orientation.x ||
|
avatarOrientation.x != MyAvatar.orientation.x ||
|
||||||
avatarOrientation.y != MyAvatar.orientation.y ||
|
avatarOrientation.y != MyAvatar.orientation.y ||
|
||||||
avatarOrientation.z != MyAvatar.orientation.z ||
|
avatarOrientation.z != MyAvatar.orientation.z ||
|
||||||
avatarOrientation.w != MyAvatar.orientation.w)) {
|
avatarOrientation.w != MyAvatar.orientation.w)) {
|
||||||
newMode = noMode;
|
newMode = noMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == noMode && newMode != noMode && Camera.mode == "independent") {
|
if (mode == noMode && newMode != noMode && Camera.mode == "independent") {
|
||||||
newMode = noMode;
|
newMode = noMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if leaving noMode
|
// if leaving noMode
|
||||||
if (mode == noMode && newMode != noMode) {
|
if (mode == noMode && newMode != noMode) {
|
||||||
saveCameraState();
|
saveCameraState();
|
||||||
}
|
}
|
||||||
// if entering noMode
|
// if entering noMode
|
||||||
if (newMode == noMode && mode != noMode) {
|
if (newMode == noMode && mode != noMode) {
|
||||||
restoreCameraState();
|
restoreCameraState();
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = newMode;
|
mode = newMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
function keyPressEvent(event) {
|
function keyPressEvent(event) {
|
||||||
var changed = false;
|
var changed = false;
|
||||||
|
|
||||||
if (event.text == "ALT") {
|
if (event.text == "ALT") {
|
||||||
alt = true;
|
alt = true;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (event.text == "CONTROL") {
|
if (event.text == "CONTROL") {
|
||||||
control = true;
|
control = true;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (event.text == "SHIFT") {
|
if (event.text == "SHIFT") {
|
||||||
shift = true;
|
shift = true;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
handleModes();
|
handleModes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function keyReleaseEvent(event) {
|
function keyReleaseEvent(event) {
|
||||||
var changed = false;
|
var changed = false;
|
||||||
|
|
||||||
if (event.text == "ALT") {
|
if (event.text == "ALT") {
|
||||||
alt = false;
|
alt = false;
|
||||||
changed = true;
|
changed = true;
|
||||||
mode = noMode;
|
mode = noMode;
|
||||||
restoreCameraState();
|
restoreCameraState();
|
||||||
}
|
}
|
||||||
if (event.text == "CONTROL") {
|
if (event.text == "CONTROL") {
|
||||||
control = false;
|
control = false;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (event.text == "SHIFT") {
|
if (event.text == "SHIFT") {
|
||||||
shift = false;
|
shift = false;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
handleModes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function mousePressEvent(event) {
|
|
||||||
if (alt && !isActive) {
|
|
||||||
mouseLastX = event.x;
|
|
||||||
mouseLastY = event.y;
|
|
||||||
|
|
||||||
// Compute trajectories related values
|
|
||||||
var pickRay = Camera.computePickRay(mouseLastX, mouseLastY);
|
|
||||||
var modelIntersection = Entities.findRayIntersection(pickRay, true);
|
|
||||||
|
|
||||||
position = Camera.getPosition();
|
|
||||||
|
|
||||||
var avatarTarget = MyAvatar.getTargetAvatarPosition();
|
|
||||||
|
|
||||||
|
|
||||||
var distance = -1;
|
|
||||||
var string;
|
|
||||||
|
|
||||||
if (modelIntersection.intersects && modelIntersection.accurate) {
|
|
||||||
distance = modelIntersection.distance;
|
|
||||||
center = modelIntersection.intersection;
|
|
||||||
string = "Inspecting model";
|
|
||||||
//We've selected our target, now orbit towards it automatically
|
|
||||||
rotatingTowardsTarget = true;
|
|
||||||
//calculate our target cam rotation
|
|
||||||
Script.setTimeout(function() {
|
|
||||||
rotatingTowardsTarget = false;
|
|
||||||
}, LOOK_AT_TIME);
|
|
||||||
|
|
||||||
vector = Vec3.subtract(position, center);
|
|
||||||
targetCamOrientation = orientationOf(vector);
|
|
||||||
radius = Vec3.length(vector);
|
|
||||||
azimuth = Math.atan2(vector.z, vector.x);
|
|
||||||
altitude = Math.asin(vector.y / Vec3.length(vector));
|
|
||||||
|
|
||||||
isActive = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
if (changed) {
|
||||||
|
handleModes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousePressEvent(event) {
|
||||||
|
if (alt && !isActive) {
|
||||||
|
mouseLastX = event.x;
|
||||||
|
mouseLastY = event.y;
|
||||||
|
|
||||||
|
// Compute trajectories related values
|
||||||
|
var pickRay = Camera.computePickRay(mouseLastX, mouseLastY);
|
||||||
|
var modelIntersection = Entities.findRayIntersection(pickRay, true);
|
||||||
|
var avatarIntersection = AvatarList.findRayIntersection(pickRay);
|
||||||
|
|
||||||
|
position = Camera.getPosition();
|
||||||
|
|
||||||
|
if (avatarIntersection.intersects || (modelIntersection.intersects && modelIntersection.accurate)) {
|
||||||
|
if (avatarIntersection.intersects) {
|
||||||
|
center = avatarIntersection.intersection;
|
||||||
|
} else {
|
||||||
|
center = modelIntersection.intersection;
|
||||||
|
}
|
||||||
|
// We've selected our target, now orbit towards it automatically
|
||||||
|
rotatingTowardsTarget = true;
|
||||||
|
// calculate our target cam rotation
|
||||||
|
Script.setTimeout(function () {
|
||||||
|
rotatingTowardsTarget = false;
|
||||||
|
}, LOOK_AT_TIME);
|
||||||
|
|
||||||
|
vector = Vec3.subtract(position, center);
|
||||||
|
targetCamOrientation = orientationOf(vector);
|
||||||
|
radius = Vec3.length(vector);
|
||||||
|
azimuth = Math.atan2(vector.z, vector.x);
|
||||||
|
altitude = Math.asin(vector.y / Vec3.length(vector));
|
||||||
|
|
||||||
|
isActive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mouseReleaseEvent(event) {
|
function mouseReleaseEvent(event) {
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
isActive = false;
|
isActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mouseMoveEvent(event) {
|
function mouseMoveEvent(event) {
|
||||||
if (isActive && mode != noMode && !rotatingTowardsTarget) {
|
if (isActive && mode != noMode && !rotatingTowardsTarget) {
|
||||||
if (mode == radialMode) {
|
if (mode == radialMode) {
|
||||||
handleRadialMode(event.x - mouseLastX, event.y - mouseLastY);
|
handleRadialMode(event.x - mouseLastX, event.y - mouseLastY);
|
||||||
|
}
|
||||||
|
if (mode == orbitMode) {
|
||||||
|
handleOrbitMode(event.x - mouseLastX, event.y - mouseLastY);
|
||||||
|
}
|
||||||
|
if (mode == panningMode) {
|
||||||
|
handlePanMode(event.x - mouseLastX, event.y - mouseLastY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (mode == orbitMode) {
|
mouseLastX = event.x;
|
||||||
handleOrbitMode(event.x - mouseLastX, event.y - mouseLastY);
|
mouseLastY = event.y;
|
||||||
}
|
|
||||||
if (mode == panningMode) {
|
|
||||||
handlePanMode(event.x - mouseLastX, event.y - mouseLastY);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
mouseLastX = event.x;
|
|
||||||
mouseLastY = event.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
handleModes();
|
handleModes();
|
||||||
if (rotatingTowardsTarget) {
|
if (rotatingTowardsTarget) {
|
||||||
rotateTowardsTarget();
|
rotateTowardsTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function rotateTowardsTarget() {
|
function rotateTowardsTarget() {
|
||||||
var newOrientation = Quat.mix(Camera.getOrientation(), targetCamOrientation, .1);
|
var newOrientation = Quat.mix(Camera.getOrientation(), targetCamOrientation, 0.1);
|
||||||
Camera.setOrientation(newOrientation);
|
Camera.setOrientation(newOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
function scriptEnding() {
|
function scriptEnding() {
|
||||||
if (mode != noMode) {
|
if (mode != noMode) {
|
||||||
restoreCameraState();
|
restoreCameraState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.keyPressEvent.connect(keyPressEvent);
|
Controller.keyPressEvent.connect(keyPressEvent);
|
||||||
|
@ -345,4 +334,4 @@ Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||||
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||||
|
|
||||||
Script.update.connect(update);
|
Script.update.connect(update);
|
||||||
Script.scriptEnding.connect(scriptEnding);
|
Script.scriptEnding.connect(scriptEnding);
|
||||||
|
|
|
@ -46,7 +46,6 @@ function onMuteClicked() {
|
||||||
printd("On Mute Clicked");
|
printd("On Mute Clicked");
|
||||||
//Menu.setIsOptionChecked("Mute Microphone", !Menu.isOptionChecked("Mute Microphone"));
|
//Menu.setIsOptionChecked("Mute Microphone", !Menu.isOptionChecked("Mute Microphone"));
|
||||||
Audio.muted = !Audio.muted;
|
Audio.muted = !Audio.muted;
|
||||||
onMuteToggled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMuteToggled() {
|
function onMuteToggled() {
|
||||||
|
|
|
@ -35,6 +35,7 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
||||||
break;
|
break;
|
||||||
case 'hide':
|
case 'hide':
|
||||||
Controller.setVPadHidden(false);
|
Controller.setVPadHidden(false);
|
||||||
|
module.exports.hide();
|
||||||
module.exports.onHidden();
|
module.exports.onHidden();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -33,7 +33,6 @@ function init() {
|
||||||
radar.setUniqueColor(uniqueColor);
|
radar.setUniqueColor(uniqueColor);
|
||||||
radar.init();
|
radar.init();
|
||||||
setupModesBar();
|
setupModesBar();
|
||||||
radar.isTouchValid = isRadarModeValidTouch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function shutdown() {
|
function shutdown() {
|
||||||
|
@ -183,34 +182,6 @@ function onButtonClicked(clickedButton, whatToDo, hideAllAfter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isRadarModeValidTouch(coords) {
|
|
||||||
var qmlFragments = [modesbar.qmlFragment];
|
|
||||||
var windows = [];
|
|
||||||
for (var i=0; i < qmlFragments.length; i++) {
|
|
||||||
var aQmlFrag = qmlFragments[i];
|
|
||||||
if (aQmlFrag != null && aQmlFrag.isVisible() &&
|
|
||||||
coords.x >= aQmlFrag.position.x * 3 && coords.x <= aQmlFrag.position.x * 3 + aQmlFrag.size.x * 3 &&
|
|
||||||
coords.y >= aQmlFrag.position.y * 3 && coords.y <= aQmlFrag.position.y * 3 + aQmlFrag.size.y * 3
|
|
||||||
) {
|
|
||||||
printd("godViewModeTouchValid- false because of qmlFragments!? idx " + i);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i=0; i < windows.length; i++) {
|
|
||||||
var aWin = windows[i];
|
|
||||||
if (aWin != null && aWin.position() != null &&
|
|
||||||
coords.x >= aWin.position().x * 3 && coords.x <= aWin.position().x * 3 + aWin.width() * 3 &&
|
|
||||||
coords.y >= aWin.position().y * 3 && coords.y <= aWin.position().y * 3 + aWin.height() * 3
|
|
||||||
) {
|
|
||||||
printd("godViewModeTouchValid- false because of windows!?");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printd("godViewModeTouchValid- true by default ");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Script.scriptEnding.connect(function () {
|
Script.scriptEnding.connect(function () {
|
||||||
shutdown();
|
shutdown();
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
var radarModeInterface = {};
|
var radarModeInterface = {};
|
||||||
|
|
||||||
var logEnabled = true;
|
var logEnabled = false;
|
||||||
function printd(str) {
|
function printd(str) {
|
||||||
if (logEnabled) {
|
if (logEnabled) {
|
||||||
print("[radar.js] " + str);
|
print("[radar.js] " + str);
|
||||||
|
@ -118,19 +118,10 @@ function actionOnObjectFromEvent(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function mousePress(event) {
|
function mousePress(event) {
|
||||||
if (!isTouchValid(coords)) {
|
|
||||||
currentTouchIsValid = false;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
currentTouchIsValid = true;
|
|
||||||
}
|
|
||||||
mousePressOrTouchEnd(event);
|
mousePressOrTouchEnd(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mousePressOrTouchEnd(event) {
|
function mousePressOrTouchEnd(event) {
|
||||||
if (!currentTouchIsValid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (radar) {
|
if (radar) {
|
||||||
if (actionOnObjectFromEvent(event)) {
|
if (actionOnObjectFromEvent(event)) {
|
||||||
return;
|
return;
|
||||||
|
@ -155,9 +146,6 @@ function fakeDoubleTap(event) {
|
||||||
teleporter.dragTeleportRelease(event);
|
teleporter.dragTeleportRelease(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentTouchIsValid = false; // Currently used to know if touch hasn't
|
|
||||||
// started on a UI overlay
|
|
||||||
|
|
||||||
var DOUBLE_TAP_TIME = 300;
|
var DOUBLE_TAP_TIME = 300;
|
||||||
var fakeDoubleTapStart = Date.now();
|
var fakeDoubleTapStart = Date.now();
|
||||||
var touchEndCount = 0;
|
var touchEndCount = 0;
|
||||||
|
@ -238,12 +226,6 @@ function touchEnd(event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if touch is invalid, cancel
|
|
||||||
if (!currentTouchIsValid) {
|
|
||||||
printd("touchEnd fail because !currentTouchIsValid");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (analyzeDoubleTap(event))
|
if (analyzeDoubleTap(event))
|
||||||
return; // double tap detected, finish
|
return; // double tap detected, finish
|
||||||
|
|
||||||
|
@ -345,20 +327,6 @@ function computePointAtPlaneY(x, y, py) {
|
||||||
p2.z, py);
|
p2.z, py);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
function isTouchValid(coords) {
|
|
||||||
// TODO: Extend to the detection of touches on new menu bars
|
|
||||||
var radarModeTouchValid = radarModeInterface.isTouchValid(coords);
|
|
||||||
|
|
||||||
// getItemAtPoint does not exist anymore, look for another way to know if we
|
|
||||||
// are touching buttons
|
|
||||||
// is it still needed?
|
|
||||||
return /* !tablet.getItemAtPoint(coords) && */radarModeTouchValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -373,16 +341,8 @@ function touchBegin(event) {
|
||||||
x : event.x,
|
x : event.x,
|
||||||
y : event.y
|
y : event.y
|
||||||
};
|
};
|
||||||
if (!isTouchValid(coords)) {
|
touchStartingCoordinates = coords;
|
||||||
printd("analyze touch - RADAR_TOUCH - INVALID");
|
touchBeginTime = Date.now();
|
||||||
currentTouchIsValid = false;
|
|
||||||
touchStartingCoordinates = null;
|
|
||||||
} else {
|
|
||||||
printd("analyze touch - RADAR_TOUCH - ok");
|
|
||||||
currentTouchIsValid = true;
|
|
||||||
touchStartingCoordinates = coords;
|
|
||||||
touchBeginTime = Date.now();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var startedDraggingCamera = false; // first time
|
var startedDraggingCamera = false; // first time
|
||||||
|
@ -848,9 +808,6 @@ function oneFingerTouchUpdate(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function touchUpdate(event) {
|
function touchUpdate(event) {
|
||||||
if (!currentTouchIsValid) {
|
|
||||||
return; // avoid moving and zooming when tap is over UI entities
|
|
||||||
}
|
|
||||||
if (event.isPinching || event.isPinchOpening) {
|
if (event.isPinching || event.isPinchOpening) {
|
||||||
pinchUpdate(event);
|
pinchUpdate(event);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -307,6 +307,10 @@ WebTablet.prototype.setScriptURL = function (scriptURL) {
|
||||||
Overlays.editOverlay(this.webOverlayID, { scriptURL: scriptURL });
|
Overlays.editOverlay(this.webOverlayID, { scriptURL: scriptURL });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
WebTablet.prototype.getOverlayObject = function () {
|
||||||
|
return Overlays.getOverlayObject(this.webOverlayID);
|
||||||
|
};
|
||||||
|
|
||||||
WebTablet.prototype.setWidth = function (width) {
|
WebTablet.prototype.setWidth = function (width) {
|
||||||
// imported from libraries/utils.js
|
// imported from libraries/utils.js
|
||||||
resizeTablet(width);
|
resizeTablet(width);
|
||||||
|
|
Loading…
Reference in a new issue