send pointer events from handControllerGrab.js to webEntities

This commit is contained in:
Anthony J. Thibault 2016-08-16 15:26:14 -07:00
parent 1be434342b
commit c407818d63
9 changed files with 283 additions and 67 deletions

View file

@ -2629,7 +2629,9 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
event->screenPos(), button,
buttons, event->modifiers());
getEntities()->mouseMoveEvent(&mappedEvent);
if (!compositor.getReticleOverDesktop() || getOverlays().getOverlayAtPoint(glm::vec2(transformedPos.x(), transformedPos.y()))) {
getEntities()->mouseMoveEvent(&mappedEvent);
}
_controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent); // send events to any registered scripts
// if one of our scripts have asked to capture this event, then stop processing it
@ -5641,3 +5643,48 @@ void Application::releaseOverlayTexture(const gpu::TexturePointer& texture) {
bool Application::isForeground() const {
return _isForeground && !_window->isMinimized();
}
void Application::sendMousePressOnEntity(QUuid id, PointerEvent event) {
EntityItemID entityItemID(id);
emit getEntities()->mousePressOnEntity(entityItemID, event);
}
void Application::sendMouseMoveOnEntity(QUuid id, PointerEvent event) {
EntityItemID entityItemID(id);
emit getEntities()->mouseMoveOnEntity(entityItemID, event);
}
void Application::sendMouseReleaseOnEntity(QUuid id, PointerEvent event) {
EntityItemID entityItemID(id);
emit getEntities()->mouseReleaseOnEntity(entityItemID, event);
}
void Application::sendClickDownOnEntity(QUuid id, PointerEvent event) {
EntityItemID entityItemID(id);
emit getEntities()->clickDownOnEntity(entityItemID, event);
}
void Application::sendHoldingClickOnEntity(QUuid id, PointerEvent event) {
EntityItemID entityItemID(id);
emit getEntities()->holdingClickOnEntity(entityItemID, event);
}
void Application::sendClickReleaseOnEntity(QUuid id, PointerEvent event) {
EntityItemID entityItemID(id);
emit getEntities()->clickReleaseOnEntity(entityItemID, event);
}
void Application::sendHoverEnterEntity(QUuid id, PointerEvent event) {
EntityItemID entityItemID(id);
emit getEntities()->hoverEnterEntity(entityItemID, event);
}
void Application::sendHoverOverEntity(QUuid id, PointerEvent event) {
EntityItemID entityItemID(id);
emit getEntities()->hoverOverEntity(entityItemID, event);
}
void Application::sendHoverLeaveEntity(QUuid id, PointerEvent event) {
EntityItemID entityItemID(id);
emit getEntities()->hoverLeaveEntity(entityItemID, event);
}

View file

@ -257,6 +257,18 @@ public:
gpu::TexturePointer getDefaultSkyboxTexture() const { return _defaultSkyboxTexture; }
gpu::TexturePointer getDefaultSkyboxAmbientTexture() const { return _defaultSkyboxAmbientTexture; }
Q_INVOKABLE void sendMousePressOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendMouseMoveOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendMouseReleaseOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendClickDownOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendHoldingClickOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendClickReleaseOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendHoverEnterEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendHoverOverEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendHoverLeaveEntity(QUuid id, PointerEvent event);
signals:
void svoImportRequested(const QString& url);

View file

@ -92,8 +92,8 @@ bool RenderableWebEntityItem::buildWebSurface(EntityTreeRenderer* renderer) {
point.setPos(windowPoint);
QList<QTouchEvent::TouchPoint> touchPoints;
touchPoints.push_back(point);
QTouchEvent touchEvent = QTouchEvent(QEvent::TouchEnd, nullptr, Qt::NoModifier, Qt::TouchPointReleased, touchPoints);
QCoreApplication::sendEvent(_webSurface->getWindow(), &touchEvent);
QTouchEvent* touchEvent = new QTouchEvent(QEvent::TouchEnd, nullptr, Qt::NoModifier, Qt::TouchPointReleased, touchPoints);
QCoreApplication::postEvent(_webSurface->getWindow(), touchEvent);
}
});
return true;
@ -188,25 +188,19 @@ void RenderableWebEntityItem::handlePointerEvent(const PointerEvent& event) {
glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * DPI);
QPointF windowPoint(windowPos.x, windowPos.y);
/*
qDebug() << "AJT: RenderableWebEntityItem::handlePointerEvent!";
qDebug() << "AJT: type = " << (int)event.getType();
qDebug() << "AJT: id = " << event.getID();
qDebug() << "AJT: pos2D = " << event.getPos2D();
qDebug() << "AJT: pos3D = " << event.getPos3D();
qDebug() << "AJT: normal = " << event.getNormal();
qDebug() << "AJT: direction = " << event.getDirection();
qDebug() << "AJT: button = " << (int)event.getButton();
qDebug() << "AJT: buttons = " << event.getButtons();
qDebug() << "AJT: windowPos = " << windowPos;
*/
if (event.getType() == PointerEvent::Move && event.getButtons() == PointerEvent::NoButtons) {
if (event.getType() == PointerEvent::Move) {
// Forward a mouse move event to webSurface
QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
QCoreApplication::sendEvent(_webSurface->getWindow(), &mouseEvent);
} else {
QMouseEvent* mouseEvent = new QMouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
QCoreApplication::postEvent(_webSurface->getWindow(), mouseEvent);
}
{
// Forward a touch update event to webSurface
if (event.getType() == PointerEvent::Press) {
this->_pressed = true;
} else if (event.getType() == PointerEvent::Release) {
this->_pressed = false;
}
QEvent::Type type;
Qt::TouchPointState touchPointState;
@ -234,17 +228,21 @@ void RenderableWebEntityItem::handlePointerEvent(const PointerEvent& event) {
QList<QTouchEvent::TouchPoint> touchPoints;
touchPoints.push_back(point);
QTouchEvent touchEvent(type, nullptr, Qt::NoModifier, touchPointState, touchPoints);
QCoreApplication::sendEvent(_webSurface->getWindow(), &touchEvent);
QTouchEvent* touchEvent = new QTouchEvent(type);
touchEvent->setWindow(nullptr);
touchEvent->setDevice(nullptr);
touchEvent->setTarget(nullptr);
touchEvent->setTouchPoints(touchPoints);
touchEvent->setTouchPointStates(touchPointState);
_lastTouchEvent = touchEvent;
_lastTouchEvent = *touchEvent;
QCoreApplication::postEvent(_webSurface->getWindow(), touchEvent);
}
}
void RenderableWebEntityItem::destroyWebSurface() {
if (_webSurface) {
qDebug() << "AJT: destroyWebSurface!";
--_currentWebCount;
_webSurface->pause();
_webSurface->disconnect(_connection);

View file

@ -1194,34 +1194,40 @@ void EntityScriptingInterface::setKeyboardFocusEntity(QUuid id) {
QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::QueuedConnection, Q_ARG(QUuid, id));
}
void EntityScriptingInterface::sendEntityMouseMoveEvent(QUuid id, glm::vec3 intersectionPoint) {
// AJT: TODO CURRENTLY BROKEN
//QMetaObject::invokeMethod(qApp, "sendEntityMouseMoveEvent", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(glm::vec3, intersectionPoint));
void EntityScriptingInterface::sendMousePressOnEntity(QUuid id, PointerEvent event) {
QMetaObject::invokeMethod(qApp, "sendMousePressOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
}
void EntityScriptingInterface::sendEntityLeftMouseDownEvent(QUuid id, glm::vec3 intersectionPoint) {
// AJT: TODO CURRENTLY BROKEN
//QMetaObject::invokeMethod(qApp, "sendEntityLeftMouseDownEvent", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(glm::vec3, intersectionPoint));
void EntityScriptingInterface::sendMouseMoveOnEntity(QUuid id, PointerEvent event) {
QMetaObject::invokeMethod(qApp, "sendMouseMoveOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
}
void EntityScriptingInterface::sendEntityLeftMouseUpEvent(QUuid id, glm::vec3 intersectionPoint) {
// AJT: TODO CURRENTLY BROKEN
//QMetaObject::invokeMethod(qApp, "sendEntityLeftMouseUpEvent", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(glm::vec3, intersectionPoint));
void EntityScriptingInterface::sendMouseReleaseOnEntity(QUuid id, PointerEvent event) {
QMetaObject::invokeMethod(qApp, "sendMouseReleaseOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
}
void EntityScriptingInterface::sendEntityTouchUpdateEvent(QUuid entityID, int fingerID, glm::vec3 intersectionPoint) {
// AJT: TODO CURRENTLY BROKEN
//QMetaObject::invokeMethod(qApp, "sendEntityTouchUpdateEvent", Qt::QueuedConnection, Q_ARG(QUuid, entityID), Q_ARG(int, fingerID), Q_ARG(glm::vec3, intersectionPoint));
void EntityScriptingInterface::sendClickDownOnEntity(QUuid id, PointerEvent event) {
QMetaObject::invokeMethod(qApp, "sendClickDownOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
}
void EntityScriptingInterface::sendEntityTouchBeginEvent(QUuid entityID, int fingerID, glm::vec3 intersectionPoint) {
// AJT: TODO CURRENTLY BROKEN
//QMetaObject::invokeMethod(qApp, "sendEntityTouchBeginEvent", Qt::QueuedConnection, Q_ARG(QUuid, entityID), Q_ARG(int, fingerID), Q_ARG(glm::vec3, intersectionPoint));
void EntityScriptingInterface::sendHoldingClickOnEntity(QUuid id, PointerEvent event) {
QMetaObject::invokeMethod(qApp, "sendHoldingClickOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
}
void EntityScriptingInterface::sendEntityTouchEndEvent(QUuid entityID, int fingerID, glm::vec3 intersectionPoint) {
// AJT: TODO CURRENTLY BROKEN
//QMetaObject::invokeMethod(qApp, "sendEntityTouchEndEvent", Qt::QueuedConnection, Q_ARG(QUuid, entityID), Q_ARG(int, fingerID), Q_ARG(glm::vec3, intersectionPoint));
void EntityScriptingInterface::sendClickReleaseOnEntity(QUuid id, PointerEvent event) {
QMetaObject::invokeMethod(qApp, "sendClickReleaseOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
}
void EntityScriptingInterface::sendHoverEnterEntity(QUuid id, PointerEvent event) {
QMetaObject::invokeMethod(qApp, "sendHoverEnterEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
}
void EntityScriptingInterface::sendHoverOverEntity(QUuid id, PointerEvent event) {
QMetaObject::invokeMethod(qApp, "sendHoverOverEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
}
void EntityScriptingInterface::sendHoverLeaveEntity(QUuid id, PointerEvent event) {
QMetaObject::invokeMethod(qApp, "sendHoverLeaveEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event));
}
float EntityScriptingInterface::calculateCost(float mass, float oldVelocity, float newVelocity) {

View file

@ -23,6 +23,7 @@
#include <Octree.h>
#include <OctreeScriptingInterface.h>
#include <RegisteredMetaTypes.h>
#include <PointerEvent.h>
#include "PolyVoxEntityItem.h"
#include "LineEntityItem.h"
@ -34,7 +35,6 @@
#include "EntityItemProperties.h"
class EntityTree;
class PointerEvent;
class RayToEntityIntersectionResult {
public:
@ -181,14 +181,17 @@ public slots:
Q_INVOKABLE QUuid getKeyboardFocusEntity() const;
Q_INVOKABLE void setKeyboardFocusEntity(QUuid id);
// AJT: TODO CURRENTLY BROKEN
Q_INVOKABLE void sendEntityMouseMoveEvent(QUuid id, glm::vec3 intersectionPoint);
Q_INVOKABLE void sendEntityLeftMouseDownEvent(QUuid id, glm::vec3 intersectionPoint);
Q_INVOKABLE void sendEntityLeftMouseUpEvent(QUuid id, glm::vec3 intersectionPoint);
Q_INVOKABLE void sendEntityTouchUpdateEvent(QUuid entityID, int fingerID, glm::vec3 intersectionPoint);
Q_INVOKABLE void sendEntityTouchBeginEvent(QUuid entityID, int fingerID, glm::vec3 intersectionPoint);
Q_INVOKABLE void sendEntityTouchEndEvent(QUuid entityID, int fingerID, glm::vec3 intersectionPoint);
Q_INVOKABLE void sendMousePressOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendMouseMoveOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendMouseReleaseOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendClickDownOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendHoldingClickOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendClickReleaseOnEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendHoverEnterEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendHoverOverEntity(QUuid id, PointerEvent event);
Q_INVOKABLE void sendHoverLeaveEntity(QUuid id, PointerEvent event);
signals:
void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);

View file

@ -99,19 +99,24 @@ void WebEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitst
}
bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal,
void** intersectedObject, bool precisionPicking) const {
bool& keepSearching, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal,
void** intersectedObject, bool precisionPicking) const {
glm::vec3 dimensions = getDimensions();
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
glm::quat rotation = getRotation();
glm::vec3 position = getPosition() + rotation *
(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT));
// FIXME - should set face and surfaceNormal
return findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance);
glm::vec3 position = getPosition() + rotation * (dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT));
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
surfaceNormal = rotation * Vectors::UNIT_Z;
face = glm::dot(surfaceNormal, direction) > 0 ? MIN_Z_FACE : MAX_Z_FACE;
return true;
} else {
return false;
}
}
void WebEntityItem::setSourceUrl(const QString& value) {
void WebEntityItem::setSourceUrl(const QString& value) {
if (_sourceUrl != value) {
_sourceUrl = value;
}

View file

@ -9,10 +9,12 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "PointerEvent.h"
#include <qscriptengine.h>
#include <qscriptvalue.h>
#include "PointerEvent.h"
#include "RegisteredMetaTypes.h"
static bool areFlagsSet(uint32_t flags, uint32_t mask) {
return (flags & mask) != 0;
@ -106,5 +108,56 @@ QScriptValue PointerEvent::toScriptValue(QScriptEngine* engine, const PointerEve
}
void PointerEvent::fromScriptValue(const QScriptValue& object, PointerEvent& event) {
// nothing for now...
if (object.isObject()) {
QScriptValue type = object.property("type");
QString typeStr = type.isString() ? type.toString() : "Move";
if (typeStr == "Press") {
event._type = Press;
} else if (typeStr == "Release") {
event._type = Release;
} else {
event._type = Move;
}
QScriptValue id = object.property("id");
event._id = type.isNumber() ? (uint32_t)type.toNumber() : 0;
glm::vec2 pos2D;
vec2FromScriptValue(object.property("pos2D"), event._pos2D);
glm::vec3 pos3D;
vec3FromScriptValue(object.property("pos3D"), event._pos3D);
glm::vec3 normal;
vec3FromScriptValue(object.property("normal"), event._normal);
glm::vec3 direction;
vec3FromScriptValue(object.property("direction"), event._direction);
QScriptValue button = object.property("button");
QString buttonStr = type.isString() ? type.toString() : "NoButtons";
if (buttonStr == "Primary") {
event._button = PrimaryButton;
} else if (buttonStr == "Secondary") {
event._button = SecondaryButton;
} else if (buttonStr == "Tertiary") {
event._button = TertiaryButton;
} else {
event._button = NoButtons;
}
bool primary = object.property("isPrimary").toBool() || object.property("isLeftButton").toBool();
bool secondary = object.property("isSecondary").toBool() || object.property("isRightButton").toBool();
bool tertiary = object.property("isTertiary").toBool() || object.property("isMiddleButton").toBool();
event._buttons = 0;
if (primary) {
event._buttons |= PrimaryButton;
}
if (secondary) {
event._buttons |= SecondaryButton;
}
if (tertiary) {
event._buttons |= TertiaryButton;
}
}
}

View file

@ -136,6 +136,7 @@ var PICKS_PER_SECOND_PER_HAND = 60;
var MSECS_PER_SEC = 1000.0;
var GRABBABLE_PROPERTIES = [
"position",
"registrationPoint",
"rotation",
"gravity",
"collidesWith",
@ -233,6 +234,18 @@ CONTROLLER_STATE_MACHINE[STATE_ENTITY_TOUCHING] = {
updateMethod: "entityTouching"
};
function projectOntoEntityXYPlane(entityID, worldPos) {
var props = entityPropertiesCache.getProps(entityID);
var invRot = Quat.inverse(props.rotation);
var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(worldPos, props.position));
var invDimensions = { x: 1 / props.dimensions.x,
y: 1 / props.dimensions.y,
z: 1 / props.dimensions.z };
var normalizedPos = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), props.registrationPoint);
return { x: normalizedPos.x * props.dimensions.x,
y: (1 - normalizedPos.y) * props.dimensions.y }; // flip y-axis
}
function handLaserIntersectWebEntity(entityID, hand) {
var standardControllerValue = (hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
var pose = Controller.getPoseValue(standardControllerValue);
@ -253,6 +266,7 @@ function handLaserIntersectWebEntity(entityID, hand) {
intersectionPoint = planePosition;
}
intersectionInfo.point = intersectionPoint;
intersectionInfo.normal = planeNormal;
intersectionInfo.searchRay = {
origin: rayStart,
direction: rayDirection,
@ -1071,7 +1085,8 @@ function MyController(hand) {
overlayID: intersection.overlayID,
searchRay: pickRay,
distance: Vec3.distance(pickRay.origin, intersection.intersection),
intersection: intersection.intersection
intersection: intersection.intersection,
normal: intersection.surfaceNormal
};
} else {
return result;
@ -1392,16 +1407,49 @@ function MyController(hand) {
entity = rayPickInfo.entityID;
name = entityPropertiesCache.getProps(entity).name;
var pointerEvent;
if (Entities.keyboardFocusEntity != entity) {
Entities.keyboardFocusEntity = entity;
pointerEvent = {
type: "Move",
id: this.hand + 1, // 0 is reserved for hardware mouse
pos2D: projectOntoEntityXYPlane(entity, rayPickInfo.intersection),
pos3D: rayPickInfo.intersection,
normal: rayPickInfo.normal,
direction: rayPickInfo.searchRay.direction,
button: "None",
isPrimaryButton: false,
isSecondaryButton: false,
isTertiaryButton: false
};
Entities.sendHoverEnterEntity(entity, pointerEvent);
// AJT: TODO: send hover leave entity at some point as well!!??!
}
// send mouse events for button highlights and tooltips.
if (this.hand == mostRecentSearchingHand || (this.hand !== mostRecentSearchingHand &&
this.getOtherHandController().state !== STATE_SEARCHING &&
this.getOtherHandController().state !== STATE_ENTITY_TOUCHING)) {
// most recently searching hand has priority over other hand, for the purposes of button highlighting.
Entities.sendEntityMouseMoveEvent(entity, rayPickInfo.intersection);
pointerEvent = {
type: "Move",
id: this.hand + 1, // 0 is reserved for hardware mouse
pos2D: projectOntoEntityXYPlane(entity, rayPickInfo.intersection),
pos3D: rayPickInfo.intersection,
normal: rayPickInfo.normal,
direction: rayPickInfo.searchRay.direction,
button: "None",
isPrimaryButton: false,
isSecondaryButton: false,
isTertiaryButton: false
};
Entities.sendMouseMoveOnEntity(entity, pointerEvent);
Entities.sendHoverOverEntity(entity, pointerEvent);
}
if (this.triggerSmoothedGrab() && !isEditing()) {
@ -2054,13 +2102,43 @@ function MyController(hand) {
this.entityTouchingEnter = function() {
// test for intersection between controller laser and web entity plane.
var intersectInfo = handLaserIntersectWebEntity(this.grabbedEntity, this.hand);
Entities.sendEntityTouchBeginEvent(this.grabbedEntity, this.hand, intersectInfo.point);
var pointerEvent = {
type: "Press",
id: this.hand + 1, // 0 is reserved for hardware mouse
pos2D: projectOntoEntityXYPlane(this.grabbedEntity, intersectInfo.point),
pos3D: intersectInfo.point,
normal: intersectInfo.normal,
direction: intersectInfo.searchRay.direction,
button: "Primary",
isPrimaryButton: true,
isSecondaryButton: false,
isTertiaryButton: false
};
Entities.sendMousePressOnEntity(this.grabbedEntity, pointerEvent);
Entities.sendClickDownOnEntity(this.grabbedEntity, pointerEvent);
};
this.entityTouchingExit = function() {
// test for intersection between controller laser and web entity plane.
var intersectInfo = handLaserIntersectWebEntity(this.grabbedEntity, this.hand);
Entities.sendEntityTouchEndEvent(this.grabbedEntity, this.hand, intersectInfo.point);
var pointerEvent = {
type: "Release",
id: this.hand + 1, // 0 is reserved for hardware mouse
pos2D: projectOntoEntityXYPlane(this.grabbedEntity, intersectInfo.point),
pos3D: intersectInfo.point,
normal: intersectInfo.normal,
direction: intersectInfo.searchRay.direction,
button: "Primary",
isPrimaryButton: true,
isSecondaryButton: false,
isTertiaryButton: false
};
Entities.sendMouseReleaseOnEntity(this.grabbedEntity, pointerEvent);
Entities.sendClickReleaseOnEntity(this.grabbedEntity, pointerEvent);
};
this.entityTouching = function() {
@ -2078,7 +2156,21 @@ function MyController(hand) {
Entities.keyboardFocusEntity = this.grabbedEntity;
}
Entities.sendEntityTouchUpdateEvent(this.grabbedEntity, this.hand, intersectInfo.point);
var pointerEvent = {
type: "Move",
id: this.hand + 1, // 0 is reserved for hardware mouse
pos2D: projectOntoEntityXYPlane(this.grabbedEntity, intersectInfo.point),
pos3D: intersectInfo.point,
normal: intersectInfo.normal,
direction: intersectInfo.searchRay.direction,
button: "NoButtons",
isPrimaryButton: true,
isSecondaryButton: false,
isTertiaryButton: false
};
Entities.sendMouseMoveOnEntity(this.grabbedEntity, pointerEvent);
Entities.sendHoldingClickOnEntity(this.grabbedEntity, pointerEvent);
this.intersectionDistance = intersectInfo.distance;
this.searchIndicatorOn(intersectInfo.searchRay);