mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 22:39:45 +02:00
finshed handControllerGrab refactoring
This commit is contained in:
parent
9bd368c0a9
commit
3b357ad61e
13 changed files with 302 additions and 150 deletions
|
@ -5,11 +5,12 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/*jslint bitwise: true */
|
||||
/* jslint bitwise: true */
|
||||
|
||||
/* global Script, Entities, Overlays, Controller, Vec3, Quat, getControllerWorldLocation, RayPick,
|
||||
controllerDispatcherPlugins, controllerDispatcherPluginsNeedSort, entityIsGrabbable,
|
||||
LEFT_HAND, RIGHT_HAND, NEAR_GRAB_PICK_RADIUS, DEFAULT_SEARCH_SPHERE_DISTANCE, DISPATCHER_PROPERTIES
|
||||
controllerDispatcherPlugins:true, controllerDispatcherPluginsNeedSort:true, entityIsGrabbable:true,
|
||||
LEFT_HAND, RIGHT_HAND, NEAR_GRAB_PICK_RADIUS, DEFAULT_SEARCH_SPHERE_DISTANCE, DISPATCHER_PROPERTIES,
|
||||
getGrabPointSphereOffset
|
||||
*/
|
||||
|
||||
controllerDispatcherPlugins = {};
|
||||
|
@ -21,18 +22,16 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|||
|
||||
(function() {
|
||||
var _this = this;
|
||||
|
||||
var NEAR_MIN_RADIUS = 0.1;
|
||||
var NEAR_MAX_RADIUS = 1.0;
|
||||
|
||||
var TARGET_UPDATE_HZ = 60; // 50hz good enough, but we're using update
|
||||
var BASIC_TIMER_INTERVAL_MS = 1000 / TARGET_UPDATE_HZ;
|
||||
var lastInterval = Date.now();
|
||||
var intervalCount = 0;
|
||||
var totalDelta = 0;
|
||||
var totalVariance = 0;
|
||||
var highVarianceCount = 0;
|
||||
var veryhighVarianceCount = 0;
|
||||
this.lastInterval = Date.now();
|
||||
this.intervalCount = 0;
|
||||
this.totalDelta = 0;
|
||||
this.totalVariance = 0;
|
||||
this.highVarianceCount = 0;
|
||||
this.veryhighVarianceCount = 0;
|
||||
this.tabletID = null;
|
||||
this.blacklist = [];
|
||||
|
||||
|
@ -63,7 +62,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|||
this.unmarkSlotsForPluginName = function (runningPluginName) {
|
||||
// this is used to free activity-slots when a plugin is deactivated while it's running.
|
||||
for (var activitySlot in _this.activitySlots) {
|
||||
if (activitySlot.hasOwnProperty(activitySlot) && _this.activitySlots[activitySlot] == runningPluginName) {
|
||||
if (activitySlot.hasOwnProperty(activitySlot) && _this.activitySlots[activitySlot] === runningPluginName) {
|
||||
_this.activitySlots[activitySlot] = false;
|
||||
}
|
||||
}
|
||||
|
@ -106,23 +105,23 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|||
};
|
||||
|
||||
this.updateTimings = function () {
|
||||
intervalCount++;
|
||||
_this.intervalCount++;
|
||||
var thisInterval = Date.now();
|
||||
var deltaTimeMsec = thisInterval - lastInterval;
|
||||
var deltaTimeMsec = thisInterval - _this.lastInterval;
|
||||
var deltaTime = deltaTimeMsec / 1000;
|
||||
lastInterval = thisInterval;
|
||||
_this.lastInterval = thisInterval;
|
||||
|
||||
totalDelta += deltaTimeMsec;
|
||||
_this.totalDelta += deltaTimeMsec;
|
||||
|
||||
var variance = Math.abs(deltaTimeMsec - BASIC_TIMER_INTERVAL_MS);
|
||||
totalVariance += variance;
|
||||
_this.totalVariance += variance;
|
||||
|
||||
if (variance > 1) {
|
||||
highVarianceCount++;
|
||||
_this.highVarianceCount++;
|
||||
}
|
||||
|
||||
if (variance > 5) {
|
||||
veryhighVarianceCount++;
|
||||
_this.veryhighVarianceCount++;
|
||||
}
|
||||
|
||||
return deltaTime;
|
||||
|
@ -132,13 +131,12 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|||
if (HMD.tabletID !== _this.tabletID) {
|
||||
RayPick.setIgnoreOverlays(_this.leftControllerRayPick, [HMD.tabletID]);
|
||||
RayPick.setIgnoreOverlays(_this.rightControllerRayPick, [HMD.tabletID]);
|
||||
tabletIgnored = true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.update = function () {
|
||||
var deltaTime = this.updateTimings();
|
||||
this.setIgnoreTablet()
|
||||
var deltaTime = this.updateTimings();
|
||||
this.setIgnoreTablet();
|
||||
|
||||
if (controllerDispatcherPluginsNeedSort) {
|
||||
this.orderedPluginNames = [];
|
||||
|
@ -167,8 +165,10 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|||
controllerDispatcherPluginsNeedSort = false;
|
||||
}
|
||||
|
||||
var controllerLocations = [_this.dataGatherers.leftControllerLocation(),
|
||||
_this.dataGatherers.rightControllerLocation()];
|
||||
var controllerLocations = [
|
||||
_this.dataGatherers.leftControllerLocation(),
|
||||
_this.dataGatherers.rightControllerLocation()
|
||||
];
|
||||
|
||||
// find 3d overlays near each hand
|
||||
var nearbyOverlayIDs = [];
|
||||
|
@ -221,7 +221,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|||
length: 1000
|
||||
};
|
||||
|
||||
if (rayPicks[h].type == RayPick.INTERSECTED_ENTITY) {
|
||||
if (rayPicks[h].type === RayPick.INTERSECTED_ENTITY) {
|
||||
// XXX check to make sure this one isn't already in nearbyEntityProperties?
|
||||
if (rayPicks[h].distance < NEAR_GRAB_PICK_RADIUS) {
|
||||
var nearEntityID = rayPicks[h].objectID;
|
||||
|
@ -259,7 +259,6 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|||
var candidatePlugin = controllerDispatcherPlugins[orderedPluginName];
|
||||
|
||||
if (_this.slotsAreAvailableForPlugin(candidatePlugin)) {
|
||||
//print(orderedPluginName);
|
||||
var readiness = candidatePlugin.isReady(controllerData, deltaTime);
|
||||
if (readiness.active) {
|
||||
// this plugin will start. add it to the list of running plugins and mark the
|
||||
|
@ -297,7 +296,7 @@ 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";
|
||||
|
@ -314,19 +313,6 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|||
|
||||
Controller.enableMapping(MAPPING_NAME);
|
||||
|
||||
|
||||
this.mouseRayPick = RayPick.createRayPick({
|
||||
joint: "Mouse",
|
||||
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
||||
enabled: true
|
||||
});
|
||||
|
||||
this.mouseHudRayPick = RayPick.createRayPick({
|
||||
joint: "Mouse",
|
||||
filter: RayPick.PICK_HUD,
|
||||
enabled: true
|
||||
});
|
||||
|
||||
this.leftControllerRayPick = RayPick.createRayPick({
|
||||
joint: "_CONTROLLER_LEFTHAND",
|
||||
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
||||
|
@ -357,7 +343,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|||
});
|
||||
|
||||
this.handleHandMessage = function(channel, message, sender) {
|
||||
var data
|
||||
var data;
|
||||
if (sender === MyAvatar.sessionUUID) {
|
||||
try {
|
||||
if (channel === 'Hifi-Hand-RayPick-Blacklist') {
|
||||
|
@ -365,33 +351,29 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|||
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();
|
||||
this.setBlacklist();
|
||||
}
|
||||
|
||||
|
||||
if (action === 'remove') {
|
||||
if (index > -1) {
|
||||
blacklist.splice(index, 1);
|
||||
//this.setBlacklist();
|
||||
this.blacklist.splice(index, 1);
|
||||
this.setBlacklist();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} catch (e) {
|
||||
print("WARNING: handControllerGrab.js -- error parsing Hifi-Hand-RayPick-Blacklist message: " + message);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
this.cleanup = function () {
|
||||
Script.update.disconnect(_this.update);
|
||||
Controller.disableMapping(MAPPING_NAME);
|
||||
// RayPick.removeRayPick(_this.mouseRayPick);
|
||||
RayPick.removeRayPick(_this.leftControllerRayPick);
|
||||
RayPick.removeRayPick(_this.rightControllerRayPick);
|
||||
RayPick.removeRayPick(_this.rightControllerHudRayPick);
|
||||
|
|
|
@ -6,37 +6,37 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
|
||||
/* global Camera, HMD, MyAvatar, controllerDispatcherPlugins, Quat, Vec3, Overlays,
|
||||
MSECS_PER_SEC, LEFT_HAND, RIGHT_HAND, NULL_UUID, AVATAR_SELF_ID, FORBIDDEN_GRAB_TYPES,
|
||||
HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, ZERO_VEC, ONE_VEC, DEFAULT_REGISTRATION_POINT, INCHES_TO_METERS,
|
||||
TRIGGER_OFF_VALUE,
|
||||
TRIGGER_ON_VALUE,
|
||||
PICK_MAX_DISTANCE,
|
||||
DEFAULT_SEARCH_SPHERE_DISTANCE,
|
||||
NEAR_GRAB_PICK_RADIUS,
|
||||
COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
|
||||
COLORS_GRAB_DISTANCE_HOLD,
|
||||
NEAR_GRAB_RADIUS,
|
||||
DISPATCHER_PROPERTIES,
|
||||
/* global Camera, HMD, MyAvatar, controllerDispatcherPlugins:true, Quat, Vec3, Overlays,
|
||||
MSECS_PER_SEC:true , LEFT_HAND:true, RIGHT_HAND:true, NULL_UUID:true, AVATAR_SELF_ID:true, FORBIDDEN_GRAB_TYPES:true,
|
||||
HAPTIC_PULSE_STRENGTH:true, HAPTIC_PULSE_DURATION:true, ZERO_VEC:true, ONE_VEC:true, DEFAULT_REGISTRATION_POINT:true, INCHES_TO_METERS:true,
|
||||
TRIGGER_OFF_VALUE:true,
|
||||
TRIGGER_ON_VALUE:true,
|
||||
PICK_MAX_DISTANCE:true,
|
||||
DEFAULT_SEARCH_SPHERE_DISTANCE:true,
|
||||
NEAR_GRAB_PICK_RADIUS:true,
|
||||
COLORS_GRAB_SEARCHING_HALF_SQUEEZE:true,
|
||||
COLORS_GRAB_SEARCHING_FULL_SQUEEZE:true,
|
||||
COLORS_GRAB_DISTANCE_HOLD:true,
|
||||
NEAR_GRAB_RADIUS:true,
|
||||
DISPATCHER_PROPERTIES:true,
|
||||
Entities,
|
||||
makeDispatcherModuleParameters,
|
||||
makeRunningValues,
|
||||
enableDispatcherModule,
|
||||
disableDispatcherModule,
|
||||
getEnabledModuleByName,
|
||||
getGrabbableData,
|
||||
entityIsGrabbable,
|
||||
entityIsDistanceGrabbable,
|
||||
getControllerJointIndex,
|
||||
propsArePhysical,
|
||||
controllerDispatcherPluginsNeedSort,
|
||||
projectOntoXYPlane,
|
||||
projectOntoEntityXYPlane,
|
||||
projectOntoOverlayXYPlane,
|
||||
entityHasActions,
|
||||
ensureDynamic,
|
||||
findGroupParent
|
||||
makeDispatcherModuleParameters:true,
|
||||
makeRunningValues:true,
|
||||
enableDispatcherModule:true,
|
||||
disableDispatcherModule:true,
|
||||
getEnabledModuleByName:true,
|
||||
getGrabbableData:true,
|
||||
entityIsGrabbable:true,
|
||||
entityIsDistanceGrabbable:true,
|
||||
getControllerJointIndex:true,
|
||||
propsArePhysical:true,
|
||||
controllerDispatcherPluginsNeedSort:true,
|
||||
projectOntoXYPlane:true,
|
||||
projectOntoEntityXYPlane:true,
|
||||
projectOntoOverlayXYPlane:true,
|
||||
entityHasActions:true,
|
||||
ensureDynamic:true,
|
||||
findGroupParent:true
|
||||
*/
|
||||
|
||||
MSECS_PER_SEC = 1000.0;
|
||||
|
@ -69,11 +69,8 @@ COLORS_GRAB_SEARCHING_HALF_SQUEEZE = { red: 10, green: 10, blue: 255 };
|
|||
COLORS_GRAB_SEARCHING_FULL_SQUEEZE = { red: 250, green: 10, blue: 10 };
|
||||
COLORS_GRAB_DISTANCE_HOLD = { red: 238, green: 75, blue: 214 };
|
||||
|
||||
|
||||
NEAR_GRAB_RADIUS = 0.1;
|
||||
|
||||
|
||||
|
||||
DISPATCHER_PROPERTIES = [
|
||||
"position",
|
||||
"registrationPoint",
|
||||
|
@ -92,9 +89,6 @@ DISPATCHER_PROPERTIES = [
|
|||
"userData"
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
// priority -- a lower priority means the module will be asked sooner than one with a higher priority in a given update step
|
||||
// activitySlots -- indicates which "slots" must not yet be in use for this module to start
|
||||
// requiredDataForReady -- which "situation" parts this module looks at to decide if it will start
|
||||
|
@ -211,12 +205,12 @@ getControllerJointIndex = function (hand) {
|
|||
var controllerJointIndex = -1;
|
||||
if (Camera.mode === "first person") {
|
||||
controllerJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ?
|
||||
"_CONTROLLER_RIGHTHAND" :
|
||||
"_CONTROLLER_LEFTHAND");
|
||||
"_CONTROLLER_RIGHTHAND" :
|
||||
"_CONTROLLER_LEFTHAND");
|
||||
} else if (Camera.mode === "third person") {
|
||||
controllerJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ?
|
||||
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
|
||||
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
|
||||
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
|
||||
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
|
||||
}
|
||||
|
||||
return controllerJointIndex;
|
||||
|
@ -229,19 +223,24 @@ propsArePhysical = function (props) {
|
|||
if (!props.dynamic) {
|
||||
return false;
|
||||
}
|
||||
var isPhysical = (props.shapeType && props.shapeType != 'none');
|
||||
var isPhysical = (props.shapeType && props.shapeType !== 'none');
|
||||
return isPhysical;
|
||||
};
|
||||
|
||||
projectOntoXYPlane = function (worldPos, position, rotation, dimensions, registrationPoint) {
|
||||
var invRot = Quat.inverse(rotation);
|
||||
var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(worldPos, position));
|
||||
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 normalizedPos = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), registrationPoint);
|
||||
return { x: normalizedPos.x * dimensions.x,
|
||||
y: (1 - normalizedPos.y) * dimensions.y }; // flip y-axis
|
||||
return {
|
||||
x: normalizedPos.x * dimensions.x,
|
||||
y: (1 - normalizedPos.y) * dimensions.y // flip y-axis
|
||||
};
|
||||
};
|
||||
|
||||
projectOntoEntityXYPlane = function (entityID, worldPos, props) {
|
||||
|
@ -257,14 +256,14 @@ projectOntoOverlayXYPlane = function projectOntoOverlayXYPlane(overlayID, worldP
|
|||
if (dpi) {
|
||||
// Calculate physical dimensions for web3d overlay from resolution and dpi; "dimensions" property is used as a scale.
|
||||
var resolution = Overlays.getProperty(overlayID, "resolution");
|
||||
resolution.z = 1; // Circumvent divide-by-zero.
|
||||
resolution.z = 1; // Circumvent divide-by-zero.
|
||||
var scale = Overlays.getProperty(overlayID, "dimensions");
|
||||
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);
|
||||
} else {
|
||||
dimensions = Overlays.getProperty(overlayID, "dimensions");
|
||||
if (dimensions.z) {
|
||||
dimensions.z = 0.01; // overlay dimensions are 2D, not 3D.
|
||||
dimensions.z = 0.01; // overlay dimensions are 2D, not 3D.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,7 +278,7 @@ ensureDynamic = function (entityID) {
|
|||
// if we distance hold something and keep it very still before releasing it, it ends up
|
||||
// non-dynamic in bullet. If it's too still, give it a little bounce so it will fall.
|
||||
var props = Entities.getEntityProperties(entityID, ["velocity", "dynamic", "parentID"]);
|
||||
if (props.dynamic && props.parentID == NULL_UUID) {
|
||||
if (props.dynamic && props.parentID === NULL_UUID) {
|
||||
var velocity = props.velocity;
|
||||
if (Vec3.length(velocity) < 0.05) { // see EntityMotionState.cpp DYNAMIC_LINEAR_VELOCITY_THRESHOLD
|
||||
velocity = { x: 0.0, y: 0.2, z: 0.0 };
|
||||
|
@ -289,7 +288,7 @@ ensureDynamic = function (entityID) {
|
|||
};
|
||||
|
||||
findGroupParent = function (controllerData, targetProps) {
|
||||
while (targetProps.parentID && targetProps.parentID != NULL_UUID) {
|
||||
while (targetProps.parentID && targetProps.parentID !== NULL_UUID) {
|
||||
// XXX use controllerData.nearbyEntityPropertiesByID ?
|
||||
var parentProps = Entities.getEntityProperties(targetProps.parentID, DISPATCHER_PROPERTIES);
|
||||
if (!parentProps) {
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
"use strict";
|
||||
|
||||
// nearTrigger.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, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
|
||||
enableDispatcherModule, disableDispatcherModule, getGrabbableData, Vec3,
|
||||
TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS,
|
||||
getEnabledModuleByName
|
||||
*/
|
||||
|
||||
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||
|
||||
(function() {
|
||||
function DisableModules(hand) {
|
||||
this.hand = hand;
|
||||
this.disableModules = false;
|
||||
this.parameters = makeDispatcherModuleParameters(
|
||||
90,
|
||||
this.hand === RIGHT_HAND ? ["rightHand", "rightHandEquip", "rightHandTrigger"] : ["leftHand", "leftHandEquip", "leftHandTrigger"],
|
||||
100);
|
||||
|
||||
this.isReady = function(controllerData) {
|
||||
if (this.disableModules) {
|
||||
return makeRunningValues(true, [], []);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
this.run = function(controllerData) {
|
||||
var teleportModuleName = this.hand === RIGHT_HAND ? "RightTeleporter" : "LeftTeleporter";
|
||||
var teleportModule = getEnabledModuleByName(teleportModuleName);
|
||||
|
||||
if (teleportModule) {
|
||||
var ready = teleportModule.isReady(controllerData);
|
||||
if (ready) {
|
||||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
}
|
||||
if (!this.disablemodules) {
|
||||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
return makeRunningValues(true, [], []);
|
||||
};
|
||||
}
|
||||
|
||||
var leftDisableModules = new DisableModules(LEFT_HAND);
|
||||
var rightDisableModules = new DisableModules(RIGHT_HAND);
|
||||
|
||||
enableDispatcherModule("LeftDisableModules", leftDisableModules);
|
||||
enableDispatcherModule("RightDisableModules", rightDisableModules);
|
||||
this.handleMessage = function(channel, message, sender) {
|
||||
if (sender === MyAvatar.sessionUUID) {
|
||||
if (channel === 'Hifi-Hand-Disabler') {
|
||||
if (message === 'left') {
|
||||
leftDisableModules.disableModules = true;
|
||||
}
|
||||
if (message === 'right') {
|
||||
rightDisableModules.disableModules = true;
|
||||
|
||||
}
|
||||
if (message === 'both' || message === 'none') {
|
||||
if (message === 'both') {
|
||||
leftDisableModules.disableModules = true;
|
||||
rightDisableModules.disableModules = true;
|
||||
} else if (message === 'none') {
|
||||
leftDisableModules.disableModules = false;
|
||||
rightDisableModules.disableModules = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Messages.subscribe('Hifi-Hand-Disabler');
|
||||
this.cleanup = function() {
|
||||
disableDispatcherModule("LeftDisableModules");
|
||||
disableDispatcherModule("RightDisableModules");
|
||||
};
|
||||
Messages.messageReceived.connect(this.handleMessage);
|
||||
Script.scriptEnding.connect(this.cleanup);
|
||||
}());
|
|
@ -187,6 +187,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
|
||||
wearable = props.userDataParsed.wearable ? props.userDataParsed.wearable : {};
|
||||
} catch (err) {
|
||||
// don't want to spam the logs
|
||||
}
|
||||
return wearable;
|
||||
}
|
||||
|
@ -199,6 +200,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
|
||||
equipHotspots = props.userDataParsed.equipHotspots ? props.userDataParsed.equipHotspots : [];
|
||||
} catch (err) {
|
||||
// don't want to spam the logs
|
||||
}
|
||||
return equipHotspots;
|
||||
}
|
||||
|
@ -255,7 +257,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
|
||||
this.parameters = makeDispatcherModuleParameters(
|
||||
300,
|
||||
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
|
||||
this.hand === RIGHT_HAND ? ["rightHand", "rightHandEquip"] : ["leftHand", "rightHandEquip"],
|
||||
[],
|
||||
100);
|
||||
|
||||
|
@ -556,8 +558,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
var controllerLocation = getControllerWorldLocation(this.handToController(), true);
|
||||
var worldHandPosition = controllerLocation.position;
|
||||
var candidateEntityProps = controllerData.nearbyEntityProperties[this.hand];
|
||||
|
||||
|
||||
|
||||
|
||||
var potentialEquipHotspot = null;
|
||||
if (this.messageGrabEntity) {
|
||||
var hotspots = this.collectEquipHotspots(this.grabEntityProps);
|
||||
|
@ -567,7 +569,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
} else {
|
||||
potentialEquipHotspot = this.chooseBestEquipHotspot(candidateEntityProps, controllerData);
|
||||
}
|
||||
|
||||
|
||||
if (!this.waitForTriggerRelease) {
|
||||
this.updateEquipHaptics(potentialEquipHotspot, worldHandPosition);
|
||||
}
|
||||
|
@ -675,7 +677,6 @@ 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 {
|
||||
|
|
|
@ -527,6 +527,19 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
this.distanceRotate(otherFarGrabModule);
|
||||
}
|
||||
}
|
||||
return this.exitIfDisabled();
|
||||
};
|
||||
|
||||
this.exitIfDisabled = function() {
|
||||
var moduleName = this.hand === RIGHT_HAND ? "RightDisableModules" : "LeftDisableModules";
|
||||
var disableModule = getEnabledModuleByName(moduleName);
|
||||
if (disableModule) {
|
||||
if (disableModule.disableModules) {
|
||||
this.laserPointerOff();
|
||||
this.endNearGrabAction();
|
||||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
}
|
||||
return makeRunningValues(true, [], []);
|
||||
};
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ Script.include("/~/system/libraries/utils.js");
|
|||
|
||||
this.parameters = makeDispatcherModuleParameters(
|
||||
160,
|
||||
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
|
||||
this.hand === RIGHT_HAND ? ["rightHand", "rightHandEquip", "rightHandTrigger"] : ["leftHand", "leftHandEquip", "leftHandTrigger"],
|
||||
100);
|
||||
|
||||
this.nearTablet = function(overlays) {
|
||||
|
|
|
@ -9,11 +9,12 @@
|
|||
getControllerJointIndex, getGrabbableData, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
|
||||
propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable,
|
||||
Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues,
|
||||
TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, findGroupParent
|
||||
TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, findGroupParent, entityIsCloneable, propsAreCloneDynamic, cloneEntity
|
||||
*/
|
||||
|
||||
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||
Script.include("/~/system/libraries/controllers.js");
|
||||
Script.include("/~/system/libraries/cloneEntityUtils.js");
|
||||
|
||||
(function() {
|
||||
|
||||
|
@ -172,7 +173,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
|
||||
var targetProps = this.getTargetProps(controllerData);
|
||||
if (targetProps) {
|
||||
if (!propsArePhysical(targetProps)) {
|
||||
if (!propsArePhysical(targetProps) && !propsAreCloneDynamic) {
|
||||
return makeRunningValues(false, [], []); // let nearParentGrabEntity handle it
|
||||
} else {
|
||||
this.targetEntityID = targetProps.id;
|
||||
|
@ -185,13 +186,12 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
|
||||
this.run = function (controllerData) {
|
||||
if (this.actionID) {
|
||||
if (controllerData.triggerClicks[this.hand] == 0) {
|
||||
if (controllerData.triggerClicks[this.hand] === 0) {
|
||||
this.endNearGrabAction();
|
||||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
|
||||
this.refreshNearGrabAction(controllerData);
|
||||
|
||||
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
|
||||
Entities.callEntityMethod(this.targetEntityID, "continueNearGrab", args);
|
||||
} else {
|
||||
|
@ -204,9 +204,18 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
|
||||
var targetProps = this.getTargetProps(controllerData);
|
||||
if (targetProps) {
|
||||
if (controllerData.triggerClicks[this.hand] == 1) {
|
||||
if (controllerData.triggerClicks[this.hand] === 1) {
|
||||
// switch to grabbing
|
||||
this.startNearGrabAction(controllerData, targetProps);
|
||||
var targetCloneable = entityIsCloneable(targetProps);
|
||||
if (targetCloneable) {
|
||||
var worldEntityProps = controllerData.nearbyEntityProperties[this.hand];
|
||||
var cloneID = cloneEntity(targetProps, worldEntityProps);
|
||||
var cloneProps = Entities.getEntityProperties(cloneID);
|
||||
this.targetEntityID = cloneID;
|
||||
this.startNearGrabAction(controllerData, cloneProps);
|
||||
} else {
|
||||
this.startNearGrabAction(controllerData, targetProps);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
|
||||
propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, TRIGGER_OFF_VALUE,
|
||||
makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS,
|
||||
findGroupParent, Vec3, cloneEntity, entityIsCloneable
|
||||
findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic
|
||||
*/
|
||||
|
||||
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||
|
@ -40,6 +40,14 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
this.handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||
this.controllerJointIndex = getControllerJointIndex(this.hand);
|
||||
|
||||
this.getOtherModule = function() {
|
||||
return (this.hand === RIGHT_HAND) ? leftNearParentingGrabEntity : rightNearParentingGrabEntity;
|
||||
};
|
||||
|
||||
this.otherHandIsParent = function(props) {
|
||||
return this.getOtherModule().thisHandIsParent(props);
|
||||
};
|
||||
|
||||
this.thisHandIsParent = function(props) {
|
||||
if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== AVATAR_SELF_ID) {
|
||||
return false;
|
||||
|
@ -67,7 +75,6 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
};
|
||||
|
||||
this.startNearParentingGrabEntity = function (controllerData, targetProps) {
|
||||
|
||||
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
|
||||
|
||||
var handJointIndex;
|
||||
|
@ -92,10 +99,18 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
// this should never happen, but if it does, don't set previous parent to be this hand.
|
||||
// this.previousParentID[targetProps.id] = NULL;
|
||||
// this.previousParentJointIndex[targetProps.id] = -1;
|
||||
} else if (this.otherHandIsParent(targetProps)) {
|
||||
// the other hand is parent. Steal the object and information
|
||||
var otherModule = this.getOtherModule();
|
||||
this.previousParentID[targetProps.id] = otherModule.previousParentID[targetProps.id];
|
||||
this.previousParentJointIndex[targetProps.id] = otherModule.previousParentJointIndex[targetProps.id];
|
||||
otherModule.endNearParentingGrabEntity();
|
||||
} else {
|
||||
this.previousParentID[targetProps.id] = targetProps.parentID;
|
||||
this.previousParentJointIndex[targetProps.id] = targetProps.parentJointIndex;
|
||||
}
|
||||
|
||||
this.targetEntityID = targetProps.id;
|
||||
Entities.editEntity(targetProps.id, reparentProps);
|
||||
|
||||
Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({
|
||||
|
@ -103,10 +118,11 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
grabbedEntity: targetProps.id,
|
||||
joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"
|
||||
}));
|
||||
this.grabbing = true;
|
||||
};
|
||||
|
||||
this.endNearParentingGrabEntity = function () {
|
||||
if (this.previousParentID[this.targetEntityID] === NULL_UUID) {
|
||||
if (this.previousParentID[this.targetEntityID] === NULL_UUID || this.previousParentID === undefined) {
|
||||
Entities.editEntity(this.targetEntityID, {
|
||||
parentID: this.previousParentID[this.targetEntityID],
|
||||
parentJointIndex: this.previousParentJointIndex[this.targetEntityID]
|
||||
|
@ -123,7 +139,6 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
|
||||
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
|
||||
Entities.callEntityMethod(this.targetEntityID, "releaseGrab", args);
|
||||
|
||||
this.grabbing = false;
|
||||
this.targetEntityID = null;
|
||||
};
|
||||
|
@ -160,7 +175,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
|
||||
var targetProps = this.getTargetProps(controllerData);
|
||||
if (targetProps) {
|
||||
if (propsArePhysical(targetProps)) {
|
||||
if (propsArePhysical(targetProps) || propsAreCloneDynamic(targetProps)) {
|
||||
return makeRunningValues(false, [], []); // let nearActionGrabEntity handle it
|
||||
} else {
|
||||
this.targetEntityID = targetProps.id;
|
||||
|
@ -178,6 +193,13 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
|
||||
var props = Entities.getEntityProperties(this.targetEntityID);
|
||||
if (!this.thisHandIsParent(props)) {
|
||||
this.grabbing = false;
|
||||
this.targetEntityID = null;
|
||||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
|
||||
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
|
||||
Entities.callEntityMethod(this.targetEntityID, "continueNearGrab", args);
|
||||
} else {
|
||||
|
|
|
@ -38,31 +38,52 @@ var GRAB_RADIUS = 0.35;
|
|||
this.handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||
this.controllerJointIndex = getControllerJointIndex(this.hand);
|
||||
|
||||
this.getOtherModule = function() {
|
||||
return (this.hand === RIGHT_HAND) ? leftNearParentingGrabOverlay : rightNearParentingGrabOverlay;
|
||||
};
|
||||
|
||||
this.otherHandIsParent = function(props) {
|
||||
return this.getOtherModule().thisHandIsParent(props);
|
||||
};
|
||||
|
||||
this.thisHandIsParent = function(props) {
|
||||
if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== AVATAR_SELF_ID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||
if (props.parentJointIndex == handJointIndex) {
|
||||
if (props.parentJointIndex === handJointIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var controllerJointIndex = this.controllerJointIndex;
|
||||
if (props.parentJointIndex == controllerJointIndex) {
|
||||
if (props.parentJointIndex === controllerJointIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var controllerCRJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ?
|
||||
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
|
||||
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
|
||||
if (props.parentJointIndex == controllerCRJointIndex) {
|
||||
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
|
||||
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
|
||||
|
||||
if (props.parentJointIndex === controllerCRJointIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
this.getGrabbedProperties = function() {
|
||||
return {
|
||||
position: Overlays.getProperty(this.grabbedThingID, "position"),
|
||||
rotation: Overlays.getProperty(this.grabbedThingID, "rotation"),
|
||||
parentID: Overlays.getProperty(this.grabbedThingID, "parentID"),
|
||||
parentJointIndex: Overlays.getProperty(this.grabbedThingID, "parentJointIndex"),
|
||||
dynamic: false,
|
||||
shapeType: "none"
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
this.startNearParentingGrabOverlay = function (controllerData) {
|
||||
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
|
||||
|
||||
|
@ -74,15 +95,8 @@ var GRAB_RADIUS = 0.35;
|
|||
// }
|
||||
handJointIndex = this.controllerJointIndex;
|
||||
|
||||
var grabbedProperties = {
|
||||
position: Overlays.getProperty(this.grabbedThingID, "position"),
|
||||
rotation: Overlays.getProperty(this.grabbedThingID, "rotation"),
|
||||
parentID: Overlays.getProperty(this.grabbedThingID, "parentID"),
|
||||
parentJointIndex: Overlays.getProperty(this.grabbedThingID, "parentJointIndex"),
|
||||
dynamic: false,
|
||||
shapeType: "none"
|
||||
};
|
||||
|
||||
var grabbedProperties = this.getGrabbedProperties();
|
||||
|
||||
var reparentProps = {
|
||||
parentID: AVATAR_SELF_ID,
|
||||
parentJointIndex: handJointIndex,
|
||||
|
@ -94,6 +108,12 @@ var GRAB_RADIUS = 0.35;
|
|||
// this should never happen, but if it does, don't set previous parent to be this hand.
|
||||
// this.previousParentID[this.grabbedThingID] = NULL;
|
||||
// this.previousParentJointIndex[this.grabbedThingID] = -1;
|
||||
} else if (this.otherHandIsParent(grabbedProperties)) {
|
||||
// the other hand is parent. Steal the object and information
|
||||
var otherModule = this.getOtherModule();
|
||||
this.previousParentID[this.grabbedThingID] = otherModule.previousParentID[this.garbbedThingID];
|
||||
this.previousParentJointIndex[this.grabbedThingID] = otherModule.previousParentJointIndex[this.grabbedThingID];
|
||||
|
||||
} else {
|
||||
this.previousParentID[this.grabbedThingID] = grabbedProperties.parentID;
|
||||
this.previousParentJointIndex[this.grabbedThingID] = grabbedProperties.parentJointIndex;
|
||||
|
@ -117,7 +137,7 @@ var GRAB_RADIUS = 0.35;
|
|||
// before we grabbed it, overlay was a child of something; put it back.
|
||||
Overlays.editOverlay(this.grabbedThingID, {
|
||||
parentID: this.previousParentID[this.grabbedThingID],
|
||||
parentJointIndex: this.previousParentJointIndex[this.grabbedThingID],
|
||||
parentJointIndex: this.previousParentJointIndex[this.grabbedThingID]
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -135,10 +155,10 @@ var GRAB_RADIUS = 0.35;
|
|||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.isReady = function (controllerData) {
|
||||
if (controllerData.triggerClicks[this.hand] == 0) {
|
||||
if (controllerData.triggerClicks[this.hand] === 0) {
|
||||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
|
||||
|
@ -160,10 +180,16 @@ var GRAB_RADIUS = 0.35;
|
|||
};
|
||||
|
||||
this.run = function (controllerData) {
|
||||
if (controllerData.triggerClicks[this.hand] == 0) {
|
||||
if (controllerData.triggerClicks[this.hand] === 0) {
|
||||
this.endNearParentingGrabOverlay();
|
||||
return makeRunningValues(false, [], []);
|
||||
} else {
|
||||
// check if someone stole the target from us
|
||||
var grabbedProperties = this.getGrabbedProperties();
|
||||
if (!this.thisHandIsParent(grabbedProperties)) {
|
||||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
|
||||
return makeRunningValues(true, [this.grabbedThingID], []);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
|||
|
||||
this.parameters = makeDispatcherModuleParameters(
|
||||
520,
|
||||
this.hand === RIGHT_HAND ? ["rightHandTrigger"] : ["leftHandTrigger"],
|
||||
this.hand === RIGHT_HAND ? ["rightHandTrigger", "rightHand"] : ["leftHandTrigger", "leftHand"],
|
||||
[],
|
||||
100);
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ var CONTOLLER_SCRIPTS = [
|
|||
"controllerModules/overlayLaserInput.js",
|
||||
"controllerModules/webEntityLaserInput.js",
|
||||
"controllerModules/inEditMode.js",
|
||||
"controllerModules/disableOtherModule.js",
|
||||
"teleport.js"
|
||||
];
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions,
|
||||
Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic
|
||||
*/
|
||||
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
||||
|
||||
Script.include("/~/system/libraries/Xform.js");
|
||||
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||
|
@ -225,7 +226,7 @@ function Teleporter(hand) {
|
|||
}
|
||||
|
||||
this.parameters = makeDispatcherModuleParameters(
|
||||
300,
|
||||
80,
|
||||
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
|
||||
[],
|
||||
100);
|
||||
|
@ -338,12 +339,12 @@ function Teleporter(hand) {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// related to repositioning the avatar after you teleport
|
||||
var FOOT_JOINT_NAMES = ["RightToe_End", "RightToeBase", "RightFoot"];
|
||||
var DEFAULT_ROOT_TO_FOOT_OFFSET = 0.5;
|
||||
function getAvatarFootOffset() {
|
||||
|
||||
|
||||
// find a valid foot jointIndex
|
||||
var footJointIndex = -1;
|
||||
var i, l = FOOT_JOINT_NAMES.length;
|
||||
|
|
|
@ -5,11 +5,13 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* global entityIsCloneable:true, getGrabbableData:true, cloneEntity:true propsAreCloneDynamic:true */
|
||||
|
||||
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||
|
||||
|
||||
// Object assign polyfill
|
||||
if (typeof Object.assign != 'function') {
|
||||
if (typeof Object.assign !== 'function') {
|
||||
Object.assign = function(target, varArgs) {
|
||||
if (target === null) {
|
||||
throw new TypeError('Cannot convert undefined or null to object');
|
||||
|
@ -36,7 +38,18 @@ entityIsCloneable = function(props) {
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
propsAreCloneDynamic = function(props) {
|
||||
var cloneable = entityIsCloneable(props);
|
||||
if (cloneable) {
|
||||
var grabInfo = getGrabbableData(props);
|
||||
if (grabInfo.cloneDynamic) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
cloneEntity = function(props, worldEntityProps) {
|
||||
|
@ -49,26 +62,26 @@ cloneEntity = function(props, worldEntityProps) {
|
|||
count++;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var grabInfo = getGrabbableData(cloneableProps);
|
||||
var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 0;
|
||||
if (count >= limit && limit !== 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
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({}, JSON.parse(cloneableProps.userData));
|
||||
var cProperties = Object.assign({}, cloneableProps);
|
||||
|
||||
|
||||
|
||||
delete cUserData.grabbableKey.cloneLifetime;
|
||||
delete cUserData.grabbableKey.cloneable;
|
||||
delete cUserData.grabbableKey.cloneDynamic;
|
||||
delete cUserData.grabbableKey.cloneLimit;
|
||||
delete cProperties.id;
|
||||
|
||||
|
||||
|
||||
cProperties.dynamic = dynamic;
|
||||
cProperties.locked = false;
|
||||
|
@ -76,7 +89,7 @@ cloneEntity = function(props, worldEntityProps) {
|
|||
cUserData.grabbableKey.grabbable = true;
|
||||
cProperties.lifetime = lifetime;
|
||||
cProperties.userData = JSON.stringify(cUserData);
|
||||
|
||||
|
||||
var cloneID = Entities.addEntity(cProperties);
|
||||
return cloneID;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue