mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 21:16:00 +02:00
179 lines
5.2 KiB
JavaScript
179 lines
5.2 KiB
JavaScript
//
|
|
// Interaction.js
|
|
// scripts/interaction
|
|
//
|
|
// Created by Trevor Berninger on 3/20/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
|
|
//
|
|
|
|
(function(){
|
|
print("loading interaction script");
|
|
|
|
var Avatar = false;
|
|
var NPC = false;
|
|
var previousNPC = false;
|
|
var hasCenteredOnNPC = false;
|
|
var distance = 10;
|
|
var r = 8;
|
|
var player = false;
|
|
|
|
var baselineX = 0;
|
|
var baselineY = 0;
|
|
var nodRange = 20;
|
|
var shakeRange = 20;
|
|
|
|
var ticker = false;
|
|
var heartbeatTimer = false;
|
|
|
|
function callOnNPC(message) {
|
|
if(NPC)
|
|
Messages.sendMessage("interactionComs", NPC + ":" + message);
|
|
else
|
|
Messages.sendMessage("interactionComs", previousNPC + ":" + message);
|
|
}
|
|
|
|
LimitlessSpeechRecognition.onFinishedSpeaking.connect(function(speech) {
|
|
print("Got: " + speech);
|
|
callOnNPC("voiceData:" + speech);
|
|
});
|
|
|
|
LimitlessSpeechRecognition.onReceivedTranscription.connect(function(speech) {
|
|
callOnNPC("speaking");
|
|
});
|
|
|
|
function setBaselineRotations(rot) {
|
|
baselineX = rot.x;
|
|
baselineY = rot.y;
|
|
}
|
|
|
|
function findLookedAtNPC() {
|
|
var intersection = AvatarList.findRayIntersection({origin: MyAvatar.position, direction: Quat.getFront(Camera.getOrientation())}, true);
|
|
if (intersection.intersects && intersection.distance <= distance){
|
|
var npcAvatar = AvatarList.getAvatar(intersection.avatarID);
|
|
if (npcAvatar.displayName.search("NPC") != -1) {
|
|
setBaselineRotations(Quat.safeEulerAngles(Camera.getOrientation()));
|
|
return intersection.avatarID;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function isStillFocusedNPC() {
|
|
var avatar = AvatarList.getAvatar(NPC);
|
|
if (avatar) {
|
|
var avatarPosition = avatar.position;
|
|
return Vec3.distance(MyAvatar.position, avatarPosition) <= distance && Math.abs(Quat.dot(Camera.getOrientation(), Quat.lookAtSimple(MyAvatar.position, avatarPosition))) > 0.6;
|
|
}
|
|
return false; // NPC reference died. Maybe it crashed or we teleported to a new world?
|
|
}
|
|
|
|
function onWeLostFocus() {
|
|
print("lost NPC: " + NPC);
|
|
callOnNPC("onLostFocused");
|
|
var baselineX = 0;
|
|
var baselineY = 0;
|
|
}
|
|
|
|
function onWeGainedFocus() {
|
|
print("found NPC: " + NPC);
|
|
callOnNPC("onFocused");
|
|
var rotation = Quat.safeEulerAngles(Camera.getOrientation());
|
|
baselineX = rotation.x;
|
|
baselineY = rotation.y;
|
|
LimitlessSpeechRecognition.setListeningToVoice(true);
|
|
}
|
|
|
|
function checkFocus() {
|
|
var newNPC = findLookedAtNPC();
|
|
|
|
if (NPC && newNPC != NPC && !isStillFocusedNPC()) {
|
|
onWeLostFocus();
|
|
previousNPC = NPC;
|
|
NPC = false;
|
|
}
|
|
if (!NPC && newNPC != false) {
|
|
NPC = newNPC;
|
|
onWeGainedFocus();
|
|
}
|
|
}
|
|
|
|
function checkGesture() {
|
|
var rotation = Quat.safeEulerAngles(Camera.getOrientation());
|
|
|
|
var deltaX = Math.abs(rotation.x - baselineX);
|
|
if (deltaX > 180) {
|
|
deltaX -= 180;
|
|
}
|
|
var deltaY = Math.abs(rotation.y - baselineY);
|
|
if (deltaY > 180) {
|
|
deltaY -= 180;
|
|
}
|
|
|
|
if (deltaX >= nodRange && deltaY <= shakeRange) {
|
|
callOnNPC("onNodReceived");
|
|
} else if (deltaY >= shakeRange && deltaX <= nodRange) {
|
|
callOnNPC("onShakeReceived");
|
|
}
|
|
}
|
|
|
|
function tick() {
|
|
checkFocus();
|
|
if (NPC) {
|
|
checkGesture();
|
|
}
|
|
}
|
|
|
|
function heartbeat() {
|
|
callOnNPC("beat");
|
|
}
|
|
|
|
Messages.subscribe("interactionComs");
|
|
|
|
Messages.messageReceived.connect(function (channel, message, sender) {
|
|
if(channel === "interactionComs" && player) {
|
|
var codeIndex = message.search('clientexec');
|
|
if(codeIndex != -1) {
|
|
var code = message.substr(codeIndex+11);
|
|
Script.evaluate(code, '');
|
|
}
|
|
}
|
|
});
|
|
|
|
this.enterEntity = function(id) {
|
|
player = true;
|
|
print("Something entered me: " + id);
|
|
LimitlessSpeechRecognition.setAuthKey("testKey");
|
|
if (!ticker) {
|
|
ticker = Script.setInterval(tick, 333);
|
|
}
|
|
if(!heartbeatTimer) {
|
|
heartbeatTimer = Script.setInterval(heartbeat, 1000);
|
|
}
|
|
};
|
|
this.leaveEntity = function(id) {
|
|
LimitlessSpeechRecognition.setListeningToVoice(false);
|
|
player = false;
|
|
print("Something left me: " + id);
|
|
if (previousNPC)
|
|
Messages.sendMessage("interactionComs", previousNPC + ":leftArea");
|
|
if (ticker) {
|
|
ticker.stop();
|
|
ticker = false;
|
|
}
|
|
if (heartbeatTimer) {
|
|
heartbeatTimer.stop();
|
|
heartbeatTimer = false;
|
|
}
|
|
};
|
|
this.unload = function() {
|
|
print("Okay. I'm Unloading!");
|
|
if (ticker) {
|
|
ticker.stop();
|
|
ticker = false;
|
|
}
|
|
};
|
|
print("finished loading interaction script");
|
|
});
|