Make web entities interactive (via the mouse) if they're not locked.

This commit is contained in:
Brad Davis 2015-05-14 01:15:20 -07:00
parent baf4157da0
commit a77816617d
5 changed files with 71 additions and 11 deletions

View file

@ -850,9 +850,18 @@ RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(cons
}
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::mousePressOnEntity, entityScriptingInterface,
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId){
entityScriptingInterface->mousePressOnEntity(intersection.entityID, MouseEvent(*event, deviceId));
});
connect(this, &EntityTreeRenderer::mouseMoveOnEntity, entityScriptingInterface,
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) {
entityScriptingInterface->mouseMoveOnEntity(intersection.entityID, MouseEvent(*event, deviceId));
});
connect(this, &EntityTreeRenderer::mouseReleaseOnEntity, entityScriptingInterface,
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) {
entityScriptingInterface->mouseReleaseOnEntity(intersection.entityID, MouseEvent(*event, deviceId));
});
connect(this, &EntityTreeRenderer::clickDownOnEntity, entityScriptingInterface, &EntityScriptingInterface::clickDownOnEntity);
connect(this, &EntityTreeRenderer::holdingClickOnEntity, entityScriptingInterface, &EntityScriptingInterface::holdingClickOnEntity);
@ -900,7 +909,7 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event, unsigned int device
RayToEntityIntersectionResult rayPickResult = findRayIntersectionWorker(ray, Octree::Lock, precisionPicking);
if (rayPickResult.intersects) {
//qCDebug(entitiesrenderer) << "mousePressEvent over entity:" << rayPickResult.entityID;
emit mousePressOnEntity(rayPickResult.entityID, MouseEvent(*event, deviceID));
emit mousePressOnEntity(rayPickResult, event, deviceID);
QScriptValueList entityScriptArgs = createMouseEventArgs(rayPickResult.entityID, event, deviceID);
QScriptValue entityScript = loadEntityScript(rayPickResult.entity);
@ -930,7 +939,7 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event, unsigned int devi
RayToEntityIntersectionResult rayPickResult = findRayIntersectionWorker(ray, Octree::Lock, precisionPicking);
if (rayPickResult.intersects) {
//qCDebug(entitiesrenderer) << "mouseReleaseEvent over entity:" << rayPickResult.entityID;
emit mouseReleaseOnEntity(rayPickResult.entityID, MouseEvent(*event, deviceID));
emit mouseReleaseOnEntity(rayPickResult, event, deviceID);
QScriptValueList entityScriptArgs = createMouseEventArgs(rayPickResult.entityID, event, deviceID);
QScriptValue entityScript = loadEntityScript(rayPickResult.entity);
@ -979,7 +988,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceI
}
//qCDebug(entitiesrenderer) << "mouseMoveEvent over entity:" << rayPickResult.entityID;
emit mouseMoveOnEntity(rayPickResult.entityID, MouseEvent(*event, deviceID));
emit mouseMoveOnEntity(rayPickResult, event, deviceID);
if (entityScript.property("mouseMoveOnEntity").isValid()) {
entityScript.property("mouseMoveOnEntity").call(entityScript, entityScriptArgs);
}

View file

@ -93,9 +93,9 @@ public:
virtual void errorInLoadingScript(const QUrl& url);
signals:
void mousePressOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
void mouseMoveOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
void mouseReleaseOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
void mousePressOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
void mouseMoveOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
void mouseReleaseOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
void clickDownOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
void holdingClickOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);

View file

@ -23,6 +23,8 @@
#include <TextureCache.h>
#include <gpu/GLBackend.h>
#include "EntityTreeRenderer.h"
const int FIXED_FONT_POINT_SIZE = 40;
const float DPI = 30.47;
const float METERS_TO_INCHES = 39.3701;
@ -63,6 +65,7 @@ RenderableWebEntityItem::~RenderableWebEntityItem() {
void RenderableWebEntityItem::render(RenderArgs* args) {
QOpenGLContext * currentContext = QOpenGLContext::currentContext();
QSurface * currentSurface = currentContext->surface();
if (!_webSurface) {
_webSurface = new OffscreenQmlSurface();
_webSurface->create(currentContext);
@ -89,6 +92,52 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
_webSurface->doneCurrent();
}
});
auto forwardMouseEvent = [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) {
// Ignore mouse interaction if we're locked
if (this->getLocked()) {
return;
}
if (intersection.entityID.id == getID()) {
if (event->button() == Qt::MouseButton::RightButton) {
if (event->type() == QEvent::MouseButtonRelease) {
AbstractViewStateInterface::instance()->postLambdaEvent([this] {
QMetaObject::invokeMethod(_webSurface->getRootItem(), "goBack");
});
}
return;
}
if (event->button() == Qt::MouseButton::MiddleButton) {
if (event->type() == QEvent::MouseButtonRelease) {
AbstractViewStateInterface::instance()->postLambdaEvent([this] {
_webSurface->getRootItem()->setProperty("url", _sourceUrl);
});
}
return;
}
// Map the intersection point to an actual offscreen pixel
glm::vec3 point = intersection.intersection;
point -= getPosition();
point = glm::inverse(getRotation()) * point;
point /= _dimensions;
point += 0.5f;
point.y = 1.0f - point.y;
point *= _dimensions * METERS_TO_INCHES * DPI;
// Forward the mouse event.
QMouseEvent mappedEvent(event->type(),
QPoint((int)point.x, (int)point.y),
event->screenPos(), event->button(),
event->buttons(), event->modifiers());
QCoreApplication::sendEvent(_webSurface->getWindow(), &mappedEvent);
}
};
EntityTreeRenderer* renderer = static_cast<EntityTreeRenderer*>(args->_renderer);
QObject::connect(renderer, &EntityTreeRenderer::mousePressOnEntity, forwardMouseEvent);
QObject::connect(renderer, &EntityTreeRenderer::mouseReleaseOnEntity, forwardMouseEvent);
QObject::connect(renderer, &EntityTreeRenderer::mouseMoveOnEntity, forwardMouseEvent);
}
glm::vec2 dims = glm::vec2(_dimensions);
@ -106,8 +155,6 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
glm::vec3 halfDimensions = dimensions / 2.0f;
glm::quat rotation = getRotation();
//qCDebug(entitytree) << "RenderableWebEntityItem::render() id:" << getEntityItemID() << "text:" << getText();
glPushMatrix();
{
glTranslatef(position.x, position.y, position.z);

View file

@ -374,3 +374,6 @@ void OffscreenQmlSurface::setProxyWindow(QWindow* window) {
_renderControl->_renderWindow = window;
}
QQuickWindow* OffscreenQmlSurface::getWindow() {
return _quickWindow;
}

View file

@ -71,6 +71,7 @@ public:
void setBaseUrl(const QUrl& baseUrl);
QQuickItem* getRootItem();
QQuickWindow* getWindow();
virtual bool eventFilter(QObject* originalDestination, QEvent* event);