UNPKG

sparkar-screen

Version:

A tool to accessing to display information in Spark AR

315 lines (314 loc) 14.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPerspectiveScale = exports.worldToPercet = exports.worldToPercent = exports.worldToCanvas = exports.worldToFocalPlane = exports.cameraTransformToWrold = exports.cameraTransformToCanvas = exports.cameraTransformToPercent = exports.cameraTransformToFocalPlane = exports.cameraTransformToFocalDistance = exports.getResolution = exports.getHeight = exports.getWidth = exports.getFullscreenSize = exports.focalPlaneToCanvas = exports.canvasToFocalPlane = exports.focalPlaneToPercent = exports.focalPlaneYToPercent = exports.focalPlaneXToPercent = exports.canvasToPercent = exports.canvasToPercentY = exports.canvasToPercentX = exports.percentToCanvas = exports.percentToCanvasY = exports.percentToCanvasX = exports.percentToFocalPlane = exports.percentToFocalPlaneY = exports.percentToFocalPlaneX = exports.screenScale = exports.height = exports.width = exports.createScaler = void 0; const Reactive_1 = __importDefault(require("Reactive")); const CameraInfo_1 = __importDefault(require("CameraInfo")); const Units_1 = __importDefault(require("Units")); const Scene_1 = __importDefault(require("Scene")); const mainCamera = Scene_1.default.root.findFirst('Camera'); const units = Units_1.default.cm(10); const fieldOfView = mainCamera.then(camera => camera.fieldOfView ? camera.fieldOfView : Reactive_1.default.val(86)); class Scaler { constructor(baseWidth, baseHeight) { this.baseWidth = baseWidth; this.baseHeight = baseHeight; } get baseRatio() { return Reactive_1.default.div(this.baseHeight, this.baseWidth); } get realRatio() { return exports.height.div(exports.width); } get multiplier() { return this.baseRatio.div(this.realRatio); } get scaleMultiplier() { return Reactive_1.default.pack3(this.multiplier, this.multiplier, this.multiplier); } autoScaleObject(sceneObject, preferredX, preferredY, preferredZ) { const x = preferredX ? preferredX : sceneObject.transform.scaleX.pinLastValue(); const y = preferredY ? preferredY : sceneObject.transform.scaleY.pinLastValue(); const z = preferredZ ? preferredZ : sceneObject.transform.scaleZ.pinLastValue(); sceneObject.transform.scale = this.scaleMultiplier.mul(Reactive_1.default.pack3(x, y, z)); } } function createScaler(baseWidth, baseHeight) { return new Scaler(baseWidth, baseHeight); } exports.createScaler = createScaler; /** * The width of the screen resolution in ScalarSignal. */ exports.width = CameraInfo_1.default.previewSize.width; /** * The height of the screen resolution in ScalarSignal. */ exports.height = CameraInfo_1.default.previewSize.height; /** * CameraInfo.previewScreenScale. */ exports.screenScale = CameraInfo_1.default.previewScreenScale; /** * The percentage [0-1] of position X in screen coordinates. `0` is left, `1` is right. */ async function percentToFocalPlaneX(percent) { const fullscreen = await getFullscreenSize(); const widthMax = Reactive_1.default.div(exports.width, exports.height).mul(fullscreen.y.mul(0.5 * units)); return Reactive_1.default.mul(percent, widthMax.mul(2)).sub(widthMax); } exports.percentToFocalPlaneX = percentToFocalPlaneX; /** * The percentage [0-1] of position Y in screen coordinates. `0` is top, `1` is bottom. */ async function percentToFocalPlaneY(percent) { const fullscreen = await getFullscreenSize(); return Reactive_1.default.mul(percent, fullscreen.y.mul(-units)).add(fullscreen.y.mul(0.5 * units)); } exports.percentToFocalPlaneY = percentToFocalPlaneY; /** * The percentage [0-1] of position in screen coordinates. `(0, 0)` is left top, `(1, 1)` is right bottom. */ async function percentToFocalPlane(percentLocation) { const [x, y] = await Promise.all([percentToFocalPlaneX(percentLocation.x), percentToFocalPlaneY(percentLocation.y)]); return Reactive_1.default.pack3(x, y, 0); } exports.percentToFocalPlane = percentToFocalPlane; /** * The percentage [0-1] of position X in canvas coordinates. `0` is left, `1` is right. */ function percentToCanvasX(percent) { return exports.width.div(exports.screenScale).mul(percent); } exports.percentToCanvasX = percentToCanvasX; /** * The percentage [0-1] of position Y in canvas coordinates. `0` is top, `1` is bottom. */ function percentToCanvasY(percent) { return exports.height.div(exports.screenScale).mul(percent); } exports.percentToCanvasY = percentToCanvasY; /** * The percentage [0-1] of position in canvas coordinates. `(0, 0)` is left top, `(1, 1)` is right bottom. */ function percentToCanvas(location) { return Reactive_1.default.pack3(percentToCanvasX(location.x), percentToCanvasY(location.y), 0); } exports.percentToCanvas = percentToCanvas; function canvasToPercentX(positionX, centerRef) { if (centerRef && centerRef.width) { return Reactive_1.default.add(positionX, centerRef.width.mul(0.5)).div(exports.width).mul(exports.screenScale); } else { return Reactive_1.default.div(positionX, exports.width).mul(exports.screenScale); } } exports.canvasToPercentX = canvasToPercentX; function canvasToPercentY(positionY, centerRef) { if (centerRef && centerRef.height) { return Reactive_1.default.add(positionY, centerRef.height.mul(0.5)).div(exports.height).mul(exports.screenScale); } else { return Reactive_1.default.div(positionY, exports.height).mul(exports.screenScale); } } exports.canvasToPercentY = canvasToPercentY; function canvasToPercent(location, centerRef) { return Reactive_1.default.pack2(canvasToPercentX(location.x, centerRef), canvasToPercentY(location.y, centerRef)); } exports.canvasToPercent = canvasToPercent; async function focalPlaneXToPercent(positionX) { const fullscreen = await getFullscreenSize(); const widthMax = Reactive_1.default.div(exports.width, exports.height).mul(fullscreen.y.mul(0.5 * units)); return Reactive_1.default.add(positionX, widthMax).div(widthMax.mul(2)); } exports.focalPlaneXToPercent = focalPlaneXToPercent; async function focalPlaneYToPercent(positionY) { const fullscreen = await getFullscreenSize(); return fullscreen.y.mul(0.5 * units).sub(positionY).div(fullscreen.y.mul(units)); } exports.focalPlaneYToPercent = focalPlaneYToPercent; async function focalPlaneToPercent(position) { const [x, y] = await Promise.all([focalPlaneXToPercent(position.x), focalPlaneYToPercent(position.y)]); return Reactive_1.default.pack2(x, y); } exports.focalPlaneToPercent = focalPlaneToPercent; /** * Convert canvas position to focal plane position. */ async function canvasToFocalPlane(position, centerRef) { const percent = canvasToPercent(position, centerRef); return await percentToFocalPlane(percent); } exports.canvasToFocalPlane = canvasToFocalPlane; async function focalPlaneToCanvas(position, centerRef) { const percent = await focalPlaneToPercent(position); if (centerRef && centerRef.width && centerRef.height) { return Reactive_1.default.pack3(percentToCanvasX(percent.x).sub(centerRef.width.mul(0.5)), percentToCanvasY(percent.y).sub(centerRef.height.mul(0.5)), 0); } else { return Reactive_1.default.pack3(percentToCanvasX(percent.x), percentToCanvasY(percent.y), 0); } } exports.focalPlaneToCanvas = focalPlaneToCanvas; /** * The fullscreen size on Focal Plane. */ async function getFullscreenSize() { const camera = await mainCamera; return Reactive_1.default.pack3(camera.focalPlane.width.mul(Units_1.default.m(10)), camera.focalPlane.height.mul(Units_1.default.m(10)), 1); } exports.getFullscreenSize = getFullscreenSize; /** * The current width of the screen window in pixels. */ function getWidth() { return new Promise(resolve => { exports.width.monitor({ 'fireOnInitialValue': true }).select('newValue').take(1).subscribe(resolve); }); } exports.getWidth = getWidth; /** * The current height of the screen window in pixels. */ function getHeight() { return new Promise(resolve => { exports.height.monitor({ 'fireOnInitialValue': true }).select('newValue').take(1).subscribe(resolve); }); } exports.getHeight = getHeight; /** * Represents a display resolution. */ async function getResolution() { const [w, h] = await Promise.all([getWidth(), getHeight(),]); return { width: w, height: h, toString() { return `${w} x ${h}`; }, }; } exports.getResolution = getResolution; /** * Get the same position as faceMesh from tracker's cameraTransform. */ async function cameraTransformToFocalDistance(cameraTransformPosition) { const camera = await mainCamera; return cameraTransformPosition.add(Reactive_1.default.pack3(0, 0, camera.focalPlane.distance)); } exports.cameraTransformToFocalDistance = cameraTransformToFocalDistance; /** * Get screen position of tracker's cameraTransform. */ async function cameraTransformToFocalPlane(cameraTransformPosition) { const percent = await worldToPixel01(cameraTransformPosition); const [x, y] = await Promise.all([percentToFocalPlaneX(percent.x), percentToFocalPlaneY(percent.y)]); return Reactive_1.default.pack3(x, y.neg(), 0); } exports.cameraTransformToFocalPlane = cameraTransformToFocalPlane; async function cameraTransformToPercent(cameraTransformPosition) { const focalPlane = await cameraTransformToFocalPlane(cameraTransformPosition); return await focalPlaneToPercent(focalPlane); } exports.cameraTransformToPercent = cameraTransformToPercent; /** * Convert position of tracker's cameraTransform to canvas. * @param {SceneObjectBase=} centerRef Reference object's width and height to offset. */ async function cameraTransformToCanvas(cameraTransformPosition, centerRef) { const percent = await worldToPixel01(cameraTransformPosition); if (centerRef && centerRef.width && centerRef.height) { return Reactive_1.default.pack3(percentToCanvasX(percent.x).sub(centerRef.width.mul(0.5)), percentToCanvasY(percent.y).neg().add(exports.height.div(exports.screenScale)).sub(centerRef.height.mul(0.5)), 0); } else { return Reactive_1.default.pack3(percentToCanvasX(percent.x), percentToCanvasY(percent.y).neg(), 0); } } exports.cameraTransformToCanvas = cameraTransformToCanvas; /** * Convert position of tracker's cameraTransform to world. */ async function cameraTransformToWrold(cameraTransformPosition) { const camera = await mainCamera; return camera.worldTransform.applyToPoint(cameraTransformPosition); } exports.cameraTransformToWrold = cameraTransformToWrold; /** * Convert position of worldTransform to focal plane position. */ async function worldToFocalPlane(worldPosition) { const position = await inverseWorldTransform(worldPosition); const percent = await worldToPixel01(position); const [x, y] = await Promise.all([percentToFocalPlaneX(percent.x), percentToFocalPlaneY(percent.y)]); return Reactive_1.default.pack3(x, y.neg(), 0); } exports.worldToFocalPlane = worldToFocalPlane; /** * Convert position of worldTransform to canvas position. */ async function worldToCanvas(worldPosition, centerRef) { const position = await inverseWorldTransform(worldPosition); const percent = await worldToPixel01(position); if (centerRef && centerRef.width && centerRef.height) { return Reactive_1.default.pack3(percentToCanvasX(percent.x).sub(centerRef.width.mul(0.5)), percentToCanvasY(percent.y).neg().add(exports.height.div(exports.screenScale)).sub(centerRef.height.mul(0.5)), 0); } else { return Reactive_1.default.pack3(percentToCanvasX(percent.x), percentToCanvasY(percent.y).neg(), 0); } } exports.worldToCanvas = worldToCanvas; /** * Convert position of worldTransform to focal position in [0-1] percent. */ async function worldToPercent(worldPosition) { const position = await worldToFocalPlane(worldPosition); return await focalPlaneToPercent(position); } exports.worldToPercent = worldToPercent; /** * Convert position of worldTransform to focal position in [0-1] percent. * @deprecated It's typo of `worldToPercent` */ async function worldToPercet(worldPosition) { return worldToPercent(worldPosition); } exports.worldToPercet = worldToPercet; /** * Get the scale that make the plane in screen space look the same size as the plane in 3d space. */ async function getPerspectiveScale(worldPosition) { const [camera, fov] = await Promise.all([mainCamera, fieldOfView,]); const distance = camera.worldTransform.position.distance(worldPosition); const scale = Reactive_1.default.div(1, distance).div(Reactive_1.default.tan(fov / 2 * 0.0174532925).mul(2)); return Reactive_1.default.pack3(scale, scale, scale); } exports.getPerspectiveScale = getPerspectiveScale; /** * Convert world position to camera position. */ async function inverseWorldTransform(worldPosition) { const camera = await mainCamera; return camera.worldTransform.inverse().applyToPoint(worldPosition); } /** * Convert position of worldTransform to screen position in 0-1. */ async function worldToPixel01(worldPosition) { const pixel = await worldToPixel(worldPosition); const perX = pixel.x.div(exports.width.mul(exports.screenScale)); const perY = pixel.y.div(exports.height.mul(exports.screenScale)); return Reactive_1.default.point2d(perX, perY); } /** * Convert position of worldTransform to screen position. */ async function worldToPixel(worldPosition) { const camera = await mainCamera; const widthTan = camera.focalPlane.width.div(2).div(camera.focalPlane.distance); const heightTan = camera.focalPlane.height.div(2).div(camera.focalPlane.distance); const scaled_width = exports.width.mul(exports.screenScale); const scaled_height = exports.height.mul(exports.screenScale); const focalPlaneWidthAtObject = worldPosition.z.mul(widthTan).mul(2); const focalPlaneHeightAtObject = worldPosition.z.mul(heightTan).mul(2); const pixelX = scaled_width.div(focalPlaneWidthAtObject).mul(worldPosition.x).neg().add(scaled_width.div(2)); const pixelY = scaled_height.div(focalPlaneHeightAtObject).mul(worldPosition.y).neg().add(scaled_height.div(2)); return Reactive_1.default.point2d(pixelX, pixelY); }