Merge pull request #11062 from rabelaiis/21479

Make Xylophone mallets equipable, make the mallets provide haptic fee…
This commit is contained in:
Melissa Brown 2017-08-01 17:05:23 -07:00 committed by GitHub
commit c83caaacf5
4 changed files with 148 additions and 95 deletions

View file

@ -1,34 +0,0 @@
//
// pUtils.js
//
// Created by Patrick Gosch on 03/28/2017
// 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
//
getEntityTextures = function(id) {
var results = null;
var properties = Entities.getEntityProperties(id, "textures");
if (properties.textures) {
try {
results = JSON.parse(properties.textures);
} catch (err) {
logDebug(err);
logDebug(properties.textures);
}
}
return results ? results : {};
};
setEntityTextures = function(id, textureList) {
var json = JSON.stringify(textureList);
Entities.editEntity(id, {textures: json});
};
editEntityTextures = function(id, textureName, textureURL) {
var textureList = getEntityTextures(id);
textureList[textureName] = textureURL;
setEntityTextures(id, textureList);
};

View file

@ -9,10 +9,10 @@
// //
(function() { (function() {
Script.include(Script.resolvePath("pUtils.js")); var TIMEOUT = 50; // at 30 ms, the key's color sometimes fails to switch when hit
var TIMEOUT = 150; var TEXTURE_GRAY = Script.resolvePath("xylotex_bar_gray.png");
var TEXGRAY = Script.resolvePath("xylotex_bar_gray.png"); var TEXTURE_BLACK = Script.resolvePath("xylotex_bar_black.png");
var TEXBLACK = Script.resolvePath("xylotex_bar_black.png"); var IS_DEBUG = false;
var _this; var _this;
function XylophoneKey() { function XylophoneKey() {
@ -22,7 +22,7 @@
XylophoneKey.prototype = { XylophoneKey.prototype = {
sound: null, sound: null,
isWaiting: false, isWaiting: false,
homePos: null, homePosition: null,
injector: null, injector: null,
preload: function(entityID) { preload: function(entityID) {
@ -34,31 +34,66 @@
collisionWithEntity: function(thisEntity, otherEntity, collision) { collisionWithEntity: function(thisEntity, otherEntity, collision) {
if (collision.type === 0) { if (collision.type === 0) {
_this.hit(); _this.hit(otherEntity);
} }
}, },
clickDownOnEntity: function() { clickDownOnEntity: function(otherEntity) {
_this.hit(); _this.hit(otherEntity);
}, },
hit: function() { hit: function(otherEntity) {
if (!_this.isWaiting) { if (!_this.isWaiting) {
_this.isWaiting = true; _this.isWaiting = true;
_this.homePos = Entities.getEntityProperties(_this.entityID, ["position"]).position; _this.homePosition = Entities.getEntityProperties(_this.entityID, ["position"]).position;
_this.injector = Audio.playSound(_this.sound, {position: _this.homePos, volume: 1}); _this.injector = Audio.playSound(_this.sound, {position: _this.homePosition, volume: 1});
editEntityTextures(_this.entityID, "file5", TEXGRAY); _this.editEntityTextures(_this.entityID, "file5", TEXTURE_GRAY);
var HAPTIC_STRENGTH = 1;
var HAPTIC_DURATION = 20;
var userData = JSON.parse(Entities.getEntityProperties(otherEntity, 'userData').userData);
if (userData.hasOwnProperty('hand')){
Controller.triggerHapticPulse(HAPTIC_STRENGTH, HAPTIC_DURATION, userData.hand);
}
_this.timeout(); _this.timeout();
} }
}, },
timeout: function() { timeout: function() {
Script.setTimeout(function() { Script.setTimeout(function() {
editEntityTextures(_this.entityID, "file5", TEXBLACK); _this.editEntityTextures(_this.entityID, "file5", TEXTURE_BLACK);
_this.isWaiting = false; _this.isWaiting = false;
}, TIMEOUT); }, TIMEOUT);
},
getEntityTextures: function(id) {
var results = null;
var properties = Entities.getEntityProperties(id, "textures");
if (properties.textures) {
try {
results = JSON.parse(properties.textures);
} catch (err) {
if (IS_DEBUG) {
print(err);
print(properties.textures);
}
}
}
return results ? results : {};
},
setEntityTextures: function(id, textureList) {
var json = JSON.stringify(textureList);
Entities.editEntity(id, {textures: json});
},
editEntityTextures: function(id, textureName, textureURL) {
var textureList = _this.getEntityTextures(id);
textureList[textureName] = textureURL;
_this.setEntityTextures(id, textureList);
}
}; };
return new XylophoneKey(); return new XylophoneKey();
}); });

View file

@ -0,0 +1,25 @@
//
// xylophoneMallet.js
//
// Created by Johnathan Franck on 07/30/2017
// 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
(function() {
function XylophoneMallet() {
}
XylophoneMallet.prototype = {
startEquip: function(entityID, args) {
var LEFT_HAND = 0;
var RIGHT_HAND = 1;
var userData = JSON.parse(Entities.getEntityProperties(entityID, 'userData').userData);
userData.hand = args[0] === "left" ? LEFT_HAND : RIGHT_HAND;
Entities.editEntity(entityID, {userData: JSON.stringify(userData)});
}
};
return new XylophoneMallet();
});

View file

@ -8,65 +8,70 @@
// 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
// //
var soundFiles = ["C4.wav", "D4.wav", "E4.wav", "F4.wav", "G4.wav", "A4.wav", "B4.wav", "C5.wav"]; var SOUND_FILES = ["C4.wav", "D4.wav", "E4.wav", "F4.wav", "G4.wav", "A4.wav", "B4.wav", "C5.wav"];
var keyModelURL = Script.resolvePath("xyloKey_2_a_e.fbx"); var KEY_MODEL_URL = Script.resolvePath("xyloKey_2_a_e.fbx");
var keyScriptURL = Script.resolvePath("xylophoneKey.js"); var KEY_SCRIPT_URL = Script.resolvePath("xylophoneKey.js");
var TEXBLACK = Script.resolvePath("xylotex_bar_black.png"); var MALLET_SCRIPT_URL = Script.resolvePath("xylophoneMallet.js");
var malletModelURL = Script.resolvePath("Mallet3-2pc.fbx"); var TEXTURE_BLACK = Script.resolvePath("xylotex_bar_black.png");
var malletModelColliderURL = Script.resolvePath("Mallet3-2bpc_phys.obj"); var MALLET_MODEL_URL = Script.resolvePath("Mallet3-2pc.fbx");
var MALLET_MODEL_COLLIDER_URL = Script.resolvePath("Mallet3-2bpc_phys.obj");
var FORWARD = { x: 0, y: 0, z: -1 };
var center = MyAvatar.position; var center = MyAvatar.position;
var fwd = {x:0, y:0, z:-1};
var xyloFramePos = Vec3.sum(center, Vec3.multiply(fwd, 0.8)); var XYLOPHONE_FORWARD_OFFSET = 0.8;
var xyloFrameID = Entities.addEntity( { var xylophoneFramePosition = Vec3.sum(center, Vec3.multiply(FORWARD, XYLOPHONE_FORWARD_OFFSET));
var xylophoneFrameID = Entities.addEntity({
name: "Xylophone", name: "Xylophone",
type: "Model", type: "Model",
modelURL: Script.resolvePath("xylophoneFrameWithWave.fbx"), modelURL: Script.resolvePath("xylophoneFrameWithWave.fbx"),
position: xyloFramePos, position: xylophoneFramePosition,
rotation: Quat.fromVec3Radians({x:0, y:Math.PI, z:0}), rotation: Quat.fromVec3Radians({ x: 0, y: Math.PI, z: 0 }),
shapeType: "static-mesh" shapeType: "static-mesh"
}); });
center.y += (0.45); // key Y offset from frame var KEY_Y_OFFSET = 0.45;
var keyPos, keyRot, ud, td, keyID; center.y += KEY_Y_OFFSET;
for (var i = 1; i <= soundFiles.length; i++) { var keyPosition, keyRotation, userData, textureData, keyID;
var ROTATION_START = 0.9;
var ROTATION_DELTA = 0.2;
for (var i = 1; i <= SOUND_FILES.length; i++) {
keyRot = Quat.fromVec3Radians({x:0, y:(0.9 - (i*0.2)), z:0}); keyRotation = Quat.fromVec3Radians({ x: 0, y: ROTATION_START - (i*ROTATION_DELTA), z: 0 });
keyPos = Vec3.sum(center, Vec3.multiplyQbyV(keyRot, fwd)); keyPosition = Vec3.sum(center, Vec3.multiplyQbyV(keyRotation, FORWARD));
ud = { userData = {
soundFile: soundFiles[i-1] soundFile: SOUND_FILES[i-1]
}; };
td = { textureData = {
"file4": Script.resolvePath("xylotex_bar" + i + ".png"), "file4": Script.resolvePath("xylotex_bar" + i + ".png"),
"file5": TEXBLACK "file5": TEXTURE_BLACK
}; };
keyID = Entities.addEntity( { keyID = Entities.addEntity({
name: ("XyloKey" + i), name: ("XyloKey" + i),
type: "Model", type: "Model",
modelURL: keyModelURL, modelURL: KEY_MODEL_URL,
position: keyPos, position: keyPosition,
rotation: keyRot, rotation: keyRotation,
shapeType: "static-mesh", shapeType: "static-mesh",
script: keyScriptURL, script: KEY_SCRIPT_URL,
textures: JSON.stringify(td), textures: JSON.stringify(textureData),
userData: JSON.stringify(ud), userData: JSON.stringify(userData),
parentID: xyloFrameID parentID: xylophoneFrameID
} ); });
} }
// if rezzed on/above something, wait until after model has loaded so you can read its dimensions then move object on to that surface. // if rezzed on/above something, wait until after model has loaded so you can read its dimensions then move object on to that surface.
var pickRay = {origin: center, direction: {x:0, y:-1, z:0}}; var pickRay = {origin: center, direction: {x: 0, y: -1, z: 0}};
var intersection = Entities.findRayIntersection(pickRay, true); var intersection = Entities.findRayIntersection(pickRay, true);
if (intersection.intersects && (intersection.distance < 10)) { if (intersection.intersects && (intersection.distance < 10)) {
var surfaceY = intersection.intersection.y; var surfaceY = intersection.intersection.y;
Script.setTimeout( function() { Script.setTimeout( function() {
// should add loop to check for fbx loaded instead of delay // should add loop to check for fbx loaded instead of delay
var xyloDimensions = Entities.getEntityProperties(xyloFrameID, ["dimensions"]).dimensions; var xylophoneDimensions = Entities.getEntityProperties(xylophoneFrameID, ["dimensions"]).dimensions;
xyloFramePos.y = surfaceY + (xyloDimensions.y/2); xylophoneFramePosition.y = surfaceY + (xylophoneDimensions.y/2);
Entities.editEntity(xyloFrameID, {position: xyloFramePos}); Entities.editEntity(xylophoneFrameID, {position: xylophoneFramePosition});
rezMallets(); rezMallets();
}, 2000); }, 2000);
} else { } else {
@ -75,28 +80,50 @@ if (intersection.intersects && (intersection.distance < 10)) {
} }
function rezMallets() { function rezMallets() {
var malletProps = { var malletProperties = {
name: "Xylophone Mallet", name: "Xylophone Mallet",
type: "Model", type: "Model",
modelURL: malletModelURL, modelURL: MALLET_MODEL_URL,
compoundShapeURL: malletModelColliderURL, compoundShapeURL: MALLET_MODEL_COLLIDER_URL,
collidesWith: "static,dynamic,kinematic,", collidesWith: "static,dynamic,kinematic",
collisionMask: 7, collisionMask: 7,
collisionsWillMove: 1, collisionsWillMove: 1,
dynamic: 1, dynamic: 1,
damping: 1, damping: 1,
angularDamping: 1, angularDamping: 1,
shapeType: "compound", shapeType: "compound",
userData: "{\"grabbableKey\":{\"grabbable\":true}}", script: MALLET_SCRIPT_URL,
dimensions: {"x": 0.057845603674650192, "y": 0.057845607399940491, "z": 0.30429631471633911} // not being set from fbx for some reason. userData: JSON.stringify({
grabbableKey: {
invertSolidWhileHeld: true
},
wearable: {
joints: {
LeftHand: [
{ x: 0, y: 0.2, z: 0.04 },
Quat.fromVec3Degrees({ x: 0, y: 90, z: 90 })
],
RightHand: [
{ x: 0, y: 0.2, z: 0.04 },
Quat.fromVec3Degrees({ x: 0, y: 90, z: 90 })
]
}
}
}),
dimensions: { "x": 0.057845603674650192, "y": 0.057845607399940491, "z": 0.30429631471633911 } // not being set from fbx for some reason.
}; };
malletProps.position = Vec3.sum(xyloFramePos, {x: 0.1, y: 0.55, z: 0}); var LEFT_MALLET_POSITION = { x: 0.1, y: 0.55, z: 0 };
malletProps.rotation = Quat.fromVec3Radians({x:0, y:Math.PI - 0.1, z:0}); var LEFT_MALLET_ROTATION = { x: 0, y: Math.PI - 0.1, z: 0 };
Entities.addEntity(malletProps); var RIGHT_MALLET_POSITION = { x: -0.1, y: 0.55, z: 0 };
var RIGHT_MALLET_ROTATION = { x: 0, y: Math.PI + 0.1, z: 0 };
malletProps.position = Vec3.sum(xyloFramePos, {x: -0.1, y: 0.55, z: 0}); malletProperties.position = Vec3.sum(xylophoneFramePosition, LEFT_MALLET_POSITION);
malletProps.rotation = Quat.fromVec3Radians({x:0, y:Math.PI + 0.1, z:0}); malletProperties.rotation = Quat.fromVec3Radians(LEFT_MALLET_ROTATION);
Entities.addEntity(malletProps); Entities.addEntity(malletProperties);
malletProperties.position = Vec3.sum(xylophoneFramePosition, RIGHT_MALLET_POSITION);
malletProperties.rotation = Quat.fromVec3Radians(RIGHT_MALLET_ROTATION);
Entities.addEntity(malletProperties);
Script.stop(); Script.stop();
} }