mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 11:37:58 +02:00
Merge pull request #11062 from rabelaiis/21479
Make Xylophone mallets equipable, make the mallets provide haptic fee…
This commit is contained in:
commit
c83caaacf5
4 changed files with 148 additions and 95 deletions
|
@ -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);
|
|
||||||
};
|
|
|
@ -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();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
25
unpublishedScripts/marketplace/xylophone/xylophoneMallet.js
Normal file
25
unpublishedScripts/marketplace/xylophone/xylophoneMallet.js
Normal 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();
|
||||||
|
});
|
|
@ -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();
|
||||||
}
|
}
|
Loading…
Reference in a new issue