mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 14:29:03 +02:00
code cleanup and fix broken features
This commit is contained in:
parent
47699d4439
commit
7cf27c18d3
10 changed files with 316 additions and 351 deletions
|
@ -54,7 +54,10 @@ module.exports = {
|
||||||
"Window": false,
|
"Window": false,
|
||||||
"XMLHttpRequest": false,
|
"XMLHttpRequest": false,
|
||||||
"location": false,
|
"location": false,
|
||||||
"print": false
|
"print": false,
|
||||||
|
"RayPick": false,
|
||||||
|
"LaserPointers": false,
|
||||||
|
"ContextOverlay": false
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"brace-style": ["error", "1tbs", { "allowSingleLine": false }],
|
"brace-style": ["error", "1tbs", { "allowSingleLine": false }],
|
||||||
|
|
|
@ -34,6 +34,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
var highVarianceCount = 0;
|
var highVarianceCount = 0;
|
||||||
var veryhighVarianceCount = 0;
|
var veryhighVarianceCount = 0;
|
||||||
this.tabletID = null;
|
this.tabletID = null;
|
||||||
|
this.blacklist = [];
|
||||||
|
|
||||||
// a module can occupy one or more "activity" slots while it's running. If all the required slots for a module are
|
// a module can occupy one or more "activity" slots while it's running. If all the required slots for a module are
|
||||||
// not set to false (not in use), a module cannot start. When a module is using a slot, that module's name
|
// not set to false (not in use), a module cannot start. When a module is using a slot, that module's name
|
||||||
|
@ -293,6 +294,12 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.setBlacklist = function() {
|
||||||
|
RayPick.setIgnoreEntities(_this.leftControllerRayPick, this.blacklist);
|
||||||
|
RayPick.setIgnoreEntities(_this.rightControllerRayPick, this.blacklist);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
var MAPPING_NAME = "com.highfidelity.controllerDispatcher";
|
var MAPPING_NAME = "com.highfidelity.controllerDispatcher";
|
||||||
var mapping = Controller.newMapping(MAPPING_NAME);
|
var mapping = Controller.newMapping(MAPPING_NAME);
|
||||||
mapping.from([Controller.Standard.RT]).peek().to(_this.rightTriggerPress);
|
mapping.from([Controller.Standard.RT]).peek().to(_this.rightTriggerPress);
|
||||||
|
@ -324,27 +331,60 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
joint: "_CONTROLLER_LEFTHAND",
|
joint: "_CONTROLLER_LEFTHAND",
|
||||||
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE
|
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
|
||||||
|
posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand)
|
||||||
});
|
});
|
||||||
this.leftControllerHudRayPick = RayPick.createRayPick({
|
this.leftControllerHudRayPick = RayPick.createRayPick({
|
||||||
joint: "_CONTROLLER_LEFTHAND",
|
joint: "_CONTROLLER_LEFTHAND",
|
||||||
filter: RayPick.PICK_HUD,
|
filter: RayPick.PICK_HUD,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE
|
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
|
||||||
|
posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand)
|
||||||
});
|
});
|
||||||
this.rightControllerRayPick = RayPick.createRayPick({
|
this.rightControllerRayPick = RayPick.createRayPick({
|
||||||
joint: "_CONTROLLER_RIGHTHAND",
|
joint: "_CONTROLLER_RIGHTHAND",
|
||||||
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE
|
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
|
||||||
|
posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand)
|
||||||
});
|
});
|
||||||
this.rightControllerHudRayPick = RayPick.createRayPick({
|
this.rightControllerHudRayPick = RayPick.createRayPick({
|
||||||
joint: "_CONTROLLER_RIGHTHAND",
|
joint: "_CONTROLLER_RIGHTHAND",
|
||||||
filter: RayPick.PICK_HUD,
|
filter: RayPick.PICK_HUD,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE
|
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
|
||||||
|
posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.handleHandMessage = function(channel, message, sender) {
|
||||||
|
var data
|
||||||
|
if (sender === MyAvatar.sessionUUID) {
|
||||||
|
try {
|
||||||
|
if (channel === 'Hifi-Hand-RayPick-Blacklist') {
|
||||||
|
data = JSON.parse(message);
|
||||||
|
var action = data.action;
|
||||||
|
var id = data.id;
|
||||||
|
var index = this.blacklis.indexOf(id);
|
||||||
|
|
||||||
|
if (action === 'add' && index === -1) {
|
||||||
|
this.blacklist.push(id);
|
||||||
|
//this.setBlacklist();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === 'remove') {
|
||||||
|
if (index > -1) {
|
||||||
|
blacklist.splice(index, 1);
|
||||||
|
//this.setBlacklist();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
print("WARNING: handControllerGrab.js -- error parsing Hifi-Hand-RayPick-Blacklist message: " + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -357,7 +397,8 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
RayPick.removeRayPick(_this.rightControllerHudRayPick);
|
RayPick.removeRayPick(_this.rightControllerHudRayPick);
|
||||||
RayPick.removeRayPick(_this.leftControllerHudRayPick);
|
RayPick.removeRayPick(_this.leftControllerHudRayPick);
|
||||||
};
|
};
|
||||||
|
Messages.subscribe('Hifi-Hand-RayPick-Blacklist');
|
||||||
|
Messages.messageReceived.connect(this.handleHandMessage);
|
||||||
Script.scriptEnding.connect(this.cleanup);
|
Script.scriptEnding.connect(this.cleanup);
|
||||||
Script.update.connect(this.update);
|
Script.update.connect(this.update);
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// cloneEntity.js
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
|
|
||||||
|
|
||||||
/* global Script, Entities, RIGHT_HAND, LEFT_HAND,
|
|
||||||
enableDispatcherModule, disableDispatcherModule, getGrabbableData, Vec3,
|
|
||||||
TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS
|
|
||||||
*/
|
|
||||||
|
|
||||||
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|
||||||
|
|
||||||
// Object assign polyfill
|
|
||||||
if (typeof Object.assign != 'function') {
|
|
||||||
Object.assign = function(target, varArgs) {
|
|
||||||
if (target === null) {
|
|
||||||
throw new TypeError('Cannot convert undefined or null to object');
|
|
||||||
}
|
|
||||||
var to = Object(target);
|
|
||||||
for (var index = 1; index < arguments.length; index++) {
|
|
||||||
var nextSource = arguments[index];
|
|
||||||
if (nextSource !== null) {
|
|
||||||
for (var nextKey in nextSource) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
|
||||||
to[nextKey] = nextSource[nextKey];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return to;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
function entityIsCloneable(props) {
|
|
||||||
var grabbableData = getGrabbableData(props);
|
|
||||||
return grabbableData.cloneable;
|
|
||||||
}
|
|
||||||
|
|
||||||
function CloneEntity(hand) {
|
|
||||||
this.hand = hand;
|
|
||||||
this.grabbing = false;
|
|
||||||
this.previousParentID = {};
|
|
||||||
this.previousParentJointIndex = {};
|
|
||||||
this.previouslyUnhooked = {};
|
|
||||||
|
|
||||||
this.parameters = makeDispatcherModuleParameters(
|
|
||||||
300,
|
|
||||||
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
|
|
||||||
[],
|
|
||||||
100);
|
|
||||||
|
|
||||||
this.getTargetProps = function (controllerData) {
|
|
||||||
// nearbyEntityProperties is already sorted by length from controller
|
|
||||||
var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand];
|
|
||||||
for (var i = 0; i < nearbyEntityProperties.length; i++) {
|
|
||||||
var props = nearbyEntityProperties[i];
|
|
||||||
var handPosition = controllerData.controllerLocations[this.hand].position;
|
|
||||||
var distance = Vec3.distance(props.position, handPosition);
|
|
||||||
if (distance > NEAR_GRAB_RADIUS) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (entityIsCloneable(props)) {
|
|
||||||
return props;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.isReady = function (controllerData) {
|
|
||||||
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) {
|
|
||||||
this.waiting = false;
|
|
||||||
return makeRunningValues(false, [], []);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) {
|
|
||||||
if (!this.waiting) {
|
|
||||||
this.waiting = true;
|
|
||||||
return makeRunningValues(true, [], []);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return makeRunningValues(false, [], []);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.run = function (controllerData, deltaTime) {
|
|
||||||
var cloneableProps = this.getTargetProps(controllerData);
|
|
||||||
if (!cloneableProps) {
|
|
||||||
return makeRunningValues(false, [], []);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need all the properties, for this
|
|
||||||
cloneableProps = Entities.getEntityProperties(cloneableProps.id);
|
|
||||||
|
|
||||||
var worldEntityProps = controllerData.nearbyEntityProperties[this.hand];
|
|
||||||
var count = 0;
|
|
||||||
worldEntityProps.forEach(function(itemWE) {
|
|
||||||
if (itemWE.name.indexOf('-clone-' + cloneableProps.id) !== -1) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var grabInfo = getGrabbableData(cloneableProps);
|
|
||||||
|
|
||||||
var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 0;
|
|
||||||
if (count >= limit && limit !== 0) {
|
|
||||||
return makeRunningValues(false, [], []);
|
|
||||||
}
|
|
||||||
|
|
||||||
cloneableProps.name = cloneableProps.name + '-clone-' + cloneableProps.id;
|
|
||||||
var lifetime = grabInfo.cloneLifetime ? grabInfo.cloneLifetime : 300;
|
|
||||||
var dynamic = grabInfo.cloneDynamic ? grabInfo.cloneDynamic : false;
|
|
||||||
var cUserData = Object.assign({}, cloneableProps.userData);
|
|
||||||
var cProperties = Object.assign({}, cloneableProps);
|
|
||||||
|
|
||||||
try {
|
|
||||||
delete cUserData.grabbableKey.cloneLifetime;
|
|
||||||
delete cUserData.grabbableKey.cloneable;
|
|
||||||
delete cUserData.grabbableKey.cloneDynamic;
|
|
||||||
delete cUserData.grabbableKey.cloneLimit;
|
|
||||||
delete cProperties.id;
|
|
||||||
} catch(e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
cProperties.dynamic = dynamic;
|
|
||||||
cProperties.locked = false;
|
|
||||||
if (!cUserData.grabbableKey) {
|
|
||||||
cUserData.grabbableKey = {};
|
|
||||||
}
|
|
||||||
cUserData.grabbableKey.triggerable = true;
|
|
||||||
cUserData.grabbableKey.grabbable = true;
|
|
||||||
cProperties.lifetime = lifetime;
|
|
||||||
cProperties.userData = JSON.stringify(cUserData);
|
|
||||||
// var cloneID =
|
|
||||||
Entities.addEntity(cProperties);
|
|
||||||
return makeRunningValues(false, [], []);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.cleanup = function () {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var leftCloneEntity = new CloneEntity(LEFT_HAND);
|
|
||||||
var rightCloneEntity = new CloneEntity(RIGHT_HAND);
|
|
||||||
|
|
||||||
enableDispatcherModule("LeftCloneEntity", leftCloneEntity);
|
|
||||||
enableDispatcherModule("RightCloneEntity", rightCloneEntity);
|
|
||||||
|
|
||||||
this.cleanup = function () {
|
|
||||||
leftNearParentingGrabEntity.cleanup();
|
|
||||||
rightNearParentingGrabEntity.cleanup();
|
|
||||||
disableDispatcherModule("LeftNearParentingGrabEntity");
|
|
||||||
disableDispatcherModule("RightNearParentingGrabEntity");
|
|
||||||
};
|
|
||||||
Script.scriptEnding.connect(this.cleanup);
|
|
||||||
}());
|
|
|
@ -9,7 +9,8 @@
|
||||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID,
|
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID,
|
||||||
getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
|
getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
|
||||||
Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions,
|
Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions,
|
||||||
Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic
|
Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable,
|
||||||
|
cloneEntity
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Script.include("/~/system/libraries/Xform.js");
|
Script.include("/~/system/libraries/Xform.js");
|
||||||
|
@ -105,14 +106,14 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
var overlayInfoSet = this.map[keys[i]];
|
var overlayInfoSet = this.map[keys[i]];
|
||||||
|
|
||||||
// this overlayInfo is highlighted.
|
// this overlayInfo is highlighted.
|
||||||
if (this.highlightedHotspots.indexOf(keys[i]) != -1) {
|
if (this.highlightedHotspots.indexOf(keys[i]) !== -1) {
|
||||||
overlayInfoSet.targetSize = HIGHLIGHT_SIZE;
|
overlayInfoSet.targetSize = HIGHLIGHT_SIZE;
|
||||||
} else {
|
} else {
|
||||||
overlayInfoSet.targetSize = NORMAL_SIZE;
|
overlayInfoSet.targetSize = NORMAL_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start to fade out this hotspot.
|
// start to fade out this hotspot.
|
||||||
if (overlayInfoSet.timestamp != timestamp) {
|
if (overlayInfoSet.timestamp !== timestamp) {
|
||||||
overlayInfoSet.targetSize = 0;
|
overlayInfoSet.targetSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +125,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
}
|
}
|
||||||
overlayInfoSet.currentSize += (overlayInfoSet.targetSize - overlayInfoSet.currentSize) * tau;
|
overlayInfoSet.currentSize += (overlayInfoSet.targetSize - overlayInfoSet.currentSize) * tau;
|
||||||
|
|
||||||
if (overlayInfoSet.timestamp != timestamp && overlayInfoSet.currentSize <= 0.05) {
|
if (overlayInfoSet.timestamp !== timestamp && overlayInfoSet.currentSize <= 0.05) {
|
||||||
// this is an old overlay, that has finished fading out, delete it!
|
// this is an old overlay, that has finished fading out, delete it!
|
||||||
overlayInfoSet.overlays.forEach(Overlays.deleteOverlay);
|
overlayInfoSet.overlays.forEach(Overlays.deleteOverlay);
|
||||||
delete this.map[keys[i]];
|
delete this.map[keys[i]];
|
||||||
|
@ -136,7 +137,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
var position = entityXform.xformPoint(overlayInfoSet.localPosition);
|
var position = entityXform.xformPoint(overlayInfoSet.localPosition);
|
||||||
|
|
||||||
var dimensions;
|
var dimensions;
|
||||||
if (overlayInfoSet.type == "sphere") {
|
if (overlayInfoSet.type === "sphere") {
|
||||||
dimensions = overlayInfoSet.hotspot.radius * 2 * overlayInfoSet.currentSize * EQUIP_SPHERE_SCALE_FACTOR;
|
dimensions = overlayInfoSet.hotspot.radius * 2 * overlayInfoSet.currentSize * EQUIP_SPHERE_SCALE_FACTOR;
|
||||||
} else {
|
} else {
|
||||||
dimensions = overlayInfoSet.hotspot.radius * 2 * overlayInfoSet.currentSize;
|
dimensions = overlayInfoSet.hotspot.radius * 2 * overlayInfoSet.currentSize;
|
||||||
|
@ -157,8 +158,6 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var ATTACH_POINT_SETTINGS = "io.highfidelity.attachPoints";
|
var ATTACH_POINT_SETTINGS = "io.highfidelity.attachPoints";
|
||||||
|
@ -185,6 +184,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
if (!props.userDataParsed) {
|
if (!props.userDataParsed) {
|
||||||
props.userDataParsed = JSON.parse(props.userData);
|
props.userDataParsed = JSON.parse(props.userData);
|
||||||
}
|
}
|
||||||
|
|
||||||
wearable = props.userDataParsed.wearable ? props.userDataParsed.wearable : {};
|
wearable = props.userDataParsed.wearable ? props.userDataParsed.wearable : {};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
}
|
}
|
||||||
|
@ -196,6 +196,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
if (!props.userDataParsed) {
|
if (!props.userDataParsed) {
|
||||||
props.userDataParsed = JSON.parse(props.userData);
|
props.userDataParsed = JSON.parse(props.userData);
|
||||||
}
|
}
|
||||||
|
|
||||||
equipHotspots = props.userDataParsed.equipHotspots ? props.userDataParsed.equipHotspots : [];
|
equipHotspots = props.userDataParsed.equipHotspots ? props.userDataParsed.equipHotspots : [];
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
}
|
}
|
||||||
|
@ -249,6 +250,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
this.targetEntityID = null;
|
this.targetEntityID = null;
|
||||||
this.prevHandIsUpsideDown = false;
|
this.prevHandIsUpsideDown = false;
|
||||||
this.triggerValue = 0;
|
this.triggerValue = 0;
|
||||||
|
this.messageGrabEntity = false;
|
||||||
|
this.grabEntityProps = null;
|
||||||
|
|
||||||
this.parameters = makeDispatcherModuleParameters(
|
this.parameters = makeDispatcherModuleParameters(
|
||||||
300,
|
300,
|
||||||
|
@ -258,6 +261,13 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
|
|
||||||
var equipHotspotBuddy = new EquipHotspotBuddy();
|
var equipHotspotBuddy = new EquipHotspotBuddy();
|
||||||
|
|
||||||
|
this.setMessageGrabData = function(entityProperties) {
|
||||||
|
if (entityProperties) {
|
||||||
|
this.messageGrabEntity = true;
|
||||||
|
this.grabEntityProps = entityProperties;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// returns a list of all equip-hotspots assosiated with this entity.
|
// returns a list of all equip-hotspots assosiated with this entity.
|
||||||
// @param {UUID} entityID
|
// @param {UUID} entityID
|
||||||
// @returns {Object[]} array of objects with the following fields.
|
// @returns {Object[]} array of objects with the following fields.
|
||||||
|
@ -322,7 +332,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
if (props.parentID === NULL_UUID) {
|
if (props.parentID === NULL_UUID) {
|
||||||
hasParent = false;
|
hasParent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParent || entityHasActions(hotspot.entityID)) {
|
if (hasParent || entityHasActions(hotspot.entityID)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -376,7 +386,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
if (entityIsCloneable(props)) {
|
if (entityIsCloneable(props)) {
|
||||||
var worldEntityProps = controllerData.nearbyEntityProperties[this.hand];
|
var worldEntityProps = controllerData.nearbyEntityProperties[this.hand];
|
||||||
var cloneID = cloneEntity(props, worldEntityProps);
|
var cloneID = cloneEntity(props, worldEntityProps);
|
||||||
return cloneID
|
return cloneID;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -420,7 +430,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
handIsUpsideDown = true;
|
handIsUpsideDown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handIsUpsideDown != this.prevHandIsUpsideDown) {
|
if (handIsUpsideDown !== this.prevHandIsUpsideDown) {
|
||||||
this.prevHandIsUpsideDown = handIsUpsideDown;
|
this.prevHandIsUpsideDown = handIsUpsideDown;
|
||||||
Controller.triggerHapticPulse(HAPTIC_DEQUIP_STRENGTH, HAPTIC_DEQUIP_DURATION, this.hand);
|
Controller.triggerHapticPulse(HAPTIC_DEQUIP_STRENGTH, HAPTIC_DEQUIP_DURATION, this.hand);
|
||||||
}
|
}
|
||||||
|
@ -486,7 +496,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
this.targetEntityID = cloneID;
|
this.targetEntityID = cloneID;
|
||||||
Entities.editEntity(this.targetEntityID, reparentProps);
|
Entities.editEntity(this.targetEntityID, reparentProps);
|
||||||
isClone = true;
|
isClone = true;
|
||||||
} else if (!grabbedProperties.locked) {
|
} else if (!grabbedProperties.locked) {
|
||||||
Entities.editEntity(this.targetEntityID, reparentProps);
|
Entities.editEntity(this.targetEntityID, reparentProps);
|
||||||
} else {
|
} else {
|
||||||
this.grabbedHotspot = null;
|
this.grabbedHotspot = null;
|
||||||
|
@ -508,12 +518,12 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
var args = [_this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
|
var args = [_this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
|
||||||
Entities.callEntityMethod(_this.targetEntityID, "startEquip", args);
|
Entities.callEntityMethod(_this.targetEntityID, "startEquip", args);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isClone) {
|
if (isClone) {
|
||||||
// 100 ms seems to be sufficient time to force the check even occur after the object has been initialized.
|
// 100 ms seems to be sufficient time to force the check even occur after the object has been initialized.
|
||||||
Script.setTimeout(grabEquipCheck, 100);
|
Script.setTimeout(grabEquipCheck, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.endEquipEntity = function () {
|
this.endEquipEntity = function () {
|
||||||
|
@ -546,8 +556,18 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
var controllerLocation = getControllerWorldLocation(this.handToController(), true);
|
var controllerLocation = getControllerWorldLocation(this.handToController(), true);
|
||||||
var worldHandPosition = controllerLocation.position;
|
var worldHandPosition = controllerLocation.position;
|
||||||
var candidateEntityProps = controllerData.nearbyEntityProperties[this.hand];
|
var candidateEntityProps = controllerData.nearbyEntityProperties[this.hand];
|
||||||
|
|
||||||
var potentialEquipHotspot = this.chooseBestEquipHotspot(candidateEntityProps, controllerData);
|
|
||||||
|
var potentialEquipHotspot = null;
|
||||||
|
if (this.messageGrabEntity) {
|
||||||
|
var hotspots = this.collectEquipHotspots(this.grabEntityProps);
|
||||||
|
if (hotspots.length > -1) {
|
||||||
|
potentialEquipHotspot = hotspots[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
potentialEquipHotspot = this.chooseBestEquipHotspot(candidateEntityProps, controllerData);
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.waitForTriggerRelease) {
|
if (!this.waitForTriggerRelease) {
|
||||||
this.updateEquipHaptics(potentialEquipHotspot, worldHandPosition);
|
this.updateEquipHaptics(potentialEquipHotspot, worldHandPosition);
|
||||||
}
|
}
|
||||||
|
@ -560,17 +580,19 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
|
|
||||||
equipHotspotBuddy.update(deltaTime, timestamp, controllerData);
|
equipHotspotBuddy.update(deltaTime, timestamp, controllerData);
|
||||||
|
|
||||||
//if the potentialHotspot is cloneable, clone it and return it
|
// if the potentialHotspot is cloneable, clone it and return it
|
||||||
// if the potentialHotspot os not cloneable and locked return null
|
// if the potentialHotspot os not cloneable and locked return null
|
||||||
|
|
||||||
if (potentialEquipHotspot) {
|
if (potentialEquipHotspot) {
|
||||||
if (this.triggerSmoothedSqueezed() && !this.waitForTriggerRelease) {
|
if ((this.triggerSmoothedSqueezed() && !this.waitForTriggerRelease) || this.messageGrabEntity) {
|
||||||
this.grabbedHotspot = potentialEquipHotspot;
|
this.grabbedHotspot = potentialEquipHotspot;
|
||||||
this.targetEntityID = this.grabbedHotspot.entityID;
|
this.targetEntityID = this.grabbedHotspot.entityID;
|
||||||
this.startEquipEntity(controllerData);
|
this.startEquipEntity(controllerData);
|
||||||
|
this.messageGrabEnity = false;
|
||||||
}
|
}
|
||||||
return makeRunningValues(true, [potentialEquipHotspot.entityID], []);
|
return makeRunningValues(true, [potentialEquipHotspot.entityID], []);
|
||||||
} else {
|
} else {
|
||||||
|
this.messageGrabEnity = false;
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -610,7 +632,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
this.waitForTriggerRelease = false;
|
this.waitForTriggerRelease = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dropDetected && this.prevDropDetected != dropDetected) {
|
if (dropDetected && this.prevDropDetected !== dropDetected) {
|
||||||
this.waitForTriggerRelease = true;
|
this.waitForTriggerRelease = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,7 +649,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
var prefprops = Entities.getEntityProperties(this.targetEntityID, ["localPosition", "localRotation"]);
|
var prefprops = Entities.getEntityProperties(this.targetEntityID, ["localPosition", "localRotation"]);
|
||||||
if (prefprops && prefprops.localPosition && prefprops.localRotation) {
|
if (prefprops && prefprops.localPosition && prefprops.localRotation) {
|
||||||
storeAttachPointForHotspotInSettings(this.grabbedHotspot, this.hand,
|
storeAttachPointForHotspotInSettings(this.grabbedHotspot, this.hand,
|
||||||
prefprops.localPosition, prefprops.localRotation);
|
prefprops.localPosition, prefprops.localRotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,6 +673,40 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var handleMessage = function(channel, message, sender) {
|
||||||
|
var data;
|
||||||
|
print(channel);
|
||||||
|
if (sender === MyAvatar.sessionUUID) {
|
||||||
|
if (channel === 'Hifi-Hand-Grab') {
|
||||||
|
try {
|
||||||
|
data = JSON.parse(message);
|
||||||
|
var equipModule = (data.hand === 'left') ? leftEquipEntity : rightEquipEntity;
|
||||||
|
var entityProperties = Entities.getEntityProperties(data.entityID, DISPATCHER_PROPERTIES);
|
||||||
|
entityProperties.id = data.entityID;
|
||||||
|
equipModule.setMessageGrabData(entityProperties);
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
print("WARNING: equipEntity.js -- error parsing Hifi-Hand-Grab message: " + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channel === 'Hifi-Hand-Drop') {
|
||||||
|
data = JSON.parse(message);
|
||||||
|
if (data.hand === 'left') {
|
||||||
|
leftEquipEntity.endEquipEntity();
|
||||||
|
} else if (data.hand === 'right') {
|
||||||
|
rightEquipEntity.endEquipEntity();
|
||||||
|
} else if (data.hand === 'both') {
|
||||||
|
leftEquipEntity.endEquipEntity();
|
||||||
|
rightEquipEntity.endEquipEntity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Messages.subscribe('Hifi-Hand-Grab');
|
||||||
|
Messages.subscribe('Hifi-Hand-Drop');
|
||||||
|
Messages.messageReceived.connect(handleMessage);
|
||||||
|
|
||||||
var leftEquipEntity = new EquipEntity(LEFT_HAND);
|
var leftEquipEntity = new EquipEntity(LEFT_HAND);
|
||||||
var rightEquipEntity = new EquipEntity(RIGHT_HAND);
|
var rightEquipEntity = new EquipEntity(RIGHT_HAND);
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,15 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
/*jslint bitwise: true */
|
/* jslint bitwise: true */
|
||||||
|
|
||||||
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat,
|
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat,
|
||||||
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID,
|
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID,
|
||||||
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable,
|
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable,
|
||||||
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
||||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||||
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE,
|
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
|
||||||
|
getControllerWorldLocation, projectOntoEntityXYPlane
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -77,14 +78,18 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
drawInFront: true, // Even when burried inside of something, show it.
|
drawInFront: true, // Even when burried inside of something, show it.
|
||||||
parentID: AVATAR_SELF_ID
|
parentID: AVATAR_SELF_ID
|
||||||
};
|
};
|
||||||
|
|
||||||
var renderStates = [{name: "half", path: halfPath, end: halfEnd},
|
|
||||||
{name: "full", path: fullPath, end: fullEnd},
|
|
||||||
{name: "hold", path: holdPath}];
|
|
||||||
|
|
||||||
var defaultRenderStates = [{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath},
|
var renderStates = [
|
||||||
{name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath},
|
{name: "half", path: halfPath, end: halfEnd},
|
||||||
{name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}];
|
{name: "full", path: fullPath, end: fullEnd},
|
||||||
|
{name: "hold", path: holdPath}
|
||||||
|
];
|
||||||
|
|
||||||
|
var defaultRenderStates = [
|
||||||
|
{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath},
|
||||||
|
{name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath},
|
||||||
|
{name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}
|
||||||
|
];
|
||||||
|
|
||||||
var GRABBABLE_PROPERTIES = [
|
var GRABBABLE_PROPERTIES = [
|
||||||
"position",
|
"position",
|
||||||
|
@ -132,10 +137,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
var dim = {x: radius, y: radius, z: radius};
|
var dim = {x: radius, y: radius, z: radius};
|
||||||
var mode = "hold";
|
var mode = "hold";
|
||||||
if (!this.distanceHolding && !this.distanceRotating) {
|
if (!this.distanceHolding && !this.distanceRotating) {
|
||||||
// mode = (this.triggerSmoothedGrab() || this.secondarySqueezed()) ? "full" : "half";
|
if (controllerData.triggerClicks[this.hand]) {
|
||||||
if (controllerData.triggerClicks[this.hand]
|
|
||||||
// || this.secondarySqueezed() // XXX
|
|
||||||
) {
|
|
||||||
mode = "full";
|
mode = "full";
|
||||||
} else {
|
} else {
|
||||||
mode = "half";
|
mode = "half";
|
||||||
|
@ -339,44 +341,44 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
this.notPointingAtEntity = function(controllerData) {
|
this.notPointingAtEntity = function(controllerData) {
|
||||||
var intersection = controllerData.rayPicks[this.hand];
|
var intersection = controllerData.rayPicks[this.hand];
|
||||||
var entityProperty = Entities.getEntityProperties(intersection.objectID);
|
var entityProperty = Entities.getEntityProperties(intersection.objectID);
|
||||||
var entityType = entityProperty.type;
|
var entityType = entityProperty.type;
|
||||||
if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web") || intersection.type === RayPick.INTERSECTED_OVERLAY) {
|
if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web") || intersection.type === RayPick.INTERSECTED_OVERLAY) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.distanceRotate = function(otherFarGrabModule) {
|
this.distanceRotate = function(otherFarGrabModule) {
|
||||||
this.distanceRotating = true;
|
this.distanceRotating = true;
|
||||||
this.distanceHolding = false;
|
this.distanceHolding = false;
|
||||||
|
|
||||||
var worldControllerRotation = getControllerWorldLocation(this.handToController(), true).orientation;
|
var worldControllerRotation = getControllerWorldLocation(this.handToController(), true).orientation;
|
||||||
var controllerRotationDelta = Quat.multiply(worldControllerRotation, Quat.inverse(this.previousWorldControllerRotation));
|
var controllerRotationDelta = Quat.multiply(worldControllerRotation, Quat.inverse(this.previousWorldControllerRotation));
|
||||||
// Rotate entity by twice the delta rotation.
|
// Rotate entity by twice the delta rotation.
|
||||||
controllerRotationDelta = Quat.multiply(controllerRotationDelta, controllerRotationDelta);
|
controllerRotationDelta = Quat.multiply(controllerRotationDelta, controllerRotationDelta);
|
||||||
|
|
||||||
// Perform the rotation in the translation controller's action update.
|
// Perform the rotation in the translation controller's action update.
|
||||||
otherFarGrabModule.currentObjectRotation = Quat.multiply(controllerRotationDelta,
|
otherFarGrabModule.currentObjectRotation = Quat.multiply(controllerRotationDelta,
|
||||||
otherFarGrabModule.currentObjectRotation);
|
otherFarGrabModule.currentObjectRotation);
|
||||||
|
|
||||||
// Rotate about the translation controller's target position.
|
// Rotate about the translation controller's target position.
|
||||||
this.offsetPosition = Vec3.multiplyQbyV(controllerRotationDelta, this.offsetPosition);
|
this.offsetPosition = Vec3.multiplyQbyV(controllerRotationDelta, this.offsetPosition);
|
||||||
otherFarGrabModule.offsetPosition = Vec3.multiplyQbyV(controllerRotationDelta,
|
otherFarGrabModule.offsetPosition = Vec3.multiplyQbyV(controllerRotationDelta,
|
||||||
otherFarGrabModule.offsetPosition);
|
otherFarGrabModule.offsetPosition);
|
||||||
|
|
||||||
this.updateLaserPointer();
|
this.updateLaserPointer();
|
||||||
|
|
||||||
this.previousWorldControllerRotation = worldControllerRotation;
|
this.previousWorldControllerRotation = worldControllerRotation;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prepareDistanceRotatingData = function(controllerData) {
|
this.prepareDistanceRotatingData = function(controllerData) {
|
||||||
var intersection = controllerData.rayPicks[this.hand];
|
var intersection = controllerData.rayPicks[this.hand];
|
||||||
|
|
||||||
var controllerLocation = getControllerWorldLocation(this.handToController(), true);
|
var controllerLocation = getControllerWorldLocation(this.handToController(), true);
|
||||||
var worldControllerPosition = controllerLocation.position;
|
var worldControllerPosition = controllerLocation.position;
|
||||||
var worldControllerRotation = controllerLocation.orientation;
|
var worldControllerRotation = controllerLocation.orientation;
|
||||||
|
|
||||||
var grabbedProperties = Entities.getEntityProperties(intersection.objectID, GRABBABLE_PROPERTIES);
|
var grabbedProperties = Entities.getEntityProperties(intersection.objectID, GRABBABLE_PROPERTIES);
|
||||||
this.currentObjectPosition = grabbedProperties.position;
|
this.currentObjectPosition = grabbedProperties.position;
|
||||||
this.grabRadius = intersection.distance;
|
this.grabRadius = intersection.distance;
|
||||||
|
@ -385,7 +387,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
var targetPosition = Vec3.multiply(this.grabRadius, Quat.getUp(worldControllerRotation));
|
var targetPosition = Vec3.multiply(this.grabRadius, Quat.getUp(worldControllerRotation));
|
||||||
targetPosition = Vec3.sum(targetPosition, worldControllerPosition);
|
targetPosition = Vec3.sum(targetPosition, worldControllerPosition);
|
||||||
this.offsetPosition = Vec3.subtract(this.currentObjectPosition, targetPosition);
|
this.offsetPosition = Vec3.subtract(this.currentObjectPosition, targetPosition);
|
||||||
|
|
||||||
// Initial controller rotation.
|
// Initial controller rotation.
|
||||||
this.previousWorldControllerRotation = worldControllerRotation;
|
this.previousWorldControllerRotation = worldControllerRotation;
|
||||||
};
|
};
|
||||||
|
@ -395,13 +397,13 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
ContextOverlay.destroyContextOverlay(this.entityWithContextOverlay);
|
ContextOverlay.destroyContextOverlay(this.entityWithContextOverlay);
|
||||||
this.entityWithContextOverlay = false;
|
this.entityWithContextOverlay = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
this.isReady = function (controllerData) {
|
this.isReady = function (controllerData) {
|
||||||
if (this.notPointingAtEntity(controllerData)) {
|
if (this.notPointingAtEntity(controllerData)) {
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.distanceHolding = false;
|
this.distanceHolding = false;
|
||||||
this.distanceRotating = false;
|
this.distanceRotating = false;
|
||||||
|
|
||||||
|
@ -418,10 +420,15 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.isPointingAtUI = function(controllerData) {
|
this.isPointingAtUI = function(controllerData) {
|
||||||
var hudRayPickInfo = controllerData.hudRayPicks[this.hand];
|
var hudRayPickInfo = controllerData.hudRayPicks[this.hand];
|
||||||
var hudPoint2d = HMD.overlayFromWorldPoint(hudRayPickInfo.intersection);
|
var hudPoint2d = HMD.overlayFromWorldPoint(hudRayPickInfo.intersection);
|
||||||
}
|
if (Reticle.pointingAtSystemOverlay || Overlays.getOverlayAtPoint(hudPoint2d || Reticle.position)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
this.run = function (controllerData) {
|
this.run = function (controllerData) {
|
||||||
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || this.notPointingAtEntity(controllerData)) {
|
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || this.notPointingAtEntity(controllerData) || this.isPointingAtUI(controllerData)) {
|
||||||
this.endNearGrabAction();
|
this.endNearGrabAction();
|
||||||
this.laserPointerOff();
|
this.laserPointerOff();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
|
@ -432,12 +439,16 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.destroyContextOverlay();
|
this.destroyContextOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var otherModuleName =this.hand === RIGHT_HAND ? "LeftFarActionGrabEntity" : "RightFarActionGrabEntity";
|
||||||
|
var otherFarGrabModule = getEnabledModuleByName(otherModuleName);
|
||||||
|
|
||||||
// gather up the readiness of the near-grab modules
|
// gather up the readiness of the near-grab modules
|
||||||
var nearGrabNames = [
|
var nearGrabNames = [
|
||||||
this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity",
|
this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity",
|
||||||
this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity",
|
this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity",
|
||||||
this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay"
|
this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay"
|
||||||
];
|
];
|
||||||
|
|
||||||
var nearGrabReadiness = [];
|
var nearGrabReadiness = [];
|
||||||
for (var i = 0; i < nearGrabNames.length; i++) {
|
for (var i = 0; i < nearGrabNames.length; i++) {
|
||||||
var nearGrabModule = getEnabledModuleByName(nearGrabNames[i]);
|
var nearGrabModule = getEnabledModuleByName(nearGrabNames[i]);
|
||||||
|
@ -449,19 +460,14 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
// if we are doing a distance grab and the object gets close enough to the controller,
|
// if we are doing a distance grab and the object gets close enough to the controller,
|
||||||
// stop the far-grab so the near-grab or equip can take over.
|
// stop the far-grab so the near-grab or equip can take over.
|
||||||
for (var k = 0; k < nearGrabReadiness.length; k++) {
|
for (var k = 0; k < nearGrabReadiness.length; k++) {
|
||||||
if (nearGrabReadiness[k].active && nearGrabReadiness[k].targets[0] == this.grabbedThingID) {
|
if (nearGrabReadiness[k].active && nearGrabReadiness[k].targets[0] === this.grabbedThingID) {
|
||||||
this.laserPointerOff();
|
this.laserPointerOff();
|
||||||
this.endNearGrabAction();
|
this.endNearGrabAction();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.continueDistanceHolding(controllerData);
|
this.continueDistanceHolding(controllerData);
|
||||||
// this.updateLaserPointer(controllerData, false, false);
|
|
||||||
|
|
||||||
// var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
|
|
||||||
// Entities.callEntityMethod(this.grabbedThingID, "continueFarGrab", args);
|
|
||||||
} else {
|
} else {
|
||||||
// if we are doing a distance search and this controller moves into a position
|
// if we are doing a distance search and this controller moves into a position
|
||||||
// where it could near-grab something, stop searching.
|
// where it could near-grab something, stop searching.
|
||||||
|
@ -473,23 +479,22 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
var rayPickInfo = controllerData.rayPicks[this.hand];
|
var rayPickInfo = controllerData.rayPicks[this.hand];
|
||||||
var hudRayPickInfo = controllerData.hudRayPicks[this.hand];
|
if (rayPickInfo.type === RayPick.INTERSECTED_ENTITY) {
|
||||||
var hudPoint2d = HMD.overlayFromWorldPoint(hudRayPickInfo.intersection);
|
|
||||||
if (rayPickInfo.type == RayPick.INTERSECTED_ENTITY) {
|
|
||||||
if (controllerData.triggerClicks[this.hand]) {
|
if (controllerData.triggerClicks[this.hand]) {
|
||||||
var entityID = rayPickInfo.objectID;
|
var entityID = rayPickInfo.objectID;
|
||||||
var targetProps = Entities.getEntityProperties(entityID, ["dynamic", "shapeType", "position",
|
var targetProps = Entities.getEntityProperties(entityID, [
|
||||||
"rotation", "dimensions", "density",
|
"dynamic", "shapeType", "position",
|
||||||
"userData", "locked", "type"]);
|
"rotation", "dimensions", "density",
|
||||||
|
"userData", "locked", "type"
|
||||||
|
]);
|
||||||
|
|
||||||
if (entityIsDistanceGrabbable(targetProps)) {
|
if (entityIsDistanceGrabbable(targetProps)) {
|
||||||
if (!this.distanceRotating) {
|
if (!this.distanceRotating) {
|
||||||
this.grabbedThingID = entityID;
|
this.grabbedThingID = entityID;
|
||||||
this.grabbedDistance = rayPickInfo.distance;
|
this.grabbedDistance = rayPickInfo.distance;
|
||||||
}
|
}
|
||||||
var otherModuleName =
|
|
||||||
this.hand == RIGHT_HAND ? "LeftFarActionGrabEntity" : "RightFarActionGrabEntity";
|
if (otherFarGrabModule.grabbedThingID === this.grabbedThingID && otherFarGrabModule.distanceHolding) {
|
||||||
var otherFarGrabModule = getEnabledModuleByName(otherModuleName);
|
|
||||||
if (otherFarGrabModule.grabbedThingID == this.grabbedThingID && otherFarGrabModule.distanceHolding) {
|
|
||||||
this.distanceRotate(otherFarGrabModule);
|
this.distanceRotate(otherFarGrabModule);
|
||||||
} else {
|
} else {
|
||||||
this.distanceHolding = true;
|
this.distanceHolding = true;
|
||||||
|
@ -519,14 +524,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
} else if (this.distanceRotating) {
|
} else if (this.distanceRotating) {
|
||||||
var otherModuleName =
|
|
||||||
this.hand == RIGHT_HAND ? "LeftFarActionGrabEntity" : "RightFarActionGrabEntity";
|
|
||||||
var otherFarGrabModule = getEnabledModuleByName(otherModuleName);
|
|
||||||
this.distanceRotate(otherFarGrabModule);
|
this.distanceRotate(otherFarGrabModule);
|
||||||
} else if (Reticle.pointingAtSystemOverlay || Overlays.getOverlayAtPoint(hudPoint2d || Reticle.position)) {
|
|
||||||
this.endNearGrabAction();
|
|
||||||
this.laserPointerOff();
|
|
||||||
return makeRunningValues(false, [], []);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return makeRunningValues(true, [], []);
|
return makeRunningValues(true, [], []);
|
||||||
|
@ -540,7 +538,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.halfEnd = halfEnd;
|
this.halfEnd = halfEnd;
|
||||||
this.fullEnd = fullEnd;
|
this.fullEnd = fullEnd;
|
||||||
this.laserPointer = LaserPointers.createLaserPointer({
|
this.laserPointer = LaserPointers.createLaserPointer({
|
||||||
joint: (this.hand == RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND",
|
joint: (this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND",
|
||||||
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
||||||
maxDistance: PICK_MAX_DISTANCE,
|
maxDistance: PICK_MAX_DISTANCE,
|
||||||
posOffset: getGrabPointSphereOffset(this.handToController()),
|
posOffset: getGrabPointSphereOffset(this.handToController()),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict"
|
"use strict";
|
||||||
|
|
||||||
// inEditMode.js
|
// inEditMode.js
|
||||||
//
|
//
|
||||||
|
@ -8,7 +8,10 @@
|
||||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
|
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
|
||||||
NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues,
|
NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues,
|
||||||
Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC,
|
Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC,
|
||||||
AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset
|
AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset,
|
||||||
|
COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||||
|
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE,
|
||||||
|
isInEditMode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
|
@ -71,13 +74,17 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
parentID: AVATAR_SELF_ID
|
parentID: AVATAR_SELF_ID
|
||||||
};
|
};
|
||||||
|
|
||||||
var renderStates = [{name: "half", path: halfPath, end: halfEnd},
|
var renderStates = [
|
||||||
{name: "full", path: fullPath, end: fullEnd},
|
{name: "half", path: halfPath, end: halfEnd},
|
||||||
{name: "hold", path: holdPath}];
|
{name: "full", path: fullPath, end: fullEnd},
|
||||||
|
{name: "hold", path: holdPath}
|
||||||
var defaultRenderStates = [{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath},
|
];
|
||||||
{name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath},
|
|
||||||
{name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}];
|
var defaultRenderStates = [
|
||||||
|
{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath},
|
||||||
|
{name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath},
|
||||||
|
{name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}
|
||||||
|
];
|
||||||
|
|
||||||
function InEditMode(hand) {
|
function InEditMode(hand) {
|
||||||
this.hand = hand;
|
this.hand = hand;
|
||||||
|
@ -97,7 +104,7 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.handToController = function() {
|
this.handToController = function() {
|
||||||
return (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
return (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
||||||
};
|
};
|
||||||
|
@ -116,7 +123,7 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
this.updateLaserPointer = function(controllerData) {
|
this.updateLaserPointer = function(controllerData) {
|
||||||
var RADIUS = 0.005;
|
var RADIUS = 0.005;
|
||||||
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
|
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
|
||||||
|
|
||||||
if (this.mode === "full") {
|
if (this.mode === "full") {
|
||||||
this.fullEnd.dimensions = dim;
|
this.fullEnd.dimensions = dim;
|
||||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: this.fullEnd});
|
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: this.fullEnd});
|
||||||
|
@ -124,11 +131,11 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
this.halfEnd.dimensions = dim;
|
this.halfEnd.dimensions = dim;
|
||||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: this.halfEnd});
|
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: this.halfEnd});
|
||||||
}
|
}
|
||||||
|
|
||||||
LaserPointers.enableLaserPointer(this.laserPointer);
|
LaserPointers.enableLaserPointer(this.laserPointer);
|
||||||
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.pointingAtTablet = function(objectID) {
|
this.pointingAtTablet = function(objectID) {
|
||||||
if (objectID === HMD.tabletScreenID || objectID === HMD.tabletButtonID) {
|
if (objectID === HMD.tabletScreenID || objectID === HMD.tabletButtonID) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -157,16 +164,21 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.isReady = function(controllerData) {
|
this.exitModule = function() {
|
||||||
var overlays = controllerData.nearbyOverlayIDs[this.hand];
|
this.disableLasers();
|
||||||
var objectID = controllerData.rayPicks[this.hand].objectID;
|
return makeRunningValues(false, [], []);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.disableLasers = function() {
|
||||||
|
LaserPointers.disableLaserPointer(this.laserPointer);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isReady = function(controllerData) {
|
||||||
if (isInEditMode()) {
|
if (isInEditMode()) {
|
||||||
this.triggerClicked = false;
|
this.triggerClicked = false;
|
||||||
return makeRunningValues(true, [], []);
|
return makeRunningValues(true, [], []);
|
||||||
}
|
}
|
||||||
|
return this.exitModule();
|
||||||
return makeRunningValues(false, [], []);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.run = function(controllerData) {
|
this.run = function(controllerData) {
|
||||||
|
@ -175,44 +187,44 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
var tabletReady = tabletStylusInput.isReady(controllerData);
|
var tabletReady = tabletStylusInput.isReady(controllerData);
|
||||||
|
|
||||||
if (tabletReady.active) {
|
if (tabletReady.active) {
|
||||||
return makeRunningValues(false, [], []);
|
return this.exitModule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var overlayLaser = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightOverlayLaserInput" : "LeftOverlayLaserInput");
|
var overlayLaser = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightOverlayLaserInput" : "LeftOverlayLaserInput");
|
||||||
if (overlayLaser) {
|
if (overlayLaser) {
|
||||||
var overlayLaserReady = overlayLaser.isReady(controllerData);
|
var overlayLaserReady = overlayLaser.isReady(controllerData);
|
||||||
|
|
||||||
if (overlayLaserReady.active && this.pointingAtTablet(overlayLaser.target)) {
|
if (overlayLaserReady.active && this.pointingAtTablet(overlayLaser.target)) {
|
||||||
return makeRunningValues(false, [], []);
|
return this.exitModule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var nearOverlay = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay");
|
var nearOverlay = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay");
|
||||||
if (nearOverlay) {
|
if (nearOverlay) {
|
||||||
var nearOverlayReady = nearOverlay.isReady(controllerData);
|
var nearOverlayReady = nearOverlay.isReady(controllerData);
|
||||||
|
|
||||||
if (nearOverlayReady.active && nearOverlay.grabbedThingID === HMD.tabletID) {
|
if (nearOverlayReady.active && nearOverlay.grabbedThingID === HMD.tabletID) {
|
||||||
return makeRunningValues(false, [], []);
|
return this.exitModule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.processControllerTriggers(controllerData);
|
this.processControllerTriggers(controllerData);
|
||||||
this.updateLaserPointer(controllerData);
|
this.updateLaserPointer(controllerData);
|
||||||
this.sendPickData(controllerData);
|
this.sendPickData(controllerData);
|
||||||
|
|
||||||
|
|
||||||
return this.isReady(controllerData);
|
return this.isReady(controllerData);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.cleanup = function() {
|
this.cleanup = function() {
|
||||||
LaserPointers.disableLaserPointer(this.laserPointer);
|
LaserPointers.disableLaserPointer(this.laserPointer);
|
||||||
LaserPointers.removeLaserPointer(this.laserPointer);
|
LaserPointers.removeLaserPointer(this.laserPointer);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
this.halfEnd = halfEnd;
|
this.halfEnd = halfEnd;
|
||||||
this.fullEnd = fullEnd;
|
this.fullEnd = fullEnd;
|
||||||
|
|
||||||
this.laserPointer = LaserPointers.createLaserPointer({
|
this.laserPointer = LaserPointers.createLaserPointer({
|
||||||
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
|
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
|
||||||
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
||||||
|
@ -222,10 +234,9 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
faceAvatar: true,
|
faceAvatar: true,
|
||||||
defaultRenderStates: defaultRenderStates
|
defaultRenderStates: defaultRenderStates
|
||||||
});
|
});
|
||||||
|
|
||||||
LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]);
|
||||||
|
}
|
||||||
|
|
||||||
var leftHandInEditMode = new InEditMode(LEFT_HAND);
|
var leftHandInEditMode = new InEditMode(LEFT_HAND);
|
||||||
var rightHandInEditMode = new InEditMode(RIGHT_HAND);
|
var rightHandInEditMode = new InEditMode(RIGHT_HAND);
|
||||||
|
|
|
@ -28,7 +28,7 @@ var GRAB_RADIUS = 0.35;
|
||||||
this.previouslyUnhooked = {};
|
this.previouslyUnhooked = {};
|
||||||
|
|
||||||
this.parameters = makeDispatcherModuleParameters(
|
this.parameters = makeDispatcherModuleParameters(
|
||||||
140,
|
90,
|
||||||
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
|
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
|
||||||
[],
|
[],
|
||||||
100);
|
100);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict"
|
"use strict";
|
||||||
|
|
||||||
// overlayLaserInput.js
|
// overlayLaserInput.js
|
||||||
//
|
//
|
||||||
|
@ -8,16 +8,16 @@
|
||||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
|
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
|
||||||
NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues,
|
NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues,
|
||||||
Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC,
|
Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC,
|
||||||
AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset
|
AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset,
|
||||||
|
COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||||
|
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
Script.include("/~/system/libraries/controllers.js");
|
Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var halfPath = {
|
var halfPath = {
|
||||||
type: "line3d",
|
type: "line3d",
|
||||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||||
visible: true,
|
visible: true,
|
||||||
|
@ -72,13 +72,17 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
parentID: AVATAR_SELF_ID
|
parentID: AVATAR_SELF_ID
|
||||||
};
|
};
|
||||||
|
|
||||||
var renderStates = [{name: "half", path: halfPath, end: halfEnd},
|
var renderStates = [
|
||||||
{name: "full", path: fullPath, end: fullEnd},
|
{name: "half", path: halfPath, end: halfEnd},
|
||||||
{name: "hold", path: holdPath}];
|
{name: "full", path: fullPath, end: fullEnd},
|
||||||
|
{name: "hold", path: holdPath}
|
||||||
|
];
|
||||||
|
|
||||||
var defaultRenderStates = [{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath},
|
var defaultRenderStates = [
|
||||||
{name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath},
|
{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath},
|
||||||
{name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}];
|
{name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath},
|
||||||
|
{name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
// triggered when stylus presses a web overlay/entity
|
// triggered when stylus presses a web overlay/entity
|
||||||
|
@ -200,7 +204,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
// will return undefined if overlayID does not exist.
|
// will return undefined if overlayID does not exist.
|
||||||
function calculateLaserTargetFromOverlay(laserTip, overlayID) {
|
function calculateLaserTargetFromOverlay(worldPos, overlayID) {
|
||||||
var overlayPosition = Overlays.getProperty(overlayID, "position");
|
var overlayPosition = Overlays.getProperty(overlayID, "position");
|
||||||
if (overlayPosition === undefined) {
|
if (overlayPosition === undefined) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -212,12 +216,11 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var normal = Vec3.multiplyQbyV(overlayRotation, {x: 0, y: 0, z: 1});
|
var normal = Vec3.multiplyQbyV(overlayRotation, {x: 0, y: 0, z: 1});
|
||||||
var distance = Vec3.dot(Vec3.subtract(laserTip, overlayPosition), normal);
|
var distance = Vec3.dot(Vec3.subtract(worldPos, overlayPosition), normal);
|
||||||
var position = Vec3.subtract(laserTip, Vec3.multiply(normal, distance));
|
|
||||||
|
|
||||||
// calclulate normalized position
|
// calclulate normalized position
|
||||||
var invRot = Quat.inverse(overlayRotation);
|
var invRot = Quat.inverse(overlayRotation);
|
||||||
var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, overlayPosition));
|
var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(worldPos, overlayPosition));
|
||||||
var dpi = Overlays.getProperty(overlayID, "dpi");
|
var dpi = Overlays.getProperty(overlayID, "dpi");
|
||||||
|
|
||||||
var dimensions;
|
var dimensions;
|
||||||
|
@ -228,12 +231,12 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
if (resolution === undefined) {
|
if (resolution === undefined) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
resolution.z = 1; // Circumvent divide-by-zero.
|
resolution.z = 1;// Circumvent divide-by-zero.
|
||||||
var scale = Overlays.getProperty(overlayID, "dimensions");
|
var scale = Overlays.getProperty(overlayID, "dimensions");
|
||||||
if (scale === undefined) {
|
if (scale === undefined) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
scale.z = 0.01; // overlay dimensions are 2D, not 3D.
|
scale.z = 0.01;// overlay dimensions are 2D, not 3D.
|
||||||
dimensions = Vec3.multiplyVbyV(Vec3.multiply(resolution, INCHES_TO_METERS / dpi), scale);
|
dimensions = Vec3.multiplyVbyV(Vec3.multiply(resolution, INCHES_TO_METERS / dpi), scale);
|
||||||
} else {
|
} else {
|
||||||
dimensions = Overlays.getProperty(overlayID, "dimensions");
|
dimensions = Overlays.getProperty(overlayID, "dimensions");
|
||||||
|
@ -241,21 +244,23 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!dimensions.z) {
|
if (!dimensions.z) {
|
||||||
dimensions.z = 0.01; // sometimes overlay dimensions are 2D, not 3D.
|
dimensions.z = 0.01;// sometimes overlay dimensions are 2D, not 3D.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var invDimensions = { x: 1 / dimensions.x, y: 1 / dimensions.y, z: 1 / dimensions.z };
|
var invDimensions = { x: 1 / dimensions.x, y: 1 / dimensions.y, z: 1 / dimensions.z };
|
||||||
var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), DEFAULT_REGISTRATION_POINT);
|
var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), DEFAULT_REGISTRATION_POINT);
|
||||||
|
|
||||||
// 2D position on overlay plane in meters, relative to the bounding box upper-left hand corner.
|
// 2D position on overlay plane in meters, relative to the bounding box upper-left hand corner.
|
||||||
var position2D = { x: normalizedPosition.x * dimensions.x,
|
var position2D = {
|
||||||
y: (1 - normalizedPosition.y) * dimensions.y }; // flip y-axis
|
x: normalizedPosition.x * dimensions.x,
|
||||||
|
y: (1 - normalizedPosition.y) * dimensions.y // flip y-axis
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entityID: null,
|
entityID: null,
|
||||||
overlayID: overlayID,
|
overlayID: overlayID,
|
||||||
distance: distance,
|
distance: distance,
|
||||||
position: position,
|
position: worldPos,
|
||||||
position2D: position2D,
|
position2D: position2D,
|
||||||
normal: normal,
|
normal: normal,
|
||||||
normalizedPosition: normalizedPosition,
|
normalizedPosition: normalizedPosition,
|
||||||
|
@ -400,8 +405,8 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
if (this.laserTarget) {
|
if (this.laserTarget) {
|
||||||
var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds
|
var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds
|
||||||
if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY ||
|
if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY ||
|
||||||
distance2D(this.laserTarget.position2D,
|
distance2D( this.laserTarget.position2D,
|
||||||
this.pressEnterLaserTarget.position2D) > this.deadspotRadius) {
|
this.pressEnterLaserTarget.position2D) > this.deadspotRadius) {
|
||||||
sendTouchMoveEventToLaserTarget(this.hand, this.laserTarget);
|
sendTouchMoveEventToLaserTarget(this.hand, this.laserTarget);
|
||||||
this.deadspotExpired = true;
|
this.deadspotExpired = true;
|
||||||
}
|
}
|
||||||
|
@ -412,7 +417,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
this.releaseTouchEvent = function() {
|
this.releaseTouchEvent = function() {
|
||||||
sendTouchEndEventToLaserTarget(this.hand, this.pressEnterLaserTarget);
|
sendTouchEndEventToLaserTarget(this.hand, this.pressEnterLaserTarget);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
this.updateLaserTargets = function(controllerData) {
|
this.updateLaserTargets = function(controllerData) {
|
||||||
|
@ -423,9 +428,9 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
this.shouldExit = function(controllerData) {
|
this.shouldExit = function(controllerData) {
|
||||||
var intersection = controllerData.rayPicks[this.hand];
|
var intersection = controllerData.rayPicks[this.hand];
|
||||||
var offOverlay = (intersection.type !== RayPick.INTERSECTED_OVERLAY)
|
var offOverlay = (intersection.type !== RayPick.INTERSECTED_OVERLAY);
|
||||||
return offOverlay;
|
return offOverlay;
|
||||||
}
|
};
|
||||||
|
|
||||||
this.exitModule = function() {
|
this.exitModule = function() {
|
||||||
this.releaseTouchEvent();
|
this.releaseTouchEvent();
|
||||||
|
@ -433,7 +438,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.reset();
|
this.reset();
|
||||||
this.updateLaserPointer();
|
this.updateLaserPointer();
|
||||||
LaserPointers.disableLaserPointer(this.laserPointer);
|
LaserPointers.disableLaserPointer(this.laserPointer);
|
||||||
}
|
};
|
||||||
|
|
||||||
this.reset = function() {
|
this.reset = function() {
|
||||||
this.hover = false;
|
this.hover = false;
|
||||||
|
@ -515,7 +520,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.halfEnd = halfEnd;
|
this.halfEnd = halfEnd;
|
||||||
this.fullEnd = fullEnd;
|
this.fullEnd = fullEnd;
|
||||||
this.laserPointer = LaserPointers.createLaserPointer({
|
this.laserPointer = LaserPointers.createLaserPointer({
|
||||||
joint: (this.hand == RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
|
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
|
||||||
filter: RayPick.PICK_OVERLAYS,
|
filter: RayPick.PICK_OVERLAYS,
|
||||||
maxDistance: PICK_MAX_DISTANCE,
|
maxDistance: PICK_MAX_DISTANCE,
|
||||||
posOffset: getGrabPointSphereOffset(this.handToController()),
|
posOffset: getGrabPointSphereOffset(this.handToController()),
|
||||||
|
@ -525,7 +530,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
});
|
});
|
||||||
|
|
||||||
LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID]);
|
LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID]);
|
||||||
};
|
}
|
||||||
|
|
||||||
var leftOverlayLaserInput = new OverlayLaserInput(LEFT_HAND);
|
var leftOverlayLaserInput = new OverlayLaserInput(LEFT_HAND);
|
||||||
var rightOverlayLaserInput = new OverlayLaserInput(RIGHT_HAND);
|
var rightOverlayLaserInput = new OverlayLaserInput(RIGHT_HAND);
|
||||||
|
|
|
@ -171,12 +171,12 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
if (resolution === undefined) {
|
if (resolution === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resolution.z = 1; // Circumvent divide-by-zero.
|
resolution.z = 1; // Circumvent divide-by-zero.
|
||||||
var scale = Overlays.getProperty(overlayID, "dimensions");
|
var scale = Overlays.getProperty(overlayID, "dimensions");
|
||||||
if (scale === undefined) {
|
if (scale === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scale.z = 0.01; // overlay dimensions are 2D, not 3D.
|
scale.z = 0.01; // overlay dimensions are 2D, not 3D.
|
||||||
dimensions = Vec3.multiplyVbyV(Vec3.multiply(resolution, INCHES_TO_METERS / dpi), scale);
|
dimensions = Vec3.multiplyVbyV(Vec3.multiply(resolution, INCHES_TO_METERS / dpi), scale);
|
||||||
} else {
|
} else {
|
||||||
dimensions = Overlays.getProperty(overlayID, "dimensions");
|
dimensions = Overlays.getProperty(overlayID, "dimensions");
|
||||||
|
@ -184,15 +184,17 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!dimensions.z) {
|
if (!dimensions.z) {
|
||||||
dimensions.z = 0.01; // sometimes overlay dimensions are 2D, not 3D.
|
dimensions.z = 0.01; // sometimes overlay dimensions are 2D, not 3D.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var invDimensions = { x: 1 / dimensions.x, y: 1 / dimensions.y, z: 1 / dimensions.z };
|
var invDimensions = { x: 1 / dimensions.x, y: 1 / dimensions.y, z: 1 / dimensions.z };
|
||||||
var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), DEFAULT_REGISTRATION_POINT);
|
var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), DEFAULT_REGISTRATION_POINT);
|
||||||
|
|
||||||
// 2D position on overlay plane in meters, relative to the bounding box upper-left hand corner.
|
// 2D position on overlay plane in meters, relative to the bounding box upper-left hand corner.
|
||||||
var position2D = { x: normalizedPosition.x * dimensions.x,
|
var position2D = {
|
||||||
y: (1 - normalizedPosition.y) * dimensions.y }; // flip y-axis
|
x: normalizedPosition.x * dimensions.x,
|
||||||
|
y: (1 - normalizedPosition.y) * dimensions.y // flip y-axis
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entityID: null,
|
entityID: null,
|
||||||
|
@ -227,8 +229,10 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), props.registrationPoint);
|
var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), props.registrationPoint);
|
||||||
|
|
||||||
// 2D position on entity plane in meters, relative to the bounding box upper-left hand corner.
|
// 2D position on entity plane in meters, relative to the bounding box upper-left hand corner.
|
||||||
var position2D = { x: normalizedPosition.x * props.dimensions.x,
|
var position2D = {
|
||||||
y: (1 - normalizedPosition.y) * props.dimensions.y }; // flip y-axis
|
x: normalizedPosition.x * props.dimensions.x,
|
||||||
|
y: (1 - normalizedPosition.y) * props.dimensions.y // flip y-axis
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entityID: props.id,
|
entityID: props.id,
|
||||||
|
@ -354,7 +358,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
// translate tip forward according to constant.
|
// translate tip forward according to constant.
|
||||||
var TIP_OFFSET = {x: 0, y: WEB_STYLUS_LENGTH - WEB_TOUCH_Y_OFFSET, z: 0};
|
var TIP_OFFSET = {x: 0, y: WEB_STYLUS_LENGTH - WEB_TOUCH_Y_OFFSET, z: 0};
|
||||||
this.stylusTip.position = Vec3.sum(this.stylusTip.position,
|
this.stylusTip.position = Vec3.sum(this.stylusTip.position,
|
||||||
Vec3.multiplyQbyV(this.stylusTip.orientation, TIP_OFFSET));
|
Vec3.multiplyQbyV(this.stylusTip.orientation, TIP_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute tip velocity from hand controller motion, it is more accurate than computing it from previous positions.
|
// compute tip velocity from hand controller motion, it is more accurate than computing it from previous positions.
|
||||||
|
@ -363,9 +367,8 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
var worldControllerPos = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, pose.translation));
|
var worldControllerPos = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, pose.translation));
|
||||||
var worldControllerLinearVel = Vec3.multiplyQbyV(MyAvatar.orientation, pose.velocity);
|
var worldControllerLinearVel = Vec3.multiplyQbyV(MyAvatar.orientation, pose.velocity);
|
||||||
var worldControllerAngularVel = Vec3.multiplyQbyV(MyAvatar.orientation, pose.angularVelocity);
|
var worldControllerAngularVel = Vec3.multiplyQbyV(MyAvatar.orientation, pose.angularVelocity);
|
||||||
var tipVelocity = Vec3.sum(worldControllerLinearVel,
|
var tipVelocity = Vec3.sum(worldControllerLinearVel, Vec3.cross(worldControllerAngularVel,
|
||||||
Vec3.cross(worldControllerAngularVel,
|
Vec3.subtract(this.stylusTip.position, worldControllerPos)));
|
||||||
Vec3.subtract(this.stylusTip.position, worldControllerPos)));
|
|
||||||
this.stylusTip.velocity = tipVelocity;
|
this.stylusTip.velocity = tipVelocity;
|
||||||
} else {
|
} else {
|
||||||
this.stylusTip.velocity = {x: 0, y: 0, z: 0};
|
this.stylusTip.velocity = {x: 0, y: 0, z: 0};
|
||||||
|
@ -381,10 +384,11 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
name: "stylus",
|
name: "stylus",
|
||||||
url: Script.resourcesPath() + "meshes/tablet-stylus-fat.fbx",
|
url: Script.resourcesPath() + "meshes/tablet-stylus-fat.fbx",
|
||||||
loadPriority: 10.0,
|
loadPriority: 10.0,
|
||||||
localPosition: Vec3.sum({ x: 0.0,
|
localPosition: Vec3.sum({
|
||||||
y: WEB_TOUCH_Y_OFFSET,
|
x: 0.0,
|
||||||
z: 0.0 },
|
y: WEB_TOUCH_Y_OFFSET,
|
||||||
getGrabPointSphereOffset(this.handToController())),
|
z: 0.0
|
||||||
|
}, getGrabPointSphereOffset(this.handToController())),
|
||||||
localRotation: Quat.fromVec3Degrees({ x: -90, y: 0, z: 0 }),
|
localRotation: Quat.fromVec3Degrees({ x: -90, y: 0, z: 0 }),
|
||||||
dimensions: { x: 0.01, y: 0.01, z: WEB_STYLUS_LENGTH },
|
dimensions: { x: 0.01, y: 0.01, z: WEB_STYLUS_LENGTH },
|
||||||
solid: true,
|
solid: true,
|
||||||
|
@ -393,8 +397,8 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
drawInFront: false,
|
drawInFront: false,
|
||||||
parentID: AVATAR_SELF_ID,
|
parentID: AVATAR_SELF_ID,
|
||||||
parentJointIndex: MyAvatar.getJointIndex(this.hand === RIGHT_HAND ?
|
parentJointIndex: MyAvatar.getJointIndex(this.hand === RIGHT_HAND ?
|
||||||
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
|
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
|
||||||
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND")
|
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND")
|
||||||
};
|
};
|
||||||
this.stylus = Overlays.addOverlay("model", stylusProperties);
|
this.stylus = Overlays.addOverlay("model", stylusProperties);
|
||||||
};
|
};
|
||||||
|
@ -524,8 +528,8 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isNearStylusTarget = isNearStylusTarget(stylusTargets, EDGE_BORDER + hysteresisOffset,
|
this.isNearStylusTarget = isNearStylusTarget(stylusTargets, EDGE_BORDER + hysteresisOffset,
|
||||||
TABLET_MIN_TOUCH_DISTANCE - hysteresisOffset,
|
TABLET_MIN_TOUCH_DISTANCE - hysteresisOffset,
|
||||||
WEB_DISPLAY_STYLUS_DISTANCE + hysteresisOffset);
|
WEB_DISPLAY_STYLUS_DISTANCE + hysteresisOffset);
|
||||||
|
|
||||||
if (this.isNearStylusTarget) {
|
if (this.isNearStylusTarget) {
|
||||||
if (!this.useFingerInsteadOfStylus) {
|
if (!this.useFingerInsteadOfStylus) {
|
||||||
|
@ -630,7 +634,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds
|
var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds
|
||||||
if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY ||
|
if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY ||
|
||||||
distance2D(this.stylusTarget.position2D,
|
distance2D(this.stylusTarget.position2D,
|
||||||
this.touchingEnterStylusTarget.position2D) > this.deadspotRadius) {
|
this.touchingEnterStylusTarget.position2D) > this.deadspotRadius) {
|
||||||
sendTouchMoveEventToStylusTarget(this.hand, this.stylusTarget);
|
sendTouchMoveEventToStylusTarget(this.hand, this.stylusTarget);
|
||||||
this.deadspotExpired = true;
|
this.deadspotExpired = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,14 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
/*jslint bitwise: true */
|
/* jslint bitwise: true */
|
||||||
|
|
||||||
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat,
|
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat,
|
||||||
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID,
|
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID,
|
||||||
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable,
|
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable,
|
||||||
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
||||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||||
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE,
|
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
Script.include("/~/system/libraries/controllers.js");
|
Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var halfPath = {
|
var halfPath = {
|
||||||
type: "line3d",
|
type: "line3d",
|
||||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||||
visible: true,
|
visible: true,
|
||||||
|
@ -75,13 +75,17 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
parentID: AVATAR_SELF_ID
|
parentID: AVATAR_SELF_ID
|
||||||
};
|
};
|
||||||
|
|
||||||
var renderStates = [{name: "half", path: halfPath, end: halfEnd},
|
var renderStates = [
|
||||||
{name: "full", path: fullPath, end: fullEnd},
|
{name: "half", path: halfPath, end: halfEnd},
|
||||||
{name: "hold", path: holdPath}];
|
{name: "full", path: fullPath, end: fullEnd},
|
||||||
|
{name: "hold", path: holdPath}
|
||||||
|
];
|
||||||
|
|
||||||
var defaultRenderStates = [{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath},
|
var defaultRenderStates = [
|
||||||
{name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath},
|
{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath},
|
||||||
{name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}];
|
{name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath},
|
||||||
|
{name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
// triggered when stylus presses a web overlay/entity
|
// triggered when stylus presses a web overlay/entity
|
||||||
|
@ -143,7 +147,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function sendTouchStartEventToLaserTarget(hand, laserTarget) {
|
function sendTouchStartEventToLaserTarget(hand, laserTarget) {
|
||||||
var pointerEvent = {
|
var pointerEvent = {
|
||||||
type: "Press",
|
type: "Press",
|
||||||
id: hand + 1, // 0 is reserved for hardware mouse
|
id: hand + 1, // 0 is reserved for hardware mouse
|
||||||
|
@ -208,16 +212,18 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
Vec3.multiplyQbyV(props.rotation, {x: 0, y: 1, z: 0});
|
Vec3.multiplyQbyV(props.rotation, {x: 0, y: 1, z: 0});
|
||||||
var distance = Vec3.dot(Vec3.subtract(intersection, props.position), normal);
|
var distance = Vec3.dot(Vec3.subtract(intersection, props.position), normal);
|
||||||
var position = Vec3.subtract(intersection, Vec3.multiply(normal, distance));
|
var position = Vec3.subtract(intersection, Vec3.multiply(normal, distance));
|
||||||
|
|
||||||
// generate normalized coordinates
|
// generate normalized coordinates
|
||||||
var invRot = Quat.inverse(props.rotation);
|
var invRot = Quat.inverse(props.rotation);
|
||||||
var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, props.position));
|
var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, props.position));
|
||||||
var invDimensions = { x: 1 / props.dimensions.x, y: 1 / props.dimensions.y, z: 1 / props.dimensions.z };
|
var invDimensions = { x: 1 / props.dimensions.x, y: 1 / props.dimensions.y, z: 1 / props.dimensions.z };
|
||||||
var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), props.registrationPoint);
|
var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), props.registrationPoint);
|
||||||
|
|
||||||
// 2D position on entity plane in meters, relative to the bounding box upper-left hand corner.
|
// 2D position on entity plane in meters, relative to the bounding box upper-left hand corner.
|
||||||
var position2D = { x: normalizedPosition.x * props.dimensions.x,
|
var position2D = {
|
||||||
y: (1 - normalizedPosition.y) * props.dimensions.y }; // flip y-axis
|
x: normalizedPosition.x * props.dimensions.x,
|
||||||
|
y: (1 - normalizedPosition.y) * props.dimensions.y // flip y-axis
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entityID: props.id,
|
entityID: props.id,
|
||||||
|
@ -258,7 +264,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.getOtherModule = function() {
|
this.getOtherModule = function() {
|
||||||
return (this.hand === RIGHT_HAND) ? leftWebEntityLaserInput : rightWebEntityLaserInput;
|
return (this.hand === RIGHT_HAND) ? leftWebEntityLaserInput : rightWebEntityLaserInput;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.parameters = makeDispatcherModuleParameters(
|
this.parameters = makeDispatcherModuleParameters(
|
||||||
550,
|
550,
|
||||||
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
|
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
|
||||||
|
@ -288,7 +294,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.processControllerTriggers = function(controllerData) {
|
this.processControllerTriggers = function(controllerData) {
|
||||||
if (controllerData.triggerClicks[this.hand]) {
|
if (controllerData.triggerClicks[this.hand]) {
|
||||||
this.mode = "full";
|
this.mode = "full";
|
||||||
this.laserPressingTarget = true;
|
this.laserPressingTarget = true;
|
||||||
this.hover = false;
|
this.hover = false;
|
||||||
|
@ -316,7 +322,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.laserPressEnter = function () {
|
this.laserPressEnter = function () {
|
||||||
sendTouchStartEventToLaserTarget(this.hand, this.laserTarget);
|
sendTouchStartEventToLaserTarget(this.hand, this.laserTarget);
|
||||||
Controller.triggerHapticPulse(HAPTIC_STYLUS_STRENGTH, HAPTIC_STYLUS_DURATION, this.hand);
|
Controller.triggerHapticPulse(HAPTIC_STYLUS_STRENGTH, HAPTIC_STYLUS_DURATION, this.hand);
|
||||||
|
|
||||||
this.touchingEnterTimer = 0;
|
this.touchingEnterTimer = 0;
|
||||||
this.pressEnterLaserTarget = this.laserTarget;
|
this.pressEnterLaserTarget = this.laserTarget;
|
||||||
this.deadspotExpired = false;
|
this.deadspotExpired = false;
|
||||||
|
@ -340,12 +346,12 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
this.laserPressing = function (controllerData, dt) {
|
this.laserPressing = function (controllerData, dt) {
|
||||||
this.touchingEnterTimer += dt;
|
this.touchingEnterTimer += dt;
|
||||||
|
|
||||||
if (this.laserTarget) {
|
if (this.laserTarget) {
|
||||||
var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds
|
var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds
|
||||||
if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY ||
|
if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY ||
|
||||||
distance2D(this.laserTarget.position2D,
|
distance2D(this.laserTarget.position2D,
|
||||||
this.pressEnterLaserTarget.position2D) > this.deadspotRadius) {
|
this.pressEnterLaserTarget.position2D) > this.deadspotRadius) {
|
||||||
sendTouchMoveEventToLaserTarget(this.hand, this.laserTarget);
|
sendTouchMoveEventToLaserTarget(this.hand, this.laserTarget);
|
||||||
this.deadspotExpired = true;
|
this.deadspotExpired = true;
|
||||||
}
|
}
|
||||||
|
@ -353,19 +359,19 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.laserPressingTarget = false;
|
this.laserPressingTarget = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.releaseTouchEvent = function() {
|
this.releaseTouchEvent = function() {
|
||||||
if (this.pressEnterLaserTarget === null) {
|
if (this.pressEnterLaserTarget === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendTouchEndEventToLaserTarget(this.hand, this.pressEnterLaserTarget);
|
sendTouchEndEventToLaserTarget(this.hand, this.pressEnterLaserTarget);
|
||||||
}
|
};
|
||||||
|
|
||||||
this.updateLaserPointer = function(controllerData) {
|
this.updateLaserPointer = function(controllerData) {
|
||||||
var RADIUS = 0.005;
|
var RADIUS = 0.005;
|
||||||
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
|
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
|
||||||
|
|
||||||
if (this.mode === "full") {
|
if (this.mode === "full") {
|
||||||
fullEnd.dimensions = dim;
|
fullEnd.dimensions = dim;
|
||||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: fullEnd});
|
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: fullEnd});
|
||||||
|
@ -373,7 +379,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
halfEnd.dimensions = dim;
|
halfEnd.dimensions = dim;
|
||||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: halfEnd});
|
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: halfEnd});
|
||||||
}
|
}
|
||||||
|
|
||||||
LaserPointers.enableLaserPointer(this.laserPointer);
|
LaserPointers.enableLaserPointer(this.laserPointer);
|
||||||
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
||||||
};
|
};
|
||||||
|
@ -386,7 +392,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web")) {
|
if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.exitModule = function() {
|
this.exitModule = function() {
|
||||||
|
@ -396,7 +402,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.updateLaserPointer();
|
this.updateLaserPointer();
|
||||||
LaserPointers.disableLaserPointer(this.laserPointer);
|
LaserPointers.disableLaserPointer(this.laserPointer);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.reset = function() {
|
this.reset = function() {
|
||||||
this.pressEnterLaserTarget = null;
|
this.pressEnterLaserTarget = null;
|
||||||
this.laserTarget = null;
|
this.laserTarget = null;
|
||||||
|
@ -412,7 +418,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
if (this.isPointingAtWebEntity(controllerData) && !otherModule.active) {
|
if (this.isPointingAtWebEntity(controllerData) && !otherModule.active) {
|
||||||
return makeRunningValues(true, [], []);
|
return makeRunningValues(true, [], []);
|
||||||
}
|
}
|
||||||
|
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -433,7 +439,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.laserPressExit();
|
this.laserPressExit();
|
||||||
}
|
}
|
||||||
this.previousLaserClickedTarget = this.laserPressingTarget;
|
this.previousLaserClickedTarget = this.laserPressingTarget;
|
||||||
|
|
||||||
if (this.laserPressingTarget) {
|
if (this.laserPressingTarget) {
|
||||||
this.laserPressing(controllerData, deltaTime);
|
this.laserPressing(controllerData, deltaTime);
|
||||||
}
|
}
|
||||||
|
@ -447,7 +453,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.cleanup = function() {
|
this.cleanup = function() {
|
||||||
LaserPointers.disableLaserPointer(this.laserPointer);
|
LaserPointers.disableLaserPointer(this.laserPointer);
|
||||||
LaserPointers.removeLaserPointer(this.laserPointer);
|
LaserPointers.removeLaserPointer(this.laserPointer);
|
||||||
}
|
};
|
||||||
|
|
||||||
this.laserPointer = LaserPointers.createLaserPointer({
|
this.laserPointer = LaserPointers.createLaserPointer({
|
||||||
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
|
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
|
||||||
|
@ -458,13 +464,13 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
faceAvatar: true,
|
faceAvatar: true,
|
||||||
defaultRenderStates: defaultRenderStates
|
defaultRenderStates: defaultRenderStates
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
var leftWebEntityLaserInput = new WebEntityLaserInput(LEFT_HAND);
|
var leftWebEntityLaserInput = new WebEntityLaserInput(LEFT_HAND);
|
||||||
var rightWebEntityLaserInput = new WebEntityLaserInput(RIGHT_HAND);
|
var rightWebEntityLaserInput = new WebEntityLaserInput(RIGHT_HAND);
|
||||||
|
|
||||||
enableDispatcherModule("LeftWebEntityLaserInput", leftWebEntityLaserInput);
|
enableDispatcherModule("LeftWebEntityLaserInput", leftWebEntityLaserInput);
|
||||||
enableDispatcherModule("RightWebEntityLaserInput", rightWebEntityLaserInput);
|
enableDispatcherModule("RightWebEntityLaserInput", rightWebEntityLaserInput);
|
||||||
|
|
||||||
this.cleanup = function() {
|
this.cleanup = function() {
|
||||||
|
@ -474,5 +480,5 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
disableDispatcherModule("RightWebEntityLaserInput");
|
disableDispatcherModule("RightWebEntityLaserInput");
|
||||||
};
|
};
|
||||||
Script.scriptEnding.connect(this.cleanup);
|
Script.scriptEnding.connect(this.cleanup);
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
Loading…
Reference in a new issue