105 lines
No EOL
5.2 KiB
JavaScript
105 lines
No EOL
5.2 KiB
JavaScript
(function() {
|
|
var LOOKAT_MIX_ALPHA = 0.05;
|
|
var lookAtPoint = undefined;
|
|
var lookingAtAvatarID = undefined;
|
|
var lookingAvatarJointIndex = undefined;
|
|
var getNormalizedLookAtPoint = function(worldLookAtPoint) {
|
|
return Vec3.sum(MyAvatar.getHeadPosition(), Vec3.normalize(Vec3.subtract(worldLookAtPoint, MyAvatar.getHeadPosition())));
|
|
}
|
|
var interpolatedLookAt = getNormalizedLookAtPoint(MyAvatar.getHeadLookAt());
|
|
var mousePressEvent = function(event) {
|
|
if (!event.isLeftButton) return;
|
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
|
var intersection = AvatarManager.findRayIntersection({origin: pickRay.origin, direction: pickRay.direction}, [], [MyAvatar.sessionUUID], false);
|
|
lookingAtAvatarID = intersection.intersects ? intersection.avatarID : undefined;
|
|
if (!lookingAtAvatarID) {
|
|
intersection = Entities.findRayIntersection({origin: pickRay.origin, direction: pickRay.direction}, true);
|
|
lookAtPoint = intersection.intersection;
|
|
} else {
|
|
var avatar = AvatarList.getAvatar(lookingAtAvatarID);
|
|
console.log("Looking at avatar: " + avatar.displayName);
|
|
lookingAvatarJointIndex = intersection.jointIndex;
|
|
}
|
|
}
|
|
var avatarWeights = {};
|
|
var avatarsLoudness = 0.0;
|
|
var avatarTalking = false;
|
|
var isInterpolatingBack = false;
|
|
function updateAvatarWeights() {
|
|
var nearbyAvatars = AvatarManager.getAvatarsInRange(MyAvatar.position, 10.0);
|
|
for (var n = 0; n < nearbyAvatars.length; n++) {
|
|
if (nearbyAvatars[n] === MyAvatar.sessionUUID) {
|
|
continue;
|
|
}
|
|
var avatar = AvatarManager.getAvatar(nearbyAvatars[n]);
|
|
var distance = Vec3.distance(MyAvatar.position, avatar.position);
|
|
var loudnessAttenuation = (1.0 / distance) - 0.1;
|
|
var loudness = loudnessAttenuation * avatar.audioLoudness;
|
|
var TALKING_TAU = 0.01;
|
|
if (avatarWeights[avatar.sessionUUID] === undefined) {
|
|
avatarWeights[avatar.sessionUUID] = {"loudness": loudness , "position": avatar.position};
|
|
} else {
|
|
avatarWeights[avatar.sessionUUID].loudness = avatarWeights[avatar.sessionUUID].loudness + TALKING_TAU * (loudness - avatarWeights[avatar.sessionUUID].loudness);
|
|
avatarWeights[avatar.sessionUUID].position = avatar.position;
|
|
}
|
|
}
|
|
var avatarIDs = Object.keys(avatarWeights);
|
|
avatarsLoudness = 0.0;
|
|
for (var n = 0; n < avatarIDs.length; n++) {
|
|
if (nearbyAvatars.indexOf(avatarIDs[n]) == -1) {
|
|
delete avatarWeights[avatarIDs[n]];
|
|
} else {
|
|
avatarsLoudness += avatarWeights[avatarIDs[n]].loudness;
|
|
}
|
|
}
|
|
avatarTalking = avatarsLoudness > 5.0;
|
|
}
|
|
function getTalkingPoint() {
|
|
var avatarIDs = Object.keys(avatarWeights);
|
|
var weightedLookAtPoint = Vec3.ZERO;
|
|
if (avatarIDs.length == 0 || avatarsLoudness == 0.0) return undefined;
|
|
for (var n = 0; n < avatarIDs.length; n++) {
|
|
if (avatarWeights[avatarIDs[n]] != undefined) {
|
|
var relativePos = Vec3.subtract(avatarWeights[avatarIDs[n]].position, MyAvatar.position);
|
|
weightedLookAtPoint = Vec3.sum(weightedLookAtPoint, Vec3.multiply(relativePos, avatarWeights[avatarIDs[n]].loudness / avatarsLoudness));
|
|
}
|
|
}
|
|
var relativeMed = Vec3.multiply(weightedLookAtPoint, 1.0/avatarIDs.length);
|
|
return Vec3.sum(relativeMed, MyAvatar.position);
|
|
}
|
|
Script.update.connect(function() {
|
|
updateAvatarWeights();
|
|
lookAtPoint = Vec3.sum(getTalkingPoint(), {x: 0.0, y: 0.6, z: 0.0});
|
|
/*
|
|
if (lookAtPoint || lookingAtAvatarID) {
|
|
if (lookingAtAvatarID && !avatarTalking) {
|
|
lookAtPoint = AvatarList.getAvatar(lookingAtAvatarID).getJointPosition(lookingAvatarJointIndex);
|
|
}
|
|
var normalizedLookAt = getNormalizedLookAtPoint(lookAtPoint);
|
|
interpolatedLookAt = Vec3.mix(interpolatedLookAt, normalizedLookAt, LOOKAT_MIX_ALPHA);
|
|
MyAvatar.setHeadLookAt(interpolatedLookAt);
|
|
}
|
|
*/
|
|
|
|
if (avatarTalking && lookAtPoint) {
|
|
console.log(avatarsLoudness);
|
|
var normalizedLookAt = getNormalizedLookAtPoint(lookAtPoint);
|
|
interpolatedLookAt = Vec3.mix(interpolatedLookAt, normalizedLookAt, LOOKAT_MIX_ALPHA);
|
|
MyAvatar.setHeadLookAt(interpolatedLookAt);
|
|
isInterpolatingBack = true;
|
|
} else if (isInterpolatingBack) {
|
|
var normalizedLookAt = getNormalizedLookAtPoint(MyAvatar.getHeadLookAt());
|
|
interpolatedLookAt = Vec3.mix(interpolatedLookAt, normalizedLookAt, LOOKAT_MIX_ALPHA);
|
|
if (Vec3.distance(interpolatedLookAt, normalizedLookAt) < 0.01) {
|
|
isInterpolatingBack = false;
|
|
}
|
|
MyAvatar.setHeadLookAt(interpolatedLookAt);
|
|
} else {
|
|
interpolatedLookAt = MyAvatar.getHeadLookAt();
|
|
}
|
|
|
|
|
|
});
|
|
|
|
Controller.mousePressEvent.connect(mousePressEvent);
|
|
})(); |