lockEnd, editRenderState, and updated grab.js

This commit is contained in:
SamGondelman 2017-07-19 17:45:21 -07:00
parent 912b417dd4
commit bf243d6025
7 changed files with 191 additions and 112 deletions

View file

@ -18,11 +18,12 @@
#include "avatar/AvatarManager.h"
LaserPointer::LaserPointer(const QString& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool enabled) :
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) :
_renderingEnabled(enabled),
_renderStates(renderStates),
_faceAvatar(faceAvatar),
_centerEndY(centerEndY)
_centerEndY(centerEndY),
_lockEnd(lockEnd)
{
_rayPickUID = DependencyManager::get<RayPickManager>()->addRayPick(std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled));
@ -34,11 +35,12 @@ LaserPointer::LaserPointer(const QString& jointName, const glm::vec3& posOffset,
}
LaserPointer::LaserPointer(const glm::vec3& position, const glm::vec3& direction, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool enabled) :
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) :
_renderingEnabled(enabled),
_renderStates(renderStates),
_faceAvatar(faceAvatar),
_centerEndY(centerEndY)
_centerEndY(centerEndY),
_lockEnd(lockEnd)
{
_rayPickUID = DependencyManager::get<RayPickManager>()->addRayPick(std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled));
@ -49,11 +51,13 @@ LaserPointer::LaserPointer(const glm::vec3& position, const glm::vec3& direction
}
}
LaserPointer::LaserPointer(const uint16_t filter, const float maxDistance, const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool enabled) :
LaserPointer::LaserPointer(const uint16_t filter, const float maxDistance, const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY,
const bool lockEnd, const bool enabled) :
_renderingEnabled(enabled),
_renderStates(renderStates),
_faceAvatar(faceAvatar),
_centerEndY(centerEndY)
_centerEndY(centerEndY),
_lockEnd(lockEnd)
{
_rayPickUID = DependencyManager::get<RayPickManager>()->addRayPick(std::make_shared<MouseRayPick>(filter, maxDistance, enabled));
@ -99,6 +103,27 @@ void LaserPointer::setRenderState(const QString& state) {
_currentRenderState = state;
}
void LaserPointer::editRenderState(const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
_renderStates[state].setStartID(updateRenderStateOverlay(_renderStates[state].getStartID(), startProps));
_renderStates[state].setPathID(updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps));
_renderStates[state].setEndID(updateRenderStateOverlay(_renderStates[state].getEndID(), endProps));
}
OverlayID LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& props) {
if (props.isValid()) {
if (!id.isNull()) {
qApp->getOverlays().editOverlay(id, props);
return id;
} else {
QVariantMap propsMap = props.toMap();
if (propsMap["type"].isValid()) {
return qApp->getOverlays().addOverlay(propsMap["type"].toString(), props);
}
}
}
return OverlayID();
}
void LaserPointer::disableRenderState(const QString& renderState) {
if (!_renderStates[renderState].getStartID().isNull()) {
QVariantMap startProps;
@ -131,7 +156,18 @@ void LaserPointer::update() {
startProps.insert("ignoreRayIntersection", _renderStates[_currentRenderState].doesStartIgnoreRays());
qApp->getOverlays().editOverlay(_renderStates[_currentRenderState].getStartID(), startProps);
}
glm::vec3 endVec = pickRay.origin + pickRay.direction * prevRayPickResult.distance;
glm::vec3 endVec;
if (!_lockEnd || prevRayPickResult.type == IntersectionType::HUD) {
endVec = pickRay.origin + pickRay.direction * prevRayPickResult.distance;
} else {
if (prevRayPickResult.type == IntersectionType::ENTITY) {
endVec = DependencyManager::get<EntityScriptingInterface>()->getEntityTransform(prevRayPickResult.objectID)[3];
} else if (prevRayPickResult.type == IntersectionType::OVERLAY) {
endVec = vec3FromVariant(qApp->getOverlays().getProperty(prevRayPickResult.objectID, "position").value);
} else if (prevRayPickResult.type == IntersectionType::AVATAR) {
endVec = DependencyManager::get<AvatarHashMap>()->getAvatar(prevRayPickResult.objectID)->getPosition();
}
}
QVariant end = vec3toVariant(endVec);
if (!_renderStates[_currentRenderState].getPathID().isNull()) {
QVariantMap pathProps;

View file

@ -29,6 +29,9 @@ public:
const OverlayID& getStartID() { return _startID; }
const OverlayID& getPathID() { return _pathID; }
const OverlayID& getEndID() { return _endID; }
void setStartID(const OverlayID& startID) { _startID = startID; }
void setPathID(const OverlayID& pathID) { _pathID = pathID; }
void setEndID(const OverlayID& endID) { _endID = endID; }
const bool& doesStartIgnoreRays() { return _startIgnoreRays; }
const bool& doesPathIgnoreRays() { return _pathIgnoreRays; }
const bool& doesEndIgnoreRays() { return _endIgnoreRays; }
@ -47,11 +50,11 @@ class LaserPointer {
public:
LaserPointer(const QString& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool enabled);
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
LaserPointer(const glm::vec3& position, const glm::vec3& direction, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool enabled);
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
LaserPointer(const uint16_t filter, const float maxDistance, const QHash<QString, RenderState>& renderStates, const bool faceAvatar,
const bool centerEndY, const bool enabled);
const bool centerEndY, const bool lockEnd, const bool enabled);
~LaserPointer();
unsigned int getUID() { return _rayPickUID; }
@ -60,7 +63,7 @@ public:
const RayPickResult getPrevRayPickResult() { return DependencyManager::get<RayPickManager>()->getPrevRayPickResult(_rayPickUID); }
void setRenderState(const QString& state);
void disableRenderState(const QString& renderState);
void editRenderState(const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
void update();
@ -70,8 +73,12 @@ private:
QHash<QString, RenderState> _renderStates;
bool _faceAvatar;
bool _centerEndY;
bool _lockEnd;
unsigned int _rayPickUID;
OverlayID updateRenderStateOverlay(const OverlayID& id, const QVariant& props);
void disableRenderState(const QString& renderState);
};
#endif // hifi_LaserPointer_h

View file

@ -13,23 +13,24 @@
#include "RayPick.h"
unsigned int LaserPointerManager::createLaserPointer(const QString& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(jointName, posOffset, dirOffset, filter, maxDistance, renderStates, faceAvatar, centerEndY, enabled);
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(jointName, posOffset, dirOffset, filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
unsigned int uid = laserPointer->getUID();
_laserPointers[uid] = laserPointer;
return uid;
}
unsigned int LaserPointerManager::createLaserPointer(const glm::vec3& position, const glm::vec3& direction, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(position, direction, filter, maxDistance, renderStates, faceAvatar, centerEndY, enabled);
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(position, direction, filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
unsigned int uid = laserPointer->getUID();
_laserPointers[uid] = laserPointer;
return uid;
}
unsigned int LaserPointerManager::createLaserPointer(const uint16_t filter, const float maxDistance, const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(filter, maxDistance, renderStates, faceAvatar, centerEndY, enabled);
unsigned int LaserPointerManager::createLaserPointer(const uint16_t filter, const float maxDistance, const QHash<QString, RenderState>& renderStates, const bool faceAvatar,
const bool centerEndY, const bool lockEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
unsigned int uid = laserPointer->getUID();
_laserPointers[uid] = laserPointer;
return uid;
@ -53,6 +54,12 @@ void LaserPointerManager::setRenderState(unsigned int uid, const QString & rende
}
}
void LaserPointerManager::editRenderState(unsigned int uid, const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
if (_laserPointers.contains(uid)) {
_laserPointers[uid]->editRenderState(state, startProps, pathProps, endProps);
}
}
const RayPickResult LaserPointerManager::getPrevRayPickResult(const unsigned int uid) {
if (_laserPointers.contains(uid)) {
return _laserPointers[uid]->getPrevRayPickResult();

View file

@ -26,15 +26,16 @@ class LaserPointerManager : public Dependency {
public:
unsigned int createLaserPointer(const QString& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool enabled);
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
unsigned int createLaserPointer(const glm::vec3& position, const glm::vec3& direction, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool enabled);
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
unsigned int createLaserPointer(const uint16_t filter, const float maxDistance, const QHash<QString, RenderState>& renderStates, const bool faceAvatar,
const bool centerEndY, const bool enabled);
const bool centerEndY, const bool lockEnd, const bool enabled);
void removeLaserPointer(const unsigned int uid) { _laserPointers.remove(uid); }
void enableLaserPointer(const unsigned int uid);
void disableLaserPointer(const unsigned int uid);
void setRenderState(unsigned int uid, const QString& renderState);
void editRenderState(unsigned int uid, const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
const RayPickResult getPrevRayPickResult(const unsigned int uid);
void update();

View file

@ -40,6 +40,11 @@ uint32_t LaserPointerScriptingInterface::createLaserPointer(const QVariant& prop
centerEndY = propertyMap["centerEndY"].toBool();
}
bool lockEnd = false;
if (propertyMap["lockEnd"].isValid()) {
lockEnd = propertyMap["lockEnd"].toBool();
}
bool enabled = false;
if (propertyMap["enabled"].isValid()) {
enabled = propertyMap["enabled"].toBool();
@ -53,33 +58,7 @@ uint32_t LaserPointerScriptingInterface::createLaserPointer(const QVariant& prop
QVariantMap renderStateMap = renderStateVariant.toMap();
if (renderStateMap["name"].isValid()) {
QString name = renderStateMap["name"].toString();
QUuid startID;
if (renderStateMap["start"].isValid()) {
QVariantMap startMap = renderStateMap["start"].toMap();
if (startMap["type"].isValid()) {
startID = qApp->getOverlays().addOverlay(startMap["type"].toString(), startMap);
}
}
QUuid pathID;
if (renderStateMap["path"].isValid()) {
QVariantMap pathMap = renderStateMap["path"].toMap();
// right now paths must be line3ds
if (pathMap["type"].isValid() && pathMap["type"].toString() == "line3d") {
pathID = qApp->getOverlays().addOverlay(pathMap["type"].toString(), pathMap);
}
}
QUuid endID;
if (renderStateMap["end"].isValid()) {
QVariantMap endMap = renderStateMap["end"].toMap();
if (endMap["type"].isValid()) {
endID = qApp->getOverlays().addOverlay(endMap["type"].toString(), endMap);
}
}
renderStates[name] = RenderState(startID, pathID, endID);
renderStates[name] = buildRenderState(renderStateMap);
}
}
}
@ -100,9 +79,9 @@ uint32_t LaserPointerScriptingInterface::createLaserPointer(const QVariant& prop
dirOffset = vec3FromVariant(propertyMap["dirOffset"]);
}
return DependencyManager::get<LaserPointerManager>()->createLaserPointer(jointName, posOffset, dirOffset, filter, maxDistance, renderStates, faceAvatar, centerEndY, enabled);
return DependencyManager::get<LaserPointerManager>()->createLaserPointer(jointName, posOffset, dirOffset, filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
} else {
return DependencyManager::get<LaserPointerManager>()->createLaserPointer(filter, maxDistance, renderStates, faceAvatar, centerEndY, enabled);
return DependencyManager::get<LaserPointerManager>()->createLaserPointer(filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
}
} else if (propertyMap["position"].isValid()) {
glm::vec3 position = vec3FromVariant(propertyMap["position"]);
@ -112,8 +91,58 @@ uint32_t LaserPointerScriptingInterface::createLaserPointer(const QVariant& prop
direction = vec3FromVariant(propertyMap["direction"]);
}
return DependencyManager::get<LaserPointerManager>()->createLaserPointer(position, direction, filter, maxDistance, renderStates, faceAvatar, centerEndY, enabled);
return DependencyManager::get<LaserPointerManager>()->createLaserPointer(position, direction, filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
}
return 0;
}
void LaserPointerScriptingInterface::editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) {
QVariantMap propMap = properties.toMap();
QVariant startProps;
if (propMap["start"].isValid()) {
startProps = propMap["start"];
}
QVariant pathProps;
if (propMap["path"].isValid()) {
pathProps = propMap["path"];
}
QVariant endProps;
if (propMap["end"].isValid()) {
endProps = propMap["end"];
}
DependencyManager::get<LaserPointerManager>()->editRenderState(uid, renderState, startProps, pathProps, endProps);
}
const RenderState LaserPointerScriptingInterface::buildRenderState(const QVariantMap& propMap) {
QUuid startID;
if (propMap["start"].isValid()) {
QVariantMap startMap = propMap["start"].toMap();
if (startMap["type"].isValid()) {
startID = qApp->getOverlays().addOverlay(startMap["type"].toString(), startMap);
}
}
QUuid pathID;
if (propMap["path"].isValid()) {
QVariantMap pathMap = propMap["path"].toMap();
// right now paths must be line3ds
if (pathMap["type"].isValid() && pathMap["type"].toString() == "line3d") {
pathID = qApp->getOverlays().addOverlay(pathMap["type"].toString(), pathMap);
}
}
QUuid endID;
if (propMap["end"].isValid()) {
QVariantMap endMap = propMap["end"].toMap();
if (endMap["type"].isValid()) {
endID = qApp->getOverlays().addOverlay(endMap["type"].toString(), endMap);
}
}
return RenderState(startID, pathID, endID);
}

View file

@ -26,9 +26,13 @@ public slots:
Q_INVOKABLE void enableLaserPointer(unsigned int uid) { DependencyManager::get<LaserPointerManager>()->enableLaserPointer(uid); }
Q_INVOKABLE void disableLaserPointer(unsigned int uid) { DependencyManager::get<LaserPointerManager>()->disableLaserPointer(uid); }
Q_INVOKABLE void removeLaserPointer(unsigned int uid) { DependencyManager::get<LaserPointerManager>()->removeLaserPointer(uid); }
Q_INVOKABLE void editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties);
Q_INVOKABLE void setRenderState(unsigned int uid, const QString& renderState) { DependencyManager::get<LaserPointerManager>()->setRenderState(uid, renderState); }
Q_INVOKABLE RayPickResult getPrevRayPickResult(unsigned int uid) { return DependencyManager::get<LaserPointerManager>()->getPrevRayPickResult(uid); }
private:
const RenderState buildRenderState(const QVariantMap & propMap);
};
#endif // hifi_LaserPointerScriptingInterface_h

View file

@ -197,53 +197,24 @@ Mouse.prototype.restoreRotateCursor = function() {
var mouse = new Mouse();
// Beacon class stores info for drawing a line at object's target position
function Beacon() {
this.height = 0.10;
this.overlayID = Overlays.addOverlay("line3d", {
color: {
red: 200,
green: 200,
blue: 200
},
alpha: 1,
visible: false,
lineWidth: 2
});
}
Beacon.prototype.enable = function() {
Overlays.editOverlay(this.overlayID, {
visible: true
});
var beacon = {
type: "cube",
dimensions: {
x: 0.01,
y: 0,
z: 0.01
},
color: {
red: 200,
green: 200,
blue: 200
},
alpha: 1,
solid: true,
ignoreRayIntersection: true,
visible: true
};
Beacon.prototype.disable = function() {
Overlays.editOverlay(this.overlayID, {
visible: false
});
};
Beacon.prototype.updatePosition = function(position) {
Overlays.editOverlay(this.overlayID, {
visible: true,
start: {
x: position.x,
y: position.y + this.height,
z: position.z
},
end: {
x: position.x,
y: position.y - this.height,
z: position.z
}
});
};
var beacon = new Beacon();
// TODO: play sounds again when we aren't leaking AudioInjector threads
// var grabSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/eric/sounds/CloseClamp.wav");
// var releaseSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/eric/sounds/ReleaseClamp.wav");
@ -285,6 +256,19 @@ function Grabber() {
this.liftKey = false; // SHIFT
this.rotateKey = false; // CONTROL
this.mouseRayOverlays = LaserPointers.createLaserPointer({
joint: "Mouse",
filter: RayPick.PICK_OVERLAYS,
enabled: true
});
this.mouseRayEntities = LaserPointers.createLaserPointer({
joint: "Mouse",
filter: RayPick.PICK_ENTITIES,
lockEnd: true,
faceAvatar: true,
enabled: true
});
}
Grabber.prototype.computeNewGrabPlane = function() {
@ -333,40 +317,43 @@ Grabber.prototype.pressEvent = function(event) {
return;
}
var pickRay = Camera.computePickRay(event.x, event.y);
var overlayResult = LaserPointers.getPrevRayPickResult(this.mouseRayOverlays);
if (overlayResult.type != RayPick.INTERSECTED_NONE) {
if (overlayResult.objectID == HMD.tabletID || overlayResult.objectID == HMD.tabletScreenID || overlayResult.objectID == HMD.homeButtonID) {
return;
}
}
var overlayResult = Overlays.findRayIntersection(pickRay, true, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]);
if (overlayResult.intersects) {
var pickResults = LaserPointers.getPrevRayPickResult(this.mouseRayEntities);
if (pickResults.type == RayPick.INTERSECTED_NONE) {
LaserPointers.setRenderState(this.mouseRayEntities, "");
return;
}
var pickResults = Entities.findRayIntersection(pickRay, true); // accurate picking
if (!pickResults.intersects) {
// didn't click on anything
return;
}
var isDynamic = Entities.getEntityProperties(pickResults.entityID, "dynamic").dynamic;
var isDynamic = Entities.getEntityProperties(pickResults.objectID, "dynamic").dynamic;
if (!isDynamic) {
// only grab dynamic objects
return;
}
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, pickResults.entityID, DEFAULT_GRABBABLE_DATA);
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, pickResults.objectID, DEFAULT_GRABBABLE_DATA);
if (grabbableData.grabbable === false) {
return;
}
LaserPointers.setRenderState(this.mouseRayEntities, "grabbed");
mouse.startDrag(event);
var clickedEntity = pickResults.entityID;
var clickedEntity = pickResults.objectID;
var entityProperties = Entities.getEntityProperties(clickedEntity);
this.startPosition = entityProperties.position;
this.lastRotation = entityProperties.rotation;
var cameraPosition = Camera.getPosition();
var objectBoundingDiameter = Vec3.length(entityProperties.dimensions);
beacon.height = objectBoundingDiameter;
beacon.dimensions.y = objectBoundingDiameter;
LaserPointers.editRenderState(this.mouseRayEntities, "grabbed", {end: beacon});
this.maxDistance = objectBoundingDiameter / MAX_SOLID_ANGLE;
if (Vec3.distance(this.startPosition, cameraPosition) > this.maxDistance) {
// don't allow grabs of things far away
@ -385,6 +372,7 @@ Grabber.prototype.pressEvent = function(event) {
};
// compute the grab point
var pickRay = Camera.computePickRay(event.x, event.y);
var nearestPoint = Vec3.subtract(this.startPosition, cameraPosition);
var distanceToGrab = Vec3.dot(nearestPoint, pickRay.direction);
nearestPoint = Vec3.multiply(distanceToGrab, pickRay.direction);
@ -395,8 +383,6 @@ Grabber.prototype.pressEvent = function(event) {
this.computeNewGrabPlane();
beacon.updatePosition(this.startPosition);
if (!entityIsGrabbedByOther(this.entityID)) {
this.moveEvent(event);
}
@ -431,7 +417,7 @@ Grabber.prototype.releaseEvent = function(event) {
}
this.actionID = null;
beacon.disable();
LaserPointers.setRenderState(this.mouseRayEntities, "");
var args = "mouse";
Entities.callEntityMethod(this.entityID, "releaseGrab", args);
@ -552,7 +538,6 @@ Grabber.prototype.moveEventProcess = function() {
ttl: ACTION_TTL
};
beacon.updatePosition(this.targetPosition);
}
if (!this.actionID) {
@ -586,6 +571,11 @@ Grabber.prototype.keyPressEvent = function(event) {
this.computeNewGrabPlane();
};
Grabber.prototype.cleanup = function() {
LaserPointers.removeLaserPointer(this.mouseRayEntities);
LaserPointers.removeLaserPointer(this.mouseRayOverlays);
};
var grabber = new Grabber();
function pressEvent(event) {
@ -608,10 +598,15 @@ function keyReleaseEvent(event) {
grabber.keyReleaseEvent(event);
}
function cleanup() {
grabber.cleanup();
}
Controller.mousePressEvent.connect(pressEvent);
Controller.mouseMoveEvent.connect(moveEvent);
Controller.mouseReleaseEvent.connect(releaseEvent);
Controller.keyPressEvent.connect(keyPressEvent);
Controller.keyReleaseEvent.connect(keyReleaseEvent);
Script.scriptEnding.connect(cleanup);
}()); // END LOCAL_SCOPE