overte-thingvellir/scripts/system/controllers/controllerModules/cloneEntity.js
2017-08-23 17:32:41 -07:00

159 lines
5.7 KiB
JavaScript

"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);
}());