content/hifi-content/DomainContent/production/avatarAccessories/attachScript/attachmentItemScript (Tuesday, August 29, 2017 6-13-25 PM).js
2022-02-13 22:49:05 +01:00

239 lines
8 KiB
JavaScript

//
// attachmentItemScript.js
//
// Created by Thijs Wenker on 5/30/17.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
/*
// User Data formats:
{
"Attachment": {
"action": "attach",
"joint": "Hips",
"options": {
"translation": {
"x": 0,
"y": -0.11,
"z": 0.04
}
}
}
}
{
"Attachment": {
"action": "attach",
"joint": "[LR]Hips",
"snapDistance": 0.31,
"options": {
"translation": {
"x": 0,
"y": -0.11,
"z": 0.04
}
}
}
}
{
"Attachment": {
"action": "clear",
"joint": "Hips"
}
}
{
"Attachment": {
"action": "clear",
"joint": "[LR]ForeArm"
}
}
*/
(function() {
var _entityID = null;
var _isGrabbing = false;
var _attachmentData = null;
var _leftRightAttachToggle = false;
var DEFAULT_SNAP_DISTANCE = 0.3;
var HAND_LEFT = 0;
var HAND_RIGHT = 1;
var LEFT_RIGHT_PLACEHOLDER = '[LR]';
var ATTACH_SOUND = SoundCache.getSound(Script.resolvePath('sound/attach_sound_1.wav'));
var DETACH_SOUND = SoundCache.getSound(Script.resolvePath('sound/detach.wav'));
var getUserData = function() {
try {
return JSON.parse(Entities.getEntityProperties(_entityID, 'userData').userData);
} catch (e) {
// e
print('Could not retrieve valid userData');
}
return null;
};
var getAttachmentData = function() {
var userDataObject = getUserData();
if (userDataObject === null || userDataObject.Attachment === undefined) {
return null;
}
return userDataObject.Attachment;
};
this.preload = function(entityID) {
_entityID = entityID;
print('loaded ' + entityID);
};
function attachmentAction(joint) {
var attachmentData = getAttachmentData();
if (attachmentData === null) {
return;
}
var otherJoint = null;
if (joint === undefined) {
if (attachmentData.joint.indexOf(LEFT_RIGHT_PLACEHOLDER) !== -1) {
joint = attachmentData.joint.replace(LEFT_RIGHT_PLACEHOLDER, _leftRightAttachToggle ? 'Left' : 'Right');
print('joint = ' + joint);
otherJoint = attachmentData.joint.replace(LEFT_RIGHT_PLACEHOLDER, _leftRightAttachToggle ? 'Right' : 'Left');
print('otherJoint = ' + otherJoint);
} else {
joint = attachmentData.joint;
}
// flip the state if attaching
if (attachmentData.action === 'attach') {
_leftRightAttachToggle = !_leftRightAttachToggle;
}
}
var currentAttachments = MyAvatar.getAttachmentsVariant();
var newAttachments = [];
currentAttachments.forEach(function(attachment) {
// do not add the current joint data to the list of the joint that we are changing
if (attachment.jointName !== joint && (attachmentData.action === 'attach' || attachment.jointName !== otherJoint)) {
newAttachments.push(attachment);
}
});
if (attachmentData.action === 'attach') {
var attachmentModel = Entities.getEntityProperties(_entityID, 'modelURL').modelURL;
var newAttachment = {
jointName: joint,
modelUrl: attachmentModel
};
for (var key in attachmentData.options) {
if (attachmentData.options.hasOwnProperty(key)) {
newAttachment[key] = attachmentData.options[key];
}
}
newAttachments.push(newAttachment);
if (ATTACH_SOUND.downloaded) {
Audio.playSound(ATTACH_SOUND, {
position: Entities.getEntityProperties(_entityID, 'position').position,
volume: 0.2,
localOnly: true
});
}
var modelPathParts = attachmentModel.split('/');
var fileName = modelPathParts[modelPathParts.length - 1];
UserActivityLogger.logAction('attachmentItemScript_attach', {
joint: joint,
model: fileName
});
} else if (attachmentData.action === 'clear') {
if (DETACH_SOUND.downloaded) {
Audio.playSound(DETACH_SOUND, {
position: Entities.getEntityProperties(_entityID, 'position').position,
volume: 0.4,
localOnly: true
});
}
var joints = [joint];
if (otherJoint !== null) {
joints.push(joint);
}
UserActivityLogger.logAction("attachmentItemScript_detach", {
joints: joints
});
}
MyAvatar.setAttachmentsVariant(newAttachments);
}
this.startFarTrigger = function(entityID, args) {
attachmentAction();
};
this.startNearGrab = function(entityID, args) {
print('NearGrabStarting ' + JSON.stringify(args));
_isGrabbing = true;
_attachmentData = getAttachmentData();
};
this.continueNearGrab = function(entityID, args) {
if (_isGrabbing && _attachmentData !== null) {
print('NearGrabHappening ' + JSON.stringify(args));
var snapDistance = _attachmentData.snapDistance !== undefined ? _attachmentData.snapDistance :
DEFAULT_SNAP_DISTANCE;
var entityPosition = Entities.getEntityProperties(entityID, 'position').position;
var joints = [];
var closestJoint = null;
if (_attachmentData.joint.indexOf(LEFT_RIGHT_PLACEHOLDER) !== -1) {
joints.push(_attachmentData.joint.replace(LEFT_RIGHT_PLACEHOLDER, 'Left'));
joints.push(_attachmentData.joint.replace(LEFT_RIGHT_PLACEHOLDER, 'Right'));
} else {
joints.push(_attachmentData.joint);
}
joints.forEach(function(joint) {
var targetJointPosition = MyAvatar.getJointPosition(joint);
var distance = Vec3.distance(entityPosition, targetJointPosition);
if (distance < snapDistance && (closestJoint === null || distance < closestJoint.distance)) {
closestJoint = {
name: joint,
distance: distance
};
}
});
if (closestJoint !== null) {
print('attach' + closestJoint.name);
attachmentAction(closestJoint.name);
Controller.triggerShortHapticPulse(0.3, args[0] === 'left' ? HAND_LEFT : HAND_RIGHT);
Entities.deleteEntity(_entityID);
}
/*
if (Vec3.distance(entityPosition, targetJointPosition) < snapDistance) {
print('attach');
attachmentAction();
Entities.deleteEntity(_entityID);
}*/
}
};
this.releaseGrab = function(entityID, args) {
if (_isGrabbing) {
_isGrabbing = false;
print('ReleaseGrab ' + JSON.stringify(args));
Entities.deleteEntity(_entityID);
}
};
this.clickReleaseOnEntity = function(entityID, mouseEvent) {
if (mouseEvent.isLeftButton) {
attachmentAction();
}
};
});