Merge branch 'master' of github.com:highfidelity/hifi into newUpdateCertLocation

This commit is contained in:
Zach Fox 2018-03-30 10:10:43 -07:00
commit 32e5e9986f
21 changed files with 405 additions and 335 deletions

View file

@ -312,7 +312,7 @@ if (APPLE)
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")
# copy script files beside the executable
@ -326,13 +326,14 @@ if (APPLE)
fixup_interface()
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
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${RESOURCES_RCC}"
"$<TARGET_FILE_DIR:interface>"
"${INTERFACE_EXEC_DIR}"
# FIXME, the edit script code loads HTML from the scripts folder
# 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
@ -340,13 +341,13 @@ else()
# so we have to retain a copy of the fonts outside of the resources binary
COMMAND "${CMAKE_COMMAND}" -E copy_directory
"${PROJECT_SOURCE_DIR}/resources/fonts"
"$<TARGET_FILE_DIR:${TARGET_NAME}>/resources/fonts"
"${RESOURCES_DEV_DIR}/fonts"
COMMAND "${CMAKE_COMMAND}" -E copy_directory
"${CMAKE_SOURCE_DIR}/scripts"
"${RESOURCES_DEV_DIR}/scripts"
"${INTERFACE_EXEC_DIR}/scripts"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${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
@ -363,7 +364,7 @@ else()
PATTERN "*.exp" EXCLUDE
)
set(RESOURCES_INSTALL_DIR "${INTERFACE_INSTALL_DIR}")
set(SCRIPTS_INSTALL_DIR "${INTERFACE_INSTALL_DIR}")
set(EXECUTABLE_COMPONENT ${CLIENT_COMPONENT})
@ -371,11 +372,11 @@ else()
endif()
endif()
if (RESOURCES_INSTALL_DIR)
if (SCRIPTS_INSTALL_DIR)
# setup install of scripts beside interface executable
install(
DIRECTORY "${CMAKE_SOURCE_DIR}/scripts/"
DESTINATION ${RESOURCES_INSTALL_DIR}/scripts
DESTINATION ${SCRIPTS_INSTALL_DIR}/scripts
COMPONENT ${CLIENT_COMPONENT}
)
endif()

View file

@ -67,6 +67,10 @@ Item {
fill: parent
}
MouseArea {
anchors.fill: parent
}
QmlHifi.WindowHeader {
id: header
iconSource: "../../../icons/goto-i.svg"

View file

@ -58,6 +58,10 @@ Item {
width: parent ? parent.width : 0
height: parent ? parent.height : 0
MouseArea {
anchors.fill: parent
}
gradient: Gradient {
GradientStop { position: 0.0; color: android.color.gradientTop }
GradientStop { position: 1.0; color: android.color.gradientBottom }

View file

@ -118,7 +118,7 @@ Item {
tabletRoot.playButtonClickSound();
}*/
}
onEntered: {
onPressed: {
button.isEntered = true;
button.entered();
if (button.isActive) {
@ -127,7 +127,7 @@ Item {
button.state = "hover state";
}
}
onExited: {
onReleased: {
button.isEntered = false;
button.exited()
if (button.isActive) {

View file

@ -71,6 +71,14 @@ Rectangle {
onAccepted: {
newModelDialog.keyboardEnabled = false;
}
onTextChanged : {
if (modelURL.text.length === 0){
button1.enabled = false;
} else {
button1.enabled = true;
}
}
MouseArea {
anchors.fill: parent
@ -200,6 +208,7 @@ Rectangle {
id: button1
text: qsTr("Add")
z: -1
enabled: false
onClicked: {
newModelDialog.sendToScript({
method: "newModelDialogAdd",

View file

@ -7455,7 +7455,7 @@ DisplayPluginPointer Application::getActiveDisplayPlugin() const {
return _displayPlugin;
}
if (!_displayPlugin) {
if (!_aboutToQuit && !_displayPlugin) {
const_cast<Application*>(this)->updateDisplayMode();
Q_ASSERT(_displayPlugin);
}

View file

@ -78,13 +78,17 @@ void WindowScriptingInterface::setFocus() {
});
}
void WindowScriptingInterface::raiseMainWindow() {
void WindowScriptingInterface::raise() {
// It's forbidden to call raise() from another thread.
qApp->postLambdaEvent([] {
qApp->raise();
});
}
void WindowScriptingInterface::raiseMainWindow() {
raise();
}
/// Display an alert box
/// \param const QString& message message to display
/// \return QScriptValue::UndefinedValue

View file

@ -68,9 +68,16 @@ public slots:
*/
void setFocus();
/**jsdoc
* Raise the Interface window if it is minimized. If raised, the window gains focus.
* @function Window.raise
*/
void raise();
/**jsdoc
* Raise the Interface window if it is minimized. If raised, the window gains focus.
* @function Window.raiseMainWindow
* @deprecated Use {@link Window.raise|raise} instead.
*/
void raiseMainWindow();

View file

@ -54,6 +54,7 @@ Overlays::Overlays() {
}
void Overlays::cleanupAllOverlays() {
_shuttingDown = true;
QMap<OverlayID, Overlay::Pointer> overlaysHUD;
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
// class on packet processing threads
Overlay::Pointer Overlays::getOverlay(OverlayID id) const {
if (_shuttingDown) {
return nullptr;
}
QMutexLocker locker(&_mutex);
if (_overlaysHUD.contains(id)) {
return _overlaysHUD[id];
@ -157,6 +162,10 @@ Overlay::Pointer Overlays::getOverlay(OverlayID id) const {
}
OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties) {
if (_shuttingDown) {
return UNKNOWN_OVERLAY_ID;
}
if (QThread::currentThread() != thread()) {
OverlayID result;
PROFILE_RANGE(script, __FUNCTION__);
@ -261,6 +270,10 @@ OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties)
}
OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) {
if (_shuttingDown) {
return UNKNOWN_OVERLAY_ID;
}
OverlayID thisID = OverlayID(QUuid::createUuid());
overlay->setOverlayID(thisID);
overlay->setStackOrder(_stackOrder++);
@ -283,6 +296,10 @@ OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) {
}
OverlayID Overlays::cloneOverlay(OverlayID id) {
if (_shuttingDown) {
return UNKNOWN_OVERLAY_ID;
}
if (QThread::currentThread() != thread()) {
OverlayID result;
PROFILE_RANGE(script, __FUNCTION__);
@ -301,6 +318,10 @@ OverlayID Overlays::cloneOverlay(OverlayID id) {
}
bool Overlays::editOverlay(OverlayID id, const QVariant& properties) {
if (_shuttingDown) {
return false;
}
auto thisOverlay = getOverlay(id);
if (!thisOverlay) {
return false;
@ -320,6 +341,10 @@ bool Overlays::editOverlay(OverlayID id, const QVariant& properties) {
}
bool Overlays::editOverlays(const QVariant& propertiesById) {
if (_shuttingDown) {
return false;
}
bool defer2DOverlays = QThread::currentThread() != thread();
QVariantMap deferrred;
@ -351,6 +376,10 @@ bool Overlays::editOverlays(const QVariant& propertiesById) {
}
void Overlays::deleteOverlay(OverlayID id) {
if (_shuttingDown) {
return;
}
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "deleteOverlay", Q_ARG(OverlayID, id));
return;
@ -374,6 +403,9 @@ void Overlays::deleteOverlay(OverlayID id) {
}
QString Overlays::getOverlayType(OverlayID overlayId) {
if (_shuttingDown) {
return "";
}
if (QThread::currentThread() != thread()) {
QString result;
PROFILE_RANGE(script, __FUNCTION__);
@ -388,8 +420,23 @@ QString Overlays::getOverlayType(OverlayID overlayId) {
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) {
if (!_enabled) {
if (_shuttingDown || !_enabled) {
return UNKNOWN_OVERLAY_ID;
}

View file

@ -235,6 +235,50 @@ public slots:
*/
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
* Get the ID of the 2D overlay at a particular point on the screen or HUD.
* @function Overlays.getOverlayAtPoint
@ -680,6 +724,7 @@ private:
unsigned int _stackOrder { 1 };
bool _enabled = true;
std::atomic<bool> _shuttingDown{ false };
PointerEvent calculateOverlayPointerEvent(OverlayID overlayID, PickRay ray, RayToOverlayIntersectionResult rayPickResult,
QMouseEvent* event, PointerEvent::EventType eventType);

View file

@ -39,18 +39,20 @@ void QmlOverlay::buildQmlElement(const QUrl& url) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->load(url, [=](QQmlContext* context, QObject* object) {
QQuickItem* rawPtr = dynamic_cast<QQuickItem*>(object);
// Create a shared ptr with a custom deleter lambda, that calls deleteLater
_qmlElement = std::shared_ptr<QQuickItem>(rawPtr, [](QQuickItem* ptr) {
if (ptr) {
ptr->deleteLater();
}
});
_qmlElement = dynamic_cast<QQuickItem*>(object);
connect(_qmlElement, &QObject::destroyed, this, &QmlOverlay::qmlElementDestroyed);
});
}
void QmlOverlay::qmlElementDestroyed() {
_qmlElement = nullptr;
}
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.
@ -62,15 +64,13 @@ void QmlOverlay::setProperties(const QVariantMap& properties) {
Overlay2D::setProperties(properties);
auto bounds = _bounds;
std::weak_ptr<QQuickItem> weakQmlElement = _qmlElement;
// check to see if qmlElement still exists
auto qmlElement = weakQmlElement.lock();
if (qmlElement) {
qmlElement->setX(bounds.left());
qmlElement->setY(bounds.top());
qmlElement->setWidth(bounds.width());
qmlElement->setHeight(bounds.height());
QMetaObject::invokeMethod(qmlElement.get(), "updatePropertiesFromScript", Qt::DirectConnection, Q_ARG(QVariant, properties));
if (_qmlElement) {
_qmlElement->setX(bounds.left());
_qmlElement->setY(bounds.top());
_qmlElement->setWidth(bounds.width());
_qmlElement->setHeight(bounds.height());
QMetaObject::invokeMethod(_qmlElement, "updatePropertiesFromScript", Qt::DirectConnection, Q_ARG(QVariant, properties));
}
}

View file

@ -32,10 +32,11 @@ public:
void render(RenderArgs* args) override;
private:
Q_INVOKABLE void qmlElementDestroyed();
Q_INVOKABLE void buildQmlElement(const QUrl& url);
protected:
std::shared_ptr<QQuickItem> _qmlElement;
QQuickItem* _qmlElement{ nullptr };
};
#endif // hifi_QmlOverlay_h

View file

@ -166,18 +166,30 @@ bool OffscreenSurface::eventFilter(QObject* originalDestination, QEvent* event)
case QEvent::TouchUpdate:
case QEvent::TouchEnd: {
QTouchEvent *originalEvent = static_cast<QTouchEvent *>(event);
QTouchEvent fakeEvent(*originalEvent);
auto newTouchPoints = fakeEvent.touchPoints();
for (size_t i = 0; i < newTouchPoints.size(); ++i) {
const auto &originalPoint = originalEvent->touchPoints()[i];
auto &newPoint = newTouchPoints[i];
newPoint.setPos(originalPoint.pos());
QEvent::Type fakeMouseEventType = QEvent::None;
Qt::MouseButton fakeMouseButton = Qt::LeftButton;
Qt::MouseButtons fakeMouseButtons = Qt::NoButton;
switch (event->type()) {
case QEvent::TouchBegin:
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);
if (QCoreApplication::sendEvent(_sharedObject->getWindow(), &fakeEvent)) {
qInfo() << __FUNCTION__ << "sent fake touch event:" << fakeEvent.type()
<< "_quickWindow handled it... accepted:" << fakeEvent.isAccepted();
return false; //event->isAccepted();
// Same case as OffscreenUi.cpp::eventFilter: touch events are always being accepted so we now use mouse events and consider one touch, touchPoints()[0].
QMouseEvent fakeMouseEvent(fakeMouseEventType, originalEvent->touchPoints()[0].pos(), fakeMouseButton, fakeMouseButtons, Qt::NoModifier);
fakeMouseEvent.ignore();
if (QCoreApplication::sendEvent(_sharedObject->getWindow(), &fakeMouseEvent)) {
/*qInfo() << __FUNCTION__ << "sent fake touch event:" << fakeMouseEvent.type()
<< "_quickWindow handled it... accepted:" << fakeMouseEvent.isAccepted();*/
return fakeMouseEvent.isAccepted();
}
break;
}

View file

@ -69,6 +69,7 @@ SharedObject::SharedObject() {
_quickWindow->setColor(QColor(255, 255, 255, 0));
_quickWindow->setClearBeforeRendering(true);
QObject::connect(qApp, &QCoreApplication::aboutToQuit, this, &SharedObject::onAboutToQuit);
}
@ -124,6 +125,7 @@ void SharedObject::setRootItem(QQuickItem* rootItem) {
_renderThread->setObjectName(objectName());
_renderThread->start();
// Create event handler for the render thread
_renderObject = new RenderEventHandler(this, _renderThread);
QCoreApplication::postEvent(this, new OffscreenEvent(OffscreenEvent::Initialize));
@ -152,9 +154,16 @@ void SharedObject::destroy() {
QObject::disconnect(_renderControl);
QObject::disconnect(qApp);
QMutexLocker lock(&_mutex);
_quit = true;
QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::Quit));
{
QMutexLocker lock(&_mutex);
_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();
}

View file

@ -118,9 +118,15 @@ uint32_t Item::fetchMetaSubItemBounds(ItemBounds& subItemBounds, Scene& scene) c
auto numSubs = fetchMetaSubItems(subItems);
for (auto id : subItems) {
auto& item = scene.getItem(id);
if (item.exist()) {
subItemBounds.emplace_back(id, item.getBound());
// TODO: Adding an extra check here even thought we shouldn't have too.
// We have cases when the id returned by fetchMetaSubItems is not allocated
if (scene.isAllocatedID(id)) {
auto& item = scene.getItem(id);
if (item.exist()) {
subItemBounds.emplace_back(id, item.getBound());
} else {
numSubs--;
}
} else {
numSubs--;
}

View file

@ -26,14 +26,14 @@ var RADIUS_RATE = 1.0 / 100.0;
var PAN_RATE = 250.0;
var Y_AXIS = {
x: 0,
y: 1,
z: 0
x: 0,
y: 1,
z: 0
};
var X_AXIS = {
x: 1,
y: 0,
z: 0
x: 1,
y: 0,
z: 0
};
var LOOK_AT_TIME = 500;
@ -56,21 +56,20 @@ var mode = noMode;
var mouseLastX = 0;
var mouseLastY = 0;
var center = {
x: 0,
y: 0,
z: 0
x: 0,
y: 0,
z: 0
};
var position = {
x: 0,
y: 0,
z: 0
x: 0,
y: 0,
z: 0
};
var vector = {
x: 0,
y: 0,
z: 0
x: 0,
y: 0,
z: 0
};
var radius = 0.0;
var azimuth = 0.0;
@ -83,258 +82,248 @@ var rotatingTowardsTarget = false;
var targetCamOrientation;
var oldPosition, oldOrientation;
function orientationOf(vector) {
var direction,
yaw,
pitch;
var direction,
yaw,
pitch;
direction = Vec3.normalize(vector);
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);
return Quat.multiply(yaw, pitch);
direction = Vec3.normalize(vector);
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);
return Quat.multiply(yaw, pitch);
}
function handleRadialMode(dx, dy) {
azimuth += dx / AZIMUTH_RATE;
radius += radius * dy * RADIUS_RATE;
if (radius < 1) {
radius = 1;
}
azimuth += dx / AZIMUTH_RATE;
radius += radius * dy * RADIUS_RATE;
if (radius < 1) {
radius = 1;
}
vector = {
x: (Math.cos(altitude) * Math.cos(azimuth)) * radius,
y: Math.sin(altitude) * radius,
z: (Math.cos(altitude) * Math.sin(azimuth)) * radius
};
position = Vec3.sum(center, vector);
Camera.setPosition(position);
Camera.setOrientation(orientationOf(vector));
vector = {
x: (Math.cos(altitude) * Math.cos(azimuth)) * radius,
y: Math.sin(altitude) * radius,
z: (Math.cos(altitude) * Math.sin(azimuth)) * radius
};
position = Vec3.sum(center, vector);
Camera.setPosition(position);
Camera.setOrientation(orientationOf(vector));
}
function handleOrbitMode(dx, dy) {
azimuth += dx / AZIMUTH_RATE;
altitude += dy / ALTITUDE_RATE;
if (altitude > PI / 2.0) {
altitude = PI / 2.0;
}
if (altitude < -PI / 2.0) {
altitude = -PI / 2.0;
}
azimuth += dx / AZIMUTH_RATE;
altitude += dy / ALTITUDE_RATE;
if (altitude > PI / 2.0) {
altitude = PI / 2.0;
}
if (altitude < -PI / 2.0) {
altitude = -PI / 2.0;
}
vector = {
x: (Math.cos(altitude) * Math.cos(azimuth)) * radius,
y: Math.sin(altitude) * radius,
z: (Math.cos(altitude) * Math.sin(azimuth)) * radius
};
position = Vec3.sum(center, vector);
Camera.setPosition(position);
Camera.setOrientation(orientationOf(vector));
vector = {
x: (Math.cos(altitude) * Math.cos(azimuth)) * radius,
y: Math.sin(altitude) * radius,
z: (Math.cos(altitude) * Math.sin(azimuth)) * radius
};
position = Vec3.sum(center, vector);
Camera.setPosition(position);
Camera.setOrientation(orientationOf(vector));
}
function handlePanMode(dx, dy) {
var up = Quat.getUp(Camera.getOrientation());
var right = Quat.getRight(Camera.getOrientation());
var distance = Vec3.length(vector);
var up = Quat.getUp(Camera.getOrientation());
var right = Quat.getRight(Camera.getOrientation());
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);
position = Vec3.sum(position, dv);
center = Vec3.sum(center, dv);
position = Vec3.sum(position, dv);
Camera.setPosition(position);
Camera.setOrientation(orientationOf(vector));
Camera.setPosition(position);
Camera.setOrientation(orientationOf(vector));
}
function saveCameraState() {
oldMode = Camera.mode;
oldPosition = Camera.getPosition();
oldOrientation = Camera.getOrientation();
oldMode = Camera.mode;
oldPosition = Camera.getPosition();
oldOrientation = Camera.getOrientation();
Camera.mode = "independent";
Camera.setPosition(oldPosition);
Camera.mode = "independent";
Camera.setPosition(oldPosition);
}
function restoreCameraState() {
Camera.mode = oldMode;
Camera.setPosition(oldPosition);
Camera.setOrientation(oldOrientation);
Camera.mode = oldMode;
Camera.setPosition(oldPosition);
Camera.setOrientation(oldOrientation);
}
function handleModes() {
var newMode = (mode == noMode) ? noMode : detachedMode;
if (alt) {
if (control) {
if (shift) {
newMode = panningMode;
} else {
newMode = orbitMode;
}
} else {
newMode = radialMode;
var newMode = (mode == noMode) ? noMode : detachedMode;
if (alt) {
if (control) {
if (shift) {
newMode = panningMode;
} else {
newMode = orbitMode;
}
} else {
newMode = radialMode;
}
}
}
// if entering detachMode
if (newMode == detachedMode && mode != detachedMode) {
avatarPosition = MyAvatar.position;
avatarOrientation = MyAvatar.orientation;
}
// if leaving detachMode
if (mode == detachedMode && newMode == detachedMode &&
(avatarPosition.x != MyAvatar.position.x ||
avatarPosition.y != MyAvatar.position.y ||
avatarPosition.z != MyAvatar.position.z ||
avatarOrientation.x != MyAvatar.orientation.x ||
avatarOrientation.y != MyAvatar.orientation.y ||
avatarOrientation.z != MyAvatar.orientation.z ||
avatarOrientation.w != MyAvatar.orientation.w)) {
newMode = noMode;
}
// if entering detachMode
if (newMode == detachedMode && mode != detachedMode) {
avatarPosition = MyAvatar.position;
avatarOrientation = MyAvatar.orientation;
}
// if leaving detachMode
if (mode == detachedMode && newMode == detachedMode &&
(avatarPosition.x != MyAvatar.position.x ||
avatarPosition.y != MyAvatar.position.y ||
avatarPosition.z != MyAvatar.position.z ||
avatarOrientation.x != MyAvatar.orientation.x ||
avatarOrientation.y != MyAvatar.orientation.y ||
avatarOrientation.z != MyAvatar.orientation.z ||
avatarOrientation.w != MyAvatar.orientation.w)) {
newMode = noMode;
}
if (mode == noMode && newMode != noMode && Camera.mode == "independent") {
newMode = noMode;
}
if (mode == noMode && newMode != noMode && Camera.mode == "independent") {
newMode = noMode;
}
// if leaving noMode
if (mode == noMode && newMode != noMode) {
saveCameraState();
}
// if entering noMode
if (newMode == noMode && mode != noMode) {
restoreCameraState();
}
// if leaving noMode
if (mode == noMode && newMode != noMode) {
saveCameraState();
}
// if entering noMode
if (newMode == noMode && mode != noMode) {
restoreCameraState();
}
mode = newMode;
mode = newMode;
}
function keyPressEvent(event) {
var changed = false;
var changed = false;
if (event.text == "ALT") {
alt = true;
changed = true;
}
if (event.text == "CONTROL") {
control = true;
changed = true;
}
if (event.text == "SHIFT") {
shift = true;
changed = true;
}
if (event.text == "ALT") {
alt = true;
changed = true;
}
if (event.text == "CONTROL") {
control = true;
changed = true;
}
if (event.text == "SHIFT") {
shift = true;
changed = true;
}
if (changed) {
handleModes();
}
if (changed) {
handleModes();
}
}
function keyReleaseEvent(event) {
var changed = false;
var changed = false;
if (event.text == "ALT") {
alt = false;
changed = true;
mode = noMode;
restoreCameraState();
}
if (event.text == "CONTROL") {
control = false;
changed = true;
}
if (event.text == "SHIFT") {
shift = false;
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 (event.text == "ALT") {
alt = false;
changed = true;
mode = noMode;
restoreCameraState();
}
if (event.text == "CONTROL") {
control = false;
changed = true;
}
if (event.text == "SHIFT") {
shift = false;
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);
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) {
if (isActive) {
isActive = false;
}
if (isActive) {
isActive = false;
}
}
function mouseMoveEvent(event) {
if (isActive && mode != noMode && !rotatingTowardsTarget) {
if (mode == radialMode) {
handleRadialMode(event.x - mouseLastX, event.y - mouseLastY);
if (isActive && mode != noMode && !rotatingTowardsTarget) {
if (mode == radialMode) {
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) {
handleOrbitMode(event.x - mouseLastX, event.y - mouseLastY);
}
if (mode == panningMode) {
handlePanMode(event.x - mouseLastX, event.y - mouseLastY);
}
}
mouseLastX = event.x;
mouseLastY = event.y;
mouseLastX = event.x;
mouseLastY = event.y;
}
function update() {
handleModes();
if (rotatingTowardsTarget) {
rotateTowardsTarget();
}
handleModes();
if (rotatingTowardsTarget) {
rotateTowardsTarget();
}
}
function rotateTowardsTarget() {
var newOrientation = Quat.mix(Camera.getOrientation(), targetCamOrientation, .1);
Camera.setOrientation(newOrientation);
var newOrientation = Quat.mix(Camera.getOrientation(), targetCamOrientation, 0.1);
Camera.setOrientation(newOrientation);
}
function scriptEnding() {
if (mode != noMode) {
restoreCameraState();
}
if (mode != noMode) {
restoreCameraState();
}
}
Controller.keyPressEvent.connect(keyPressEvent);
@ -345,4 +334,4 @@ Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
Controller.mouseMoveEvent.connect(mouseMoveEvent);
Script.update.connect(update);
Script.scriptEnding.connect(scriptEnding);
Script.scriptEnding.connect(scriptEnding);

View file

@ -46,7 +46,6 @@ function onMuteClicked() {
printd("On Mute Clicked");
//Menu.setIsOptionChecked("Mute Microphone", !Menu.isOptionChecked("Mute Microphone"));
Audio.muted = !Audio.muted;
onMuteToggled();
}
function onMuteToggled() {

View file

@ -35,6 +35,7 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
break;
case 'hide':
Controller.setVPadHidden(false);
module.exports.hide();
module.exports.onHidden();
break;
default:

View file

@ -33,7 +33,6 @@ function init() {
radar.setUniqueColor(uniqueColor);
radar.init();
setupModesBar();
radar.isTouchValid = isRadarModeValidTouch;
}
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 () {
shutdown();
});

View file

@ -13,7 +13,7 @@
var radarModeInterface = {};
var logEnabled = true;
var logEnabled = false;
function printd(str) {
if (logEnabled) {
print("[radar.js] " + str);
@ -118,19 +118,10 @@ function actionOnObjectFromEvent(event) {
}
function mousePress(event) {
if (!isTouchValid(coords)) {
currentTouchIsValid = false;
return;
} else {
currentTouchIsValid = true;
}
mousePressOrTouchEnd(event);
}
function mousePressOrTouchEnd(event) {
if (!currentTouchIsValid) {
return;
}
if (radar) {
if (actionOnObjectFromEvent(event)) {
return;
@ -155,9 +146,6 @@ function fakeDoubleTap(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 fakeDoubleTapStart = Date.now();
var touchEndCount = 0;
@ -238,12 +226,6 @@ function touchEnd(event) {
return;
}
// if touch is invalid, cancel
if (!currentTouchIsValid) {
printd("touchEnd fail because !currentTouchIsValid");
return;
}
if (analyzeDoubleTap(event))
return; // double tap detected, finish
@ -345,20 +327,6 @@ function computePointAtPlaneY(x, y, 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,
y : event.y
};
if (!isTouchValid(coords)) {
printd("analyze touch - RADAR_TOUCH - INVALID");
currentTouchIsValid = false;
touchStartingCoordinates = null;
} else {
printd("analyze touch - RADAR_TOUCH - ok");
currentTouchIsValid = true;
touchStartingCoordinates = coords;
touchBeginTime = Date.now();
}
touchStartingCoordinates = coords;
touchBeginTime = Date.now();
}
var startedDraggingCamera = false; // first time
@ -848,9 +808,6 @@ function oneFingerTouchUpdate(event) {
}
function touchUpdate(event) {
if (!currentTouchIsValid) {
return; // avoid moving and zooming when tap is over UI entities
}
if (event.isPinching || event.isPinchOpening) {
pinchUpdate(event);
} else {

View file

@ -307,6 +307,10 @@ WebTablet.prototype.setScriptURL = function (scriptURL) {
Overlays.editOverlay(this.webOverlayID, { scriptURL: scriptURL });
};
WebTablet.prototype.getOverlayObject = function () {
return Overlays.getOverlayObject(this.webOverlayID);
};
WebTablet.prototype.setWidth = function (width) {
// imported from libraries/utils.js
resizeTablet(width);