Refactor renderer initialization and domElement handling in RuntimeHost
This commit is contained in:
@@ -29,7 +29,7 @@ const FALLBACK_FACE_COLOR = 0x747d89;
|
|||||||
export class RuntimeHost {
|
export class RuntimeHost {
|
||||||
private readonly scene = new Scene();
|
private readonly scene = new Scene();
|
||||||
private readonly camera = new PerspectiveCamera(70, 1, 0.05, 1000);
|
private readonly camera = new PerspectiveCamera(70, 1, 0.05, 1000);
|
||||||
private readonly renderer = new WebGLRenderer({ antialias: true, alpha: true });
|
private readonly domElement: HTMLCanvasElement;
|
||||||
private readonly ambientLight = new AmbientLight();
|
private readonly ambientLight = new AmbientLight();
|
||||||
private readonly sunLight = new DirectionalLight();
|
private readonly sunLight = new DirectionalLight();
|
||||||
private readonly brushGroup = new Group();
|
private readonly brushGroup = new Group();
|
||||||
@@ -39,6 +39,7 @@ export class RuntimeHost {
|
|||||||
private readonly brushMeshes = new Map<string, Mesh<BoxGeometry, MeshStandardMaterial[]>>();
|
private readonly brushMeshes = new Map<string, Mesh<BoxGeometry, MeshStandardMaterial[]>>();
|
||||||
private readonly materialTextureCache = new Map<string, CachedMaterialTexture>();
|
private readonly materialTextureCache = new Map<string, CachedMaterialTexture>();
|
||||||
private readonly controllerContext: RuntimeControllerContext;
|
private readonly controllerContext: RuntimeControllerContext;
|
||||||
|
private readonly renderer: WebGLRenderer | null;
|
||||||
private resizeObserver: ResizeObserver | null = null;
|
private resizeObserver: ResizeObserver | null = null;
|
||||||
private animationFrame = 0;
|
private animationFrame = 0;
|
||||||
private previousFrameTime = 0;
|
private previousFrameTime = 0;
|
||||||
@@ -50,16 +51,25 @@ export class RuntimeHost {
|
|||||||
private currentRuntimeMessage: string | null = null;
|
private currentRuntimeMessage: string | null = null;
|
||||||
private currentFirstPersonTelemetry: FirstPersonTelemetry | null = null;
|
private currentFirstPersonTelemetry: FirstPersonTelemetry | null = null;
|
||||||
|
|
||||||
constructor() {
|
constructor(options: { enableRendering?: boolean } = {}) {
|
||||||
|
const enableRendering = options.enableRendering ?? true;
|
||||||
|
|
||||||
this.scene.add(this.ambientLight);
|
this.scene.add(this.ambientLight);
|
||||||
this.scene.add(this.sunLight);
|
this.scene.add(this.sunLight);
|
||||||
this.scene.add(this.brushGroup);
|
this.scene.add(this.brushGroup);
|
||||||
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
this.renderer = enableRendering ? new WebGLRenderer({ antialias: true, alpha: true }) : null;
|
||||||
this.renderer.setClearAlpha(0);
|
this.domElement = this.renderer?.domElement ?? document.createElement("canvas");
|
||||||
|
|
||||||
|
if (this.renderer !== null) {
|
||||||
|
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
||||||
|
this.renderer.setClearAlpha(0);
|
||||||
|
} else {
|
||||||
|
this.domElement.className = "runner-canvas__surface";
|
||||||
|
}
|
||||||
|
|
||||||
this.controllerContext = {
|
this.controllerContext = {
|
||||||
camera: this.camera,
|
camera: this.camera,
|
||||||
domElement: this.renderer.domElement,
|
domElement: this.domElement,
|
||||||
getRuntimeScene: () => {
|
getRuntimeScene: () => {
|
||||||
if (this.runtimeScene === null) {
|
if (this.runtimeScene === null) {
|
||||||
throw new Error("Runtime scene has not been loaded.");
|
throw new Error("Runtime scene has not been loaded.");
|
||||||
@@ -84,7 +94,7 @@ export class RuntimeHost {
|
|||||||
|
|
||||||
mount(container: HTMLElement) {
|
mount(container: HTMLElement) {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
container.appendChild(this.renderer.domElement);
|
container.appendChild(this.domElement);
|
||||||
this.resize();
|
this.resize();
|
||||||
|
|
||||||
this.resizeObserver = new ResizeObserver(() => {
|
this.resizeObserver = new ResizeObserver(() => {
|
||||||
@@ -149,10 +159,10 @@ export class RuntimeHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.materialTextureCache.clear();
|
this.materialTextureCache.clear();
|
||||||
this.renderer.dispose();
|
this.renderer?.dispose();
|
||||||
|
|
||||||
if (this.container !== null && this.container.contains(this.renderer.domElement)) {
|
if (this.container !== null && this.container.contains(this.domElement)) {
|
||||||
this.container.removeChild(this.renderer.domElement);
|
this.container.removeChild(this.domElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.container = null;
|
this.container = null;
|
||||||
@@ -260,7 +270,9 @@ export class RuntimeHost {
|
|||||||
|
|
||||||
this.camera.aspect = width / height;
|
this.camera.aspect = width / height;
|
||||||
this.camera.updateProjectionMatrix();
|
this.camera.updateProjectionMatrix();
|
||||||
this.renderer.setSize(width, height, false);
|
this.domElement.width = width;
|
||||||
|
this.domElement.height = height;
|
||||||
|
this.renderer?.setSize(width, height, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private render = () => {
|
private render = () => {
|
||||||
@@ -283,7 +295,7 @@ export class RuntimeHost {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.renderer.render(this.scene, this.camera);
|
this.renderer?.render(this.scene, this.camera);
|
||||||
};
|
};
|
||||||
|
|
||||||
private applyTeleportPlayerAction(target: RuntimeTeleportTarget) {
|
private applyTeleportPlayerAction(target: RuntimeTeleportTarget) {
|
||||||
|
|||||||
Reference in New Issue
Block a user