(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); })();