mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 04:59:54 +02:00
pointerevents are working!
This commit is contained in:
parent
abd7d6bddf
commit
8f0bd2449b
9 changed files with 120 additions and 132 deletions
|
@ -1884,6 +1884,16 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
connect(&_overlays, &Overlays::mousePressOnOverlay, [this](const QUuid& id, const PointerEvent& event) {
|
||||||
|
if (event.shouldFocus()) {
|
||||||
|
if (getEntities()->wantsKeyboardFocus(id)) {
|
||||||
|
setKeyboardFocusLocalEntity(id);
|
||||||
|
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||||
|
} else {
|
||||||
|
setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::deletingEntity, [this](const EntityItemID& entityItemID) {
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::deletingEntity, [this](const EntityItemID& entityItemID) {
|
||||||
if (entityItemID == _keyboardFocusedEntity.get()) {
|
if (entityItemID == _keyboardFocusedEntity.get()) {
|
||||||
|
@ -5729,7 +5739,7 @@ void Application::setKeyboardFocusHighlight(const glm::vec3& position, const glm
|
||||||
properties.getPulse().setMax(1.0f);
|
properties.getPulse().setMax(1.0f);
|
||||||
properties.getPulse().setColorMode(PulseMode::IN_PHASE);
|
properties.getPulse().setColorMode(PulseMode::IN_PHASE);
|
||||||
properties.setIgnorePickIntersection(true);
|
properties.setIgnorePickIntersection(true);
|
||||||
_keyboardFocusHighlightID = entityScriptingInterface->addEntity(properties, QString("local"));
|
_keyboardFocusHighlightID = entityScriptingInterface->addEntityInternal(properties, entity::HostType::LOCAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position focus
|
// Position focus
|
||||||
|
@ -8760,7 +8770,7 @@ void Application::createLoginDialog() {
|
||||||
properties.setVisible(true);
|
properties.setVisible(true);
|
||||||
|
|
||||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
_loginDialogID = entityScriptingInterface->addEntity(properties, QString("local"));
|
_loginDialogID = entityScriptingInterface->addEntityInternal(properties, entity::HostType::LOCAL);
|
||||||
|
|
||||||
auto keyboard = DependencyManager::get<Keyboard>().data();
|
auto keyboard = DependencyManager::get<Keyboard>().data();
|
||||||
if (!keyboard->getAnchorID().isNull() && !_loginDialogID.isNull()) {
|
if (!keyboard->getAnchorID().isNull() && !_loginDialogID.isNull()) {
|
||||||
|
|
|
@ -84,7 +84,7 @@ void OtherAvatar::createOrb() {
|
||||||
properties.setDimensions(glm::vec3(0.5f, 0.5f, 0.5f));
|
properties.setDimensions(glm::vec3(0.5f, 0.5f, 0.5f));
|
||||||
properties.setVisible(true);
|
properties.setVisible(true);
|
||||||
|
|
||||||
_otherAvatarOrbMeshPlaceholderID = DependencyManager::get<EntityScriptingInterface>()->addEntity(properties, QString("local"));
|
_otherAvatarOrbMeshPlaceholderID = DependencyManager::get<EntityScriptingInterface>()->addEntityInternal(properties, entity::HostType::LOCAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -743,7 +743,7 @@ void Keyboard::loadKeyboardFile(const QString& keyboardFile) {
|
||||||
properties.setRotation(quatFromVariant(anchorObject["rotation"].toVariant()));
|
properties.setRotation(quatFromVariant(anchorObject["rotation"].toVariant()));
|
||||||
|
|
||||||
Anchor anchor;
|
Anchor anchor;
|
||||||
anchor.entityID = entityScriptingInterface->addEntity(properties, QString("local"));
|
anchor.entityID = entityScriptingInterface->addEntityInternal(properties, entity::HostType::LOCAL);
|
||||||
anchor.originalDimensions = dimensions;
|
anchor.originalDimensions = dimensions;
|
||||||
_anchor = anchor;
|
_anchor = anchor;
|
||||||
}
|
}
|
||||||
|
@ -765,7 +765,7 @@ void Keyboard::loadKeyboardFile(const QString& keyboardFile) {
|
||||||
properties.setParentID(_anchor.entityID);
|
properties.setParentID(_anchor.entityID);
|
||||||
|
|
||||||
BackPlate backPlate;
|
BackPlate backPlate;
|
||||||
backPlate.entityID = entityScriptingInterface->addEntity(properties, QString("local"));
|
backPlate.entityID = entityScriptingInterface->addEntityInternal(properties, entity::HostType::LOCAL);
|
||||||
backPlate.dimensions = dimensions;
|
backPlate.dimensions = dimensions;
|
||||||
EntityPropertyFlags desiredProperties;
|
EntityPropertyFlags desiredProperties;
|
||||||
desiredProperties += PROP_LOCAL_POSITION;
|
desiredProperties += PROP_LOCAL_POSITION;
|
||||||
|
@ -822,7 +822,7 @@ void Keyboard::loadKeyboardFile(const QString& keyboardFile) {
|
||||||
properties.setTextures(QVariant(textureMap).toString());
|
properties.setTextures(QVariant(textureMap).toString());
|
||||||
properties.getGrab().setGrabbable(false);
|
properties.getGrab().setGrabbable(false);
|
||||||
properties.setLocalRotation(quatFromVariant(keyboardKeyValue["localOrientation"].toVariant()));
|
properties.setLocalRotation(quatFromVariant(keyboardKeyValue["localOrientation"].toVariant()));
|
||||||
QUuid id = entityScriptingInterface->addEntity(properties, QString("local"));
|
QUuid id = entityScriptingInterface->addEntityInternal(properties, entity::HostType::LOCAL);
|
||||||
key.setID(id);
|
key.setID(id);
|
||||||
key.setKeyString(keyString);
|
key.setKeyString(keyString);
|
||||||
key.saveDimensionsAndLocalPosition();
|
key.saveDimensionsAndLocalPosition();
|
||||||
|
@ -859,7 +859,7 @@ void Keyboard::loadKeyboardFile(const QString& keyboardFile) {
|
||||||
properties.setParentID(_anchor.entityID);
|
properties.setParentID(_anchor.entityID);
|
||||||
|
|
||||||
TextDisplay textDisplay;
|
TextDisplay textDisplay;
|
||||||
textDisplay.entityID = entityScriptingInterface->addEntity(properties, QString("local"));
|
textDisplay.entityID = entityScriptingInterface->addEntityInternal(properties, entity::HostType::LOCAL);
|
||||||
textDisplay.localPosition = localPosition;
|
textDisplay.localPosition = localPosition;
|
||||||
textDisplay.dimensions = dimensions;
|
textDisplay.dimensions = dimensions;
|
||||||
textDisplay.lineHeight = lineHeight;
|
textDisplay.lineHeight = lineHeight;
|
||||||
|
|
|
@ -205,7 +205,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
|
||||||
properties.setImageURL(PathUtils::resourcesUrl() + "images/inspect-icon.png");
|
properties.setImageURL(PathUtils::resourcesUrl() + "images/inspect-icon.png");
|
||||||
properties.setBillboardMode(BillboardMode::FULL);
|
properties.setBillboardMode(BillboardMode::FULL);
|
||||||
|
|
||||||
_contextOverlayID = entityScriptingInterface->addEntity(properties, QString("local"));
|
_contextOverlayID = entityScriptingInterface->addEntityInternal(properties, entity::HostType::LOCAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties properties;
|
EntityItemProperties properties;
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#include <raypick/RayPick.h>
|
#include <raypick/RayPick.h>
|
||||||
#include <PointerManager.h>
|
#include <PointerManager.h>
|
||||||
|
#include <raypick/MouseTransformNode.h>
|
||||||
|
#include <PickManager.h>
|
||||||
|
|
||||||
#include <RenderableWebEntityItem.h>
|
#include <RenderableWebEntityItem.h>
|
||||||
#include "VariantMapToScriptValue.h"
|
#include "VariantMapToScriptValue.h"
|
||||||
|
@ -35,7 +37,6 @@
|
||||||
#include "ui/Keyboard.h"
|
#include "ui/Keyboard.h"
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
|
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(trace_render_overlays, "trace.render.overlays")
|
Q_LOGGING_CATEGORY(trace_render_overlays, "trace.render.overlays")
|
||||||
|
|
||||||
std::unordered_map<QString, QString> Overlays::_entityToOverlayTypes;
|
std::unordered_map<QString, QString> Overlays::_entityToOverlayTypes;
|
||||||
|
@ -62,6 +63,13 @@ Overlays::Overlays() {
|
||||||
ADD_TYPE_MAP(PolyLine, line3d);
|
ADD_TYPE_MAP(PolyLine, line3d);
|
||||||
ADD_TYPE_MAP(Grid, grid);
|
ADD_TYPE_MAP(Grid, grid);
|
||||||
ADD_TYPE_MAP(Gizmo, circle3d);
|
ADD_TYPE_MAP(Gizmo, circle3d);
|
||||||
|
|
||||||
|
auto mouseRayPick = std::make_shared<RayPick>(Vectors::ZERO, Vectors::UP,
|
||||||
|
PickFilter(PickFilter::getBitMask(PickFilter::FlagBit::LOCAL_ENTITIES) |
|
||||||
|
PickFilter::getBitMask(PickFilter::FlagBit::VISIBLE)), 0.0f, true);
|
||||||
|
mouseRayPick->parentTransform = std::make_shared<MouseTransformNode>();
|
||||||
|
mouseRayPick->setJointState(PickQuery::JOINT_STATE_MOUSE);
|
||||||
|
_mouseRayPickID = DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, mouseRayPick);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::cleanupAllOverlays() {
|
void Overlays::cleanupAllOverlays() {
|
||||||
|
@ -79,6 +87,13 @@ void Overlays::cleanupAllOverlays() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::init() {
|
void Overlays::init() {
|
||||||
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
|
connect(this, &Overlays::hoverEnterOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity);
|
||||||
|
connect(this, &Overlays::hoverOverOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity);
|
||||||
|
connect(this, &Overlays::hoverLeaveOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity);
|
||||||
|
connect(this, &Overlays::mousePressOnOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity);
|
||||||
|
connect(this, &Overlays::mouseMoveOnOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity);
|
||||||
|
connect(this, &Overlays::mouseReleaseOnOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::update(float deltatime) {
|
void Overlays::update(float deltatime) {
|
||||||
|
@ -320,7 +335,7 @@ EntityItemProperties Overlays::convertOverlayToEntityProperties(QVariantMap& ove
|
||||||
ratio = iter.value().toFloat() / 0.5f;
|
ratio = iter.value().toFloat() / 0.5f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glm::vec3 dimensions = ENTITY_ITEM_DEFAULT_DIMENSIONS;
|
glm::vec3 dimensions = glm::vec3(1.0f);
|
||||||
{
|
{
|
||||||
auto iter = overlayProps.find("dimensions");
|
auto iter = overlayProps.find("dimensions");
|
||||||
if (iter != overlayProps.end()) {
|
if (iter != overlayProps.end()) {
|
||||||
|
@ -347,7 +362,7 @@ EntityItemProperties Overlays::convertOverlayToEntityProperties(QVariantMap& ove
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME:
|
// FIXME:
|
||||||
overlayProps["rotation"] = quatToVariant(glm::angleAxis((float)M_PI_2, Vectors::RIGHT) * rotation);
|
//overlayProps["rotation"] = quatToVariant(glm::angleAxis((float)M_PI_2, Vectors::RIGHT) * rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -510,7 +525,7 @@ QUuid Overlays::addOverlay(const QString& type, const QVariant& properties) {
|
||||||
if (type == "rectangle3d") {
|
if (type == "rectangle3d") {
|
||||||
propertyMap["shape"] = "Quad";
|
propertyMap["shape"] = "Quad";
|
||||||
}
|
}
|
||||||
return DependencyManager::get<EntityScriptingInterface>()->addEntity(convertOverlayToEntityProperties(propertyMap, entityType, true), QString("local"));
|
return DependencyManager::get<EntityScriptingInterface>()->addEntityInternal(convertOverlayToEntityProperties(propertyMap, entityType, true), entity::HostType::LOCAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid Overlays::add2DOverlay(const Overlay::Pointer& overlay) {
|
QUuid Overlays::add2DOverlay(const Overlay::Pointer& overlay) {
|
||||||
|
@ -950,21 +965,63 @@ static PointerEvent::Button toPointerButton(const QMouseEvent& event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerEvent Overlays::calculateOverlayPointerEvent(const QUuid& id, const PickRay& ray,
|
RayToOverlayIntersectionResult getPrevPickResult(unsigned int mouseRayPickID) {
|
||||||
const RayToOverlayIntersectionResult& rayPickResult, QMouseEvent* event,
|
RayToOverlayIntersectionResult overlayResult;
|
||||||
PointerEvent::EventType eventType) {
|
overlayResult.intersects = false;
|
||||||
glm::vec2 pos2D = RayPick::projectOntoEntityXYPlane(id, rayPickResult.intersection);
|
auto pickResult = DependencyManager::get<PickManager>()->getPrevPickResultTyped<RayPickResult>(mouseRayPickID);
|
||||||
PointerEvent pointerEvent(eventType, PointerManager::MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal,
|
if (pickResult) {
|
||||||
ray.direction, toPointerButton(*event), toPointerButtons(*event), event->modifiers());
|
overlayResult.intersects = pickResult->type != IntersectionType::NONE;
|
||||||
|
if (overlayResult.intersects) {
|
||||||
|
overlayResult.intersection = pickResult->intersection;
|
||||||
|
overlayResult.distance = pickResult->distance;
|
||||||
|
overlayResult.surfaceNormal = pickResult->surfaceNormal;
|
||||||
|
overlayResult.overlayID = pickResult->objectID;
|
||||||
|
overlayResult.extraInfo = pickResult->extraInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return overlayResult;
|
||||||
|
}
|
||||||
|
|
||||||
return pointerEvent;
|
PointerEvent Overlays::calculateOverlayPointerEvent(const QUuid& id, const PickRay& ray,
|
||||||
|
const RayToOverlayIntersectionResult& rayPickResult, QMouseEvent* event,
|
||||||
|
PointerEvent::EventType eventType) {
|
||||||
|
glm::vec2 pos2D = RayPick::projectOntoEntityXYPlane(id, rayPickResult.intersection);
|
||||||
|
return PointerEvent(eventType, PointerManager::MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal,
|
||||||
|
ray.direction, toPointerButton(*event), toPointerButtons(*event), event->modifiers());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Overlays::hoverEnterPointerEvent(const QUuid& id, const PointerEvent& event) {
|
||||||
|
auto keyboard = DependencyManager::get<Keyboard>();
|
||||||
|
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
||||||
|
if (!keyboard->getKeysID().contains(id)) {
|
||||||
|
// emit to scripts
|
||||||
|
emit hoverEnterOverlay(id, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Overlays::hoverOverPointerEvent(const QUuid& id, const PointerEvent& event) {
|
||||||
|
auto keyboard = DependencyManager::get<Keyboard>();
|
||||||
|
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
||||||
|
if (!keyboard->getKeysID().contains(id)) {
|
||||||
|
// emit to scripts
|
||||||
|
emit hoverOverOverlay(id, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Overlays::hoverLeavePointerEvent(const QUuid& id, const PointerEvent& event) {
|
||||||
|
auto keyboard = DependencyManager::get<Keyboard>();
|
||||||
|
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
||||||
|
if (!keyboard->getKeysID().contains(id)) {
|
||||||
|
// emit to scripts
|
||||||
|
emit hoverLeaveOverlay(id, event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Overlays::mousePressEvent(QMouseEvent* event) {
|
bool Overlays::mousePressEvent(QMouseEvent* event) {
|
||||||
PerformanceTimer perfTimer("Overlays::mousePressEvent");
|
PerformanceTimer perfTimer("Overlays::mousePressEvent");
|
||||||
|
|
||||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<EntityItemID>(), QVector<EntityItemID>());
|
RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(_mouseRayPickID);
|
||||||
if (rayPickResult.intersects) {
|
if (rayPickResult.intersects) {
|
||||||
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
||||||
|
|
||||||
|
@ -974,27 +1031,11 @@ bool Overlays::mousePressEvent(QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
// if we didn't press on an overlay, disable overlay keyboard focus
|
// if we didn't press on an overlay, disable overlay keyboard focus
|
||||||
setKeyboardFocusOverlay(UNKNOWN_ENTITY_ID);
|
setKeyboardFocusOverlay(UNKNOWN_ENTITY_ID);
|
||||||
// emit to scripts
|
|
||||||
emit mousePressOffOverlay();
|
emit mousePressOffOverlay();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::mousePressPointerEvent(const QUuid& id, const PointerEvent& event) {
|
void Overlays::mousePressPointerEvent(const QUuid& id, const PointerEvent& event) {
|
||||||
// TODO: generalize this to allow any object to recieve events
|
|
||||||
auto renderable = qApp->getEntities()->renderableForEntityId(id);
|
|
||||||
if (renderable) {
|
|
||||||
auto web = std::dynamic_pointer_cast<render::entities::WebEntityRenderer>(renderable);
|
|
||||||
if (web) {
|
|
||||||
if (event.shouldFocus()) {
|
|
||||||
// Focus keyboard on web overlays
|
|
||||||
DependencyManager::get<EntityScriptingInterface>()->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
|
||||||
setKeyboardFocusOverlay(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
web->handlePointerEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto keyboard = DependencyManager::get<Keyboard>();
|
auto keyboard = DependencyManager::get<Keyboard>();
|
||||||
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
||||||
if (!keyboard->getKeysID().contains(id)) {
|
if (!keyboard->getKeysID().contains(id)) {
|
||||||
|
@ -1007,79 +1048,23 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) {
|
||||||
PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent");
|
PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent");
|
||||||
|
|
||||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<EntityItemID>(), QVector<EntityItemID>());
|
RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(_mouseRayPickID);
|
||||||
if (rayPickResult.intersects) {
|
if (rayPickResult.intersects) {
|
||||||
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
||||||
|
|
||||||
auto pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press);
|
auto pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press);
|
||||||
// emit to scripts
|
|
||||||
emit mouseDoublePressOnOverlay(_currentClickingOnOverlayID, pointerEvent);
|
emit mouseDoublePressOnOverlay(_currentClickingOnOverlayID, pointerEvent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// emit to scripts
|
|
||||||
emit mouseDoublePressOffOverlay();
|
emit mouseDoublePressOffOverlay();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::hoverEnterPointerEvent(const QUuid& id, const PointerEvent& event) {
|
|
||||||
// TODO: generalize this to allow any object to recieve events
|
|
||||||
auto renderable = qApp->getEntities()->renderableForEntityId(id);
|
|
||||||
if (renderable) {
|
|
||||||
auto web = std::dynamic_pointer_cast<render::entities::WebEntityRenderer>(renderable);
|
|
||||||
if (web) {
|
|
||||||
web->hoverEnterEntity(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto keyboard = DependencyManager::get<Keyboard>();
|
|
||||||
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
|
||||||
if (!keyboard->getKeysID().contains(id)) {
|
|
||||||
// emit to scripts
|
|
||||||
emit hoverEnterOverlay(id, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlays::hoverOverPointerEvent(const QUuid& id, const PointerEvent& event) {
|
|
||||||
// TODO: generalize this to allow any overlay to recieve events
|
|
||||||
auto renderable = qApp->getEntities()->renderableForEntityId(id);
|
|
||||||
if (renderable) {
|
|
||||||
auto web = std::dynamic_pointer_cast<render::entities::WebEntityRenderer>(renderable);
|
|
||||||
if (web) {
|
|
||||||
web->handlePointerEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto keyboard = DependencyManager::get<Keyboard>();
|
|
||||||
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
|
||||||
if (!keyboard->getKeysID().contains(id)) {
|
|
||||||
// emit to scripts
|
|
||||||
emit hoverOverOverlay(id, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlays::hoverLeavePointerEvent(const QUuid& id, const PointerEvent& event) {
|
|
||||||
// TODO: generalize this to allow any overlay to recieve events
|
|
||||||
auto renderable = qApp->getEntities()->renderableForEntityId(id);
|
|
||||||
if (renderable) {
|
|
||||||
auto web = std::dynamic_pointer_cast<render::entities::WebEntityRenderer>(renderable);
|
|
||||||
if (web) {
|
|
||||||
web->hoverLeaveEntity(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto keyboard = DependencyManager::get<Keyboard>();
|
|
||||||
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
|
||||||
if (!keyboard->getKeysID().contains(id)) {
|
|
||||||
// emit to scripts
|
|
||||||
emit hoverLeaveOverlay(id, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Overlays::mouseReleaseEvent(QMouseEvent* event) {
|
bool Overlays::mouseReleaseEvent(QMouseEvent* event) {
|
||||||
PerformanceTimer perfTimer("Overlays::mouseReleaseEvent");
|
PerformanceTimer perfTimer("Overlays::mouseReleaseEvent");
|
||||||
|
|
||||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<EntityItemID>(), QVector<EntityItemID>());
|
RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(_mouseRayPickID);
|
||||||
if (rayPickResult.intersects) {
|
if (rayPickResult.intersects) {
|
||||||
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release);
|
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release);
|
||||||
mouseReleasePointerEvent(rayPickResult.overlayID, pointerEvent);
|
mouseReleasePointerEvent(rayPickResult.overlayID, pointerEvent);
|
||||||
|
@ -1090,19 +1075,9 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::mouseReleasePointerEvent(const QUuid& id, const PointerEvent& event) {
|
void Overlays::mouseReleasePointerEvent(const QUuid& id, const PointerEvent& event) {
|
||||||
// TODO: generalize this to allow any overlay to recieve events
|
|
||||||
auto renderable = qApp->getEntities()->renderableForEntityId(id);
|
|
||||||
if (renderable) {
|
|
||||||
auto web = std::dynamic_pointer_cast<render::entities::WebEntityRenderer>(renderable);
|
|
||||||
if (web) {
|
|
||||||
web->handlePointerEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto keyboard = DependencyManager::get<Keyboard>();
|
auto keyboard = DependencyManager::get<Keyboard>();
|
||||||
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
||||||
if (!keyboard->getKeysID().contains(id)) {
|
if (!keyboard->getKeysID().contains(id)) {
|
||||||
// emit to scripts
|
|
||||||
emit mouseReleaseOnOverlay(id, event);
|
emit mouseReleaseOnOverlay(id, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1111,7 +1086,7 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) {
|
||||||
PerformanceTimer perfTimer("Overlays::mouseMoveEvent");
|
PerformanceTimer perfTimer("Overlays::mouseMoveEvent");
|
||||||
|
|
||||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<EntityItemID>(), QVector<EntityItemID>());
|
RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(_mouseRayPickID);
|
||||||
if (rayPickResult.intersects) {
|
if (rayPickResult.intersects) {
|
||||||
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move);
|
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move);
|
||||||
mouseMovePointerEvent(rayPickResult.overlayID, pointerEvent);
|
mouseMovePointerEvent(rayPickResult.overlayID, pointerEvent);
|
||||||
|
@ -1144,15 +1119,6 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::mouseMovePointerEvent(const QUuid& id, const PointerEvent& event) {
|
void Overlays::mouseMovePointerEvent(const QUuid& id, const PointerEvent& event) {
|
||||||
// TODO: generalize this to allow any overlay to recieve events
|
|
||||||
auto renderable = qApp->getEntities()->renderableForEntityId(id);
|
|
||||||
if (renderable) {
|
|
||||||
auto web = std::dynamic_pointer_cast<render::entities::WebEntityRenderer>(renderable);
|
|
||||||
if (web) {
|
|
||||||
web->handlePointerEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto keyboard = DependencyManager::get<Keyboard>();
|
auto keyboard = DependencyManager::get<Keyboard>();
|
||||||
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
|
||||||
if (!keyboard->getKeysID().contains(id)) {
|
if (!keyboard->getKeysID().contains(id)) {
|
||||||
|
@ -1175,8 +1141,6 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* <p>An overlay may be one of the following types:</p>
|
* <p>An overlay may be one of the following types:</p>
|
||||||
* <table>
|
* <table>
|
||||||
|
|
|
@ -715,6 +715,7 @@ private:
|
||||||
PointerEvent calculateOverlayPointerEvent(const QUuid& id, const PickRay& ray, const RayToOverlayIntersectionResult& rayPickResult,
|
PointerEvent calculateOverlayPointerEvent(const QUuid& id, const PickRay& ray, const RayToOverlayIntersectionResult& rayPickResult,
|
||||||
QMouseEvent* event, PointerEvent::EventType eventType);
|
QMouseEvent* event, PointerEvent::EventType eventType);
|
||||||
|
|
||||||
|
unsigned int _mouseRayPickID;
|
||||||
QUuid _currentClickingOnOverlayID;
|
QUuid _currentClickingOnOverlayID;
|
||||||
QUuid _currentHoverOverOverlayID;
|
QUuid _currentHoverOverOverlayID;
|
||||||
|
|
||||||
|
|
|
@ -84,38 +84,38 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
|
||||||
connect(pointerManager.data(), &PointerManager::triggerEndEntity, entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity);
|
connect(pointerManager.data(), &PointerManager::triggerEndEntity, entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity);
|
||||||
|
|
||||||
// Forward mouse events to web entities
|
// Forward mouse events to web entities
|
||||||
auto handlePointerEvent = [&](const EntityItemID& entityID, const PointerEvent& event) {
|
auto handlePointerEvent = [&](const QUuid& entityID, const PointerEvent& event) {
|
||||||
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
|
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
|
||||||
auto entity = getEntity(entityID);
|
auto entity = getEntity(entityID);
|
||||||
if (entity && entity->getType() == EntityTypes::Web) {
|
if (entity && entity->getType() == EntityTypes::Web) {
|
||||||
thisEntity = std::static_pointer_cast<render::entities::WebEntityRenderer>(renderableForEntityId(entityID));
|
thisEntity = std::static_pointer_cast<render::entities::WebEntityRenderer>(renderableForEntityId(entityID));
|
||||||
}
|
}
|
||||||
if (thisEntity) {
|
if (thisEntity) {
|
||||||
QMetaObject::invokeMethod(thisEntity.get(), "handlePointerEvent", Q_ARG(PointerEvent, event));
|
QMetaObject::invokeMethod(thisEntity.get(), "handlePointerEvent", Q_ARG(const PointerEvent&, event));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, handlePointerEvent);
|
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::mouseMoveOnEntity, this, handlePointerEvent);
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, this, [&](const EntityItemID& entityID, const PointerEvent& event) {
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, handlePointerEvent);
|
||||||
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, this, [&](const QUuid& entityID, const PointerEvent& event) {
|
||||||
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
|
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
|
||||||
auto entity = getEntity(entityID);
|
auto entity = getEntity(entityID);
|
||||||
if (entity && entity->getType() == EntityTypes::Web) {
|
if (entity && entity->getType() == EntityTypes::Web) {
|
||||||
thisEntity = std::static_pointer_cast<render::entities::WebEntityRenderer>(renderableForEntityId(entityID));
|
thisEntity = std::static_pointer_cast<render::entities::WebEntityRenderer>(renderableForEntityId(entityID));
|
||||||
}
|
}
|
||||||
if (thisEntity) {
|
if (thisEntity) {
|
||||||
QMetaObject::invokeMethod(thisEntity.get(), "hoverEnterEntity", Q_ARG(PointerEvent, event));
|
QMetaObject::invokeMethod(thisEntity.get(), "hoverEnterEntity", Q_ARG(const PointerEvent&, event));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, this, handlePointerEvent);
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, this, handlePointerEvent);
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, [&](const EntityItemID& entityID, const PointerEvent& event) {
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, [&](const QUuid& entityID, const PointerEvent& event) {
|
||||||
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
|
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
|
||||||
auto entity = getEntity(entityID);
|
auto entity = getEntity(entityID);
|
||||||
if (entity && entity->getType() == EntityTypes::Web) {
|
if (entity && entity->getType() == EntityTypes::Web) {
|
||||||
thisEntity = std::static_pointer_cast<render::entities::WebEntityRenderer>(renderableForEntityId(entityID));
|
thisEntity = std::static_pointer_cast<render::entities::WebEntityRenderer>(renderableForEntityId(entityID));
|
||||||
}
|
}
|
||||||
if (thisEntity) {
|
if (thisEntity) {
|
||||||
QMetaObject::invokeMethod(thisEntity.get(), "hoverLeaveEntity", Q_ARG(PointerEvent, event));
|
QMetaObject::invokeMethod(thisEntity.get(), "hoverLeaveEntity", Q_ARG(const PointerEvent&, event));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -474,7 +474,7 @@ void synchronizeEditedGrabProperties(EntityItemProperties& properties, const QSt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties, const QString& entityHostTypeString) {
|
QUuid EntityScriptingInterface::addEntityInternal(const EntityItemProperties& properties, entity::HostType entityHostType) {
|
||||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
|
||||||
_activityTracking.addedEntityCount++;
|
_activityTracking.addedEntityCount++;
|
||||||
|
@ -483,10 +483,10 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
|
||||||
const auto sessionID = nodeList->getSessionUUID();
|
const auto sessionID = nodeList->getSessionUUID();
|
||||||
|
|
||||||
EntityItemProperties propertiesWithSimID = properties;
|
EntityItemProperties propertiesWithSimID = properties;
|
||||||
propertiesWithSimID.setEntityHostTypeFromString(entityHostTypeString);
|
propertiesWithSimID.setEntityHostType(entityHostType);
|
||||||
if (propertiesWithSimID.getEntityHostType() == entity::HostType::AVATAR) {
|
if (entityHostType == entity::HostType::AVATAR) {
|
||||||
propertiesWithSimID.setOwningAvatarID(sessionID);
|
propertiesWithSimID.setOwningAvatarID(sessionID);
|
||||||
} else if (propertiesWithSimID.getEntityHostType() == entity::HostType::LOCAL) {
|
} else if (entityHostType == entity::HostType::LOCAL) {
|
||||||
// For now, local entities are always collisionless
|
// For now, local entities are always collisionless
|
||||||
// TODO: create a separate, local physics simulation that just handles local entities (and MyAvatar?)
|
// TODO: create a separate, local physics simulation that just handles local entities (and MyAvatar?)
|
||||||
propertiesWithSimID.setCollisionless(true);
|
propertiesWithSimID.setCollisionless(true);
|
||||||
|
@ -579,9 +579,9 @@ QUuid EntityScriptingInterface::cloneEntity(const QUuid& entityIDToClone) {
|
||||||
|
|
||||||
if (properties.getEntityHostType() == entity::HostType::LOCAL) {
|
if (properties.getEntityHostType() == entity::HostType::LOCAL) {
|
||||||
// Local entities are only cloned locally
|
// Local entities are only cloned locally
|
||||||
return addEntity(properties, QString("local"));
|
return addEntityInternal(properties, entity::HostType::LOCAL);
|
||||||
} else if (cloneAvatarEntity) {
|
} else if (cloneAvatarEntity) {
|
||||||
return addEntity(properties, QString("avatar"));
|
return addEntityInternal(properties, entity::HostType::AVATAR);
|
||||||
} else {
|
} else {
|
||||||
// setLastEdited timestamp to 0 to ensure this entity gets updated with the properties
|
// setLastEdited timestamp to 0 to ensure this entity gets updated with the properties
|
||||||
// from the server-created entity, don't change this unless you know what you are doing
|
// from the server-created entity, don't change this unless you know what you are doing
|
||||||
|
|
|
@ -167,6 +167,9 @@ public:
|
||||||
*/
|
*/
|
||||||
static QScriptValue getMultipleEntityProperties(QScriptContext* context, QScriptEngine* engine);
|
static QScriptValue getMultipleEntityProperties(QScriptContext* context, QScriptEngine* engine);
|
||||||
QScriptValue getMultipleEntityPropertiesInternal(QScriptEngine* engine, QVector<QUuid> entityIDs, const QScriptValue& extendedDesiredProperties);
|
QScriptValue getMultipleEntityPropertiesInternal(QScriptEngine* engine, QVector<QUuid> entityIDs, const QScriptValue& extendedDesiredProperties);
|
||||||
|
|
||||||
|
QUuid addEntityInternal(const EntityItemProperties& properties, entity::HostType entityHostType);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -269,7 +272,17 @@ public slots:
|
||||||
* });
|
* });
|
||||||
* print("Entity created: " + entityID);
|
* print("Entity created: " + entityID);
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE QUuid addEntity(const EntityItemProperties& properties, const QString& entityHostTypeString);
|
Q_INVOKABLE QUuid addEntity(const EntityItemProperties& properties, const QString& entityHostTypeString) {
|
||||||
|
entity::HostType entityHostType;
|
||||||
|
if (entityHostTypeString == "domain") {
|
||||||
|
entityHostType = entity::HostType::DOMAIN;
|
||||||
|
} else if (entityHostTypeString == "avatar") {
|
||||||
|
entityHostType = entity::HostType::AVATAR;
|
||||||
|
} else if (entityHostTypeString == "local") {
|
||||||
|
entityHostType = entity::HostType::LOCAL;
|
||||||
|
}
|
||||||
|
return addEntityInternal(properties, entityHostType);
|
||||||
|
}
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Add a new entity with specified properties.
|
* Add a new entity with specified properties.
|
||||||
|
@ -279,8 +292,8 @@ public slots:
|
||||||
* @returns {Uuid} The ID of the entity if successfully created, otherwise {@link Uuid|Uuid.NULL}.
|
* @returns {Uuid} The ID of the entity if successfully created, otherwise {@link Uuid|Uuid.NULL}.
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE QUuid addEntity(const EntityItemProperties& properties, bool avatarEntity = false) {
|
Q_INVOKABLE QUuid addEntity(const EntityItemProperties& properties, bool avatarEntity = false) {
|
||||||
QString entityHostType = avatarEntity ? "avatar" : "domain";
|
entity::HostType entityHostType = avatarEntity ? entity::HostType::AVATAR : entity::HostType::DOMAIN;
|
||||||
return addEntity(properties, entityHostType);
|
return addEntityInternal(properties, entityHostType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// temporary method until addEntity can be used from QJSEngine
|
/// temporary method until addEntity can be used from QJSEngine
|
||||||
|
|
Loading…
Reference in a new issue