content/hifi-public/sam/scripts/focus/focus.js
Dale Glass 0d14e5a379 Initial data.
Needs a lot of cleanup. Data has been de-duplicated, and where identical copies existed, one of them
has been replaced with a symlink.

Some files have been excluded, such as binaries, installers and debug dumps. Some of that may still
be present.
2022-02-13 18:59:11 +01:00

304 lines
No EOL
8.8 KiB
JavaScript

"use strict";
//
// focus.js
// Sam Cake Lab
//
// 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 Cam() {
this._enabled = false;
this._aspectRatio = 2.0;
this._height = 1024;
this._fov = 10.0;
this._exposure = 0.0;
this._position = Camera.position;
this._orientation = Camera.orientation;
this._name = "focus";
this._shotNum = 0;
};
Cam.prototype = {
init: function() {
this.updateImageSize();
this.updateTransform();
this.updateFov();
this.updateExposure();
this.updateTone();
},
// Image Size
aspectRatio: function() { return this._aspectRatio; },
height: function() { return this._height; },
width: function() { return this._height * this._aspectRatio; },
updateImageSize: function() {
this.config().resetSizeSpectatorCamera(this.width(), this.height());
},
setAspectRatio: function(ar) {
ar = Math.min(10, Math.max(ar, 0.1))
this.updateImageSize();
},
setHeight: function(h) {
this._height = Math.max(1, h)
this.updateImageSize();
},
setWidth: function(w) {
this._height = Math.max(1, w) / this.aspectRatio();
this.updateImageSize();
},
setWidthHeight: function(w, h) {
this._height = Math.max(1, h);
this._aspectRatio = Math.max(1, w) / this._height;
this.updateImageSize();
},
// Activation
config: function() {
return Render.getConfig("SecondaryCamera");
},
enable: function() {
this._enabled = true;
this.config().enableSecondaryCameraRenderConfigs(true);
},
disable: function() {
this._enabled = false;
this.config().enableSecondaryCameraRenderConfigs(false);
},
// Transform
position: function() { return this._position; },
orientation: function() { return this._orientation; },
updateTransform: function() {
this.config().position = this._position;
this.config().orientation = this._orientation;
},
setTransform: function(pos, ori) {
this._position = pos;
this._orientation = ori;
this.updateTransform();
},
setPosition: function(pos) {
this._position = pos;
this.updateTransform();
},
setOrientation: function(ori) {
this._orientation = ori;
this.updateTransform();
},
// Focus
fov: function() { return this._fov; },
updateFov: function() {
this.config().vFoV = this._fov;
},
setFov: function(fov) {
this._fov = Math.min(180, Math.max(0.1, fov));
this.updateFov();
},
// Exposure
exposure: function() { return this._exposure; },
updateExposure: function() {
Render.getConfig("SecondaryCameraJob.ToneMapping").exposure = this._exposure;
},
setExposure: function(exposure) {
this._exposure = Math.min(5, Math.max(-5, exposure));
this.updateExposure();
},
// Tone
updateTone: function() {
Render.getConfig("SecondaryCameraJob.ToneMapping").curve = 0;
},
// Shot!
shoot: function() {
var d = new Date();
var name = this._name + '-' + d.getMonth() + '.' + + d.getDate() + '-' + d.getHours() + '.' + d.getMinutes() + '-' + this._shotNum;
Window.takeSecondaryCameraSnapshot(false, name);
this._shotNum++;
this.updateTone();
},
};
var cam = new Cam();
cam.init();
var overlays = [];
var overlayFrames = {};
var viewFinderOverlay = false;
var DIM = {x: 1.0, y: -1.0, z: 0.0};
var avatarHeadJoint = MyAvatar.getJointIndex("Head");
function getCamePos(i) {
return Vec3.sum(Camera.position, Vec3.multiplyQbyV(Camera.orientation, { x: -0.5 + 0.2 * i, y: -0.3, z: -1 }))
}
function updateFrames() {
for (var i = 0; i < overlays.length; i++) {
overlayFrames[overlays[i]] = { position: getCamePos(i), rotation: Camera.orientation }
}
Overlays.editOverlays(overlayFrames)
}
function updateOverlay() {
// The only way I found to update the viewFinderOverlay without turning the spectator camera on and off is to delete and recreate the
// overlay, which is inefficient but resizing the window shouldn't be performed often
if (viewFinderOverlay) {
Overlays.deleteOverlay(viewFinderOverlay);
}
viewFinderOverlay = Overlays.addOverlay("image3d", {
url: "resource://spectatorCameraFrame",
emissive: true,
parentID: MyAvatar.SELF_ID,
parentJointIndex: -7,
alpha: 1,
localRotation: { w: 1, x: 0, y: 0, z: 0 },
localPosition: { x: 0, y: 0.0, z: -1.0 },
dimensions: DIM,
});
}
var accumulated = 0;
function theUpdate(deltaTime) {
accumulated += deltaTime;
if (accumulated > 1)
updateFrames()
cam.setTransform(Camera.position, Camera.orientation);
}
function takeShot() {
cam.shoot();
}
function turnOn() {
// createAppWindow();
cam.enable();
cam.setAspectRatio(2.0);
cam.setTransform(Camera.position, Camera.orientation);
updateOverlay()
Script.update.connect(theUpdate);
initUIFromCam();
}
function turnOff() {
// killAppWindow();
Script.update.disconnect(theUpdate);
cam.disable();
for (var i = 0; i < overlays.length; i++) {
Overlays.deleteOverlay(overlays[i]);
}
Overlays.deleteOverlay(viewFinderOverlay);
}
var AppUi = Script.require('appUi');
//*****************************************************
// THE APP TABLET ICON ON OFF + "?" + Date.now()
//*****************************************************
var TABLET_BUTTON_NAME = "Focus";
var ICON_URL = Script.resolvePath("./focus.svg");
var ACTIVE_ICON_URL = Script.resolvePath("./focus.svg");
function fromAppUI (message) {
if (message.focusApp !== undefined) {
print("fromAppUI: " + JSON.stringify(message))
switch (message.focusApp) {
case "takeShot":
takeShot();
break;
case "setFov":
cam.setFov(message.params[0]);
break;
case "setExposure":
cam.setExposure(message.params[0]);
break;
}
}
}
var UI_URL = Script.resolvePath("./focus.qml");
var appWindow = null
function createAppWindow() {
appWindow = Desktop.createWindow(UI_URL, {
title: 'Shot!',
flags: Desktop.ALWAYS_ON_TOP,
presentationMode: Desktop.PresentationMode.NATIVE,
size: {x: 300, y: 300}
});
appWindow.closed.connect(killAppWindow);
appWindow.fromQml.connect(fromAppUI);
}
function killAppWindow() {
if (appWindow !== null) {
appWindow.closed.disconnect(killAppWindow);
appWindow.fromQml.disconnect(fromAppUI);
appWindow.close()
appWindow = null
}
}
function sendToUI(message) {
if (appWindow) {
appWindow.sendToQml(message);
}
}
function initUIFromCam() {
sendToUI({ 'initFOV': cam.fov() });
sendToUI({ 'initExposure': cam.exposure() });
}
var ui;
function startup() {
ui = new AppUi({
buttonName: TABLET_BUTTON_NAME,
home: UI_URL,
onOpened: function () {
print("Hello Focus!");
turnOn()
},
onClosed: function () {
turnOff()
print("Bye Focus!");
},
onMessage: fromAppUI,
normalButton: ICON_URL,
activeButton: ACTIVE_ICON_URL
});
}
startup();
Script.scriptEnding.connect(function () {
turnOff()
});
}());