@epicgames-ps/lib-pixelstreamingfrontend-ue5.4
Version:
Frontend library for Unreal Engine 5.4 Pixel Streaming
291 lines (269 loc) • 9.79 kB
text/typescript
// Copyright Epic Games, Inc. All Rights Reserved.
import { Logger } from '../Logger/Logger';
import { VideoPlayer } from '../VideoPlayer/VideoPlayer';
/**
* Converts coordinates from element relative coordinates to values normalized within the value range of a short (and back again)
*/
export class CoordinateConverter {
videoElementProvider: VideoPlayer;
videoElementParent: HTMLElement;
videoElement: HTMLVideoElement;
ratio: number;
normalizeAndQuantizeUnsignedFunc: (
x: number,
y: number
) => NormalizedQuantizedUnsignedCoord;
normalizeAndQuantizeSignedFunc: (
x: number,
y: number
) => NormalizedQuantizedSignedCoord;
denormalizeAndUnquantizeUnsignedFunc: (
x: number,
y: number
) => UnquantizedDenormalizedUnsignedCoord;
/**
* @param videoElementProvider - the div element that the video player will be injected into
*/
constructor(videoElementProvider: VideoPlayer) {
this.videoElementProvider = videoElementProvider;
this.normalizeAndQuantizeUnsignedFunc = () => {
throw new Error(
'Normalize and quantize unsigned, method not implemented.'
);
};
this.normalizeAndQuantizeSignedFunc = () => {
throw new Error(
'Normalize and unquantize signed, method not implemented.'
);
};
this.denormalizeAndUnquantizeUnsignedFunc = () => {
throw new Error(
'Denormalize and unquantize unsigned, method not implemented.'
);
};
}
/**
* The surface method for setterNormalizeAndQuantizeUnsigned
* @param x - x axis point
* @param y - y axis point
*/
normalizeAndQuantizeUnsigned(
x: number,
y: number
): NormalizedQuantizedUnsignedCoord {
return this.normalizeAndQuantizeUnsignedFunc(x, y);
}
/**
* The surface method for setterUnquantizeAndDenormalizeUnsigned
* @param x - x axis point
* @param y - y axis point
*/
unquantizeAndDenormalizeUnsigned(
x: number,
y: number
): UnquantizedDenormalizedUnsignedCoord {
return this.denormalizeAndUnquantizeUnsignedFunc(x, y);
}
/**
* The surface method for setterNormalizeAndQuantizeSigned
* @param x - x axis point
* @param y - y axis point
*/
normalizeAndQuantizeSigned(
x: number,
y: number
): NormalizedQuantizedSignedCoord {
return this.normalizeAndQuantizeSignedFunc(x, y);
}
/**
* set up the Normalize And Quantize methods based on the aspect ratio and the video player ratio
*/
setupNormalizeAndQuantize() {
this.videoElementParent =
this.videoElementProvider.getVideoParentElement();
this.videoElement = this.videoElementProvider.getVideoElement();
if (this.videoElementParent && this.videoElement) {
const playerWidth = this.videoElementParent.clientWidth || 1;
const playerHeight = this.videoElementParent.clientHeight || 1;
const videoWidth = this.videoElement.videoWidth || 1;
const videoHeight = this.videoElement.videoHeight || 1;
const playerAspectRatio = playerHeight / playerWidth;
const videoAspectRatio = videoHeight / videoWidth;
if (playerAspectRatio > videoAspectRatio) {
Logger.Log(
Logger.GetStackTrace(),
'Setup Normalize and Quantize for playerAspectRatio > videoAspectRatio',
6
);
this.ratio = playerAspectRatio / videoAspectRatio;
this.normalizeAndQuantizeUnsignedFunc = (
x: number,
y: number
) => this.normalizeAndQuantizeUnsignedPlayerBigger(x, y);
this.normalizeAndQuantizeSignedFunc = (x: number, y: number) =>
this.normalizeAndQuantizeSignedPlayerBigger(x, y);
this.denormalizeAndUnquantizeUnsignedFunc = (
x: number,
y: number
) => this.denormalizeAndUnquantizeUnsignedPlayerBigger(x, y);
} else {
Logger.Log(
Logger.GetStackTrace(),
'Setup Normalize and Quantize for playerAspectRatio <= videoAspectRatio',
6
);
this.ratio = videoAspectRatio / playerAspectRatio;
this.normalizeAndQuantizeUnsignedFunc = (
x: number,
y: number
) => this.normalizeAndQuantizeUnsignedPlayerSmaller(x, y);
this.normalizeAndQuantizeSignedFunc = (x: number, y: number) =>
this.normalizeAndQuantizeSignedPlayerSmaller(x, y);
this.denormalizeAndUnquantizeUnsignedFunc = (
x: number,
y: number
) => this.denormalizeAndUnquantizeUnsignedPlayerSmaller(x, y);
}
}
}
/**
* normalizeAndQuantizeUnsigned for playerAspectRatio > videoAspectRatio
* @param x - x axis point
* @param y - y axis point
*/
normalizeAndQuantizeUnsignedPlayerBigger(
x: number,
y: number
): NormalizedQuantizedUnsignedCoord {
const normalizedX = x / this.videoElementParent.clientWidth;
const normalizedY =
this.ratio * (y / this.videoElementParent.clientHeight - 0.5) + 0.5;
if (
normalizedX < 0.0 ||
normalizedX > 1.0 ||
normalizedY < 0.0 ||
normalizedY > 1.0
) {
return new NormalizedQuantizedUnsignedCoord(false, 65535, 65535);
} else {
return new NormalizedQuantizedUnsignedCoord(
true,
normalizedX * 65536,
normalizedY * 65536
);
}
}
/**
* unquantizeAndDenormalizeUnsigned for playerAspectRatio > videoAspectRatio
* @param x - x axis point
* @param y - y axis point
*/
denormalizeAndUnquantizeUnsignedPlayerBigger(x: number, y: number) {
const normalizedX = x / 65536;
const normalizedY = (y / 65536 - 0.5) / this.ratio + 0.5;
return new UnquantizedDenormalizedUnsignedCoord(
normalizedX * this.videoElementParent.clientWidth,
normalizedY * this.videoElementParent.clientHeight
);
}
/**
* normalizeAndQuantizeSigned for playerAspectRatio > videoAspectRatio
* @param x - x axis point
* @param y - y axis point
*/
normalizeAndQuantizeSignedPlayerBigger(x: number, y: number) {
const normalizedX = x / (0.5 * this.videoElementParent.clientWidth);
const normalizedY =
(this.ratio * y) / (0.5 * this.videoElementParent.clientHeight);
return new NormalizedQuantizedSignedCoord(
normalizedX * 32767,
normalizedY * 32767
);
}
/**
* normalizeAndQuantizeUnsigned for playerAspectRatio <= videoAspectRatio
* @param x - x axis point
* @param y - y axis point
*/
normalizeAndQuantizeUnsignedPlayerSmaller(x: number, y: number) {
const normalizedX =
this.ratio * (x / this.videoElementParent.clientWidth - 0.5) + 0.5;
const normalizedY = y / this.videoElementParent.clientHeight;
if (
normalizedX < 0.0 ||
normalizedX > 1.0 ||
normalizedY < 0.0 ||
normalizedY > 1.0
) {
return new NormalizedQuantizedUnsignedCoord(false, 65535, 65535);
} else {
return new NormalizedQuantizedUnsignedCoord(
true,
normalizedX * 65536,
normalizedY * 65536
);
}
}
/**
* unquantizeAndDenormalizeUnsigned for playerAspectRatio <= videoAspectRatio
* @param x - x axis point
* @param y - y axis point
*/
denormalizeAndUnquantizeUnsignedPlayerSmaller(x: number, y: number) {
const normalizedX = (x / 65536 - 0.5) / this.ratio + 0.5;
const normalizedY = y / 65536;
return new UnquantizedDenormalizedUnsignedCoord(
normalizedX * this.videoElementParent.clientWidth,
normalizedY * this.videoElementParent.clientHeight
);
}
/**
* normalizeAndQuantizeSigned for playerAspectRatio <= videoAspectRatio
* @param x - x axis point
* @param y - y axis point
*/
normalizeAndQuantizeSignedPlayerSmaller(x: number, y: number) {
const normalizedX =
(this.ratio * x) / (0.5 * this.videoElementParent.clientWidth);
const normalizedY = y / (0.5 * this.videoElementParent.clientHeight);
return new NormalizedQuantizedSignedCoord(
normalizedX * 32767,
normalizedY * 32767
);
}
}
/**
* A class for NormalizeAndQuantizeUnsigned objects
*/
export class NormalizedQuantizedUnsignedCoord {
inRange: boolean;
x: number;
y: number;
constructor(inRange: boolean, x: number, y: number) {
this.inRange = inRange;
this.x = x;
this.y = y;
}
}
/**
* A class for UnquantizedAndDenormalizeUnsigned objects
*/
export class UnquantizedDenormalizedUnsignedCoord {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
/**
* A class for NormalizedQuantizedSignedCoord objects
*/
export class NormalizedQuantizedSignedCoord {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}