From bee3ffdf1577564feea39d2c68a869304a4c467d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 24 Oct 2023 19:19:59 +0200 Subject: [PATCH 01/86] floating origin v2 for starmap --- src/ts/starmap/starMap.ts | 42 +++++++++++++++++++------------------ src/ts/starmap/starMapUI.ts | 9 ++++---- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/ts/starmap/starMap.ts b/src/ts/starmap/starMap.ts index 4ac411d0a..e77a16f81 100644 --- a/src/ts/starmap/starMap.ts +++ b/src/ts/starmap/starMap.ts @@ -84,6 +84,10 @@ export class StarMap { */ private currentCellPosition = Vector3.Zero(); + private cameraPositionToCenter = Vector3.Zero(); + + private static readonly FLOATING_ORIGIN_MAX_DISTANCE = 1000; + private static readonly FADE_OUT_ANIMATION = new Animation("fadeIn", "instancedBuffers.color.a", 60, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CYCLE); private static readonly FADE_OUT_DURATION = 1000; @@ -204,7 +208,7 @@ export class StarMap { this.travelLine = new ThickLines("travelLine", { points: [], thickness: 0.01, color: Color3.Red() }, this.scene); this.thickLines = [this.travelLine]; - // then generate missing cells // TODO: make this in parralel + // then generate missing cells // TODO: make this in parallel for (let x = -StarMap.RENDER_RADIUS; x <= StarMap.RENDER_RADIUS; x++) { for (let y = -StarMap.RENDER_RADIUS; y <= StarMap.RENDER_RADIUS; y++) { for (let z = -StarMap.RENDER_RADIUS; z <= StarMap.RENDER_RADIUS; z++) { @@ -227,29 +231,27 @@ export class StarMap { const deltaTime = this.scene.getEngine().getDeltaTime() / 1000; if (this.rotationAnimation !== null) this.rotationAnimation.update(deltaTime); + if (this.translationAnimation !== null) this.translationAnimation.update(deltaTime); - const playerDisplacementNegated = this.controller.update(deltaTime).negate(); - - if (this.translationAnimation !== null) { - const oldPosition = this.controller.getTransform().getAbsolutePosition().clone(); - this.translationAnimation.update(deltaTime); - const newPosition = this.controller.getTransform().getAbsolutePosition().clone(); - - const displacementNegated = oldPosition.subtractInPlace(newPosition); - - playerDisplacementNegated.addInPlace(displacementNegated); - } - - translate(this.controller.getTransform(), playerDisplacementNegated); - this.starMapCenterPosition.addInPlace(playerDisplacementNegated); - for (const mesh of this.scene.meshes) mesh.position.addInPlace(playerDisplacementNegated); + this.controller.update(deltaTime); - const cameraPosition = this.starMapCenterPosition.negate(); + this.cameraPositionToCenter = this.controller.getActiveCamera().getAbsolutePosition().subtract(this.starMapCenterPosition); - this.currentCellPosition = new Vector3(Math.round(cameraPosition.x / Cell.SIZE), Math.round(cameraPosition.y / Cell.SIZE), Math.round(cameraPosition.z / Cell.SIZE)); + this.currentCellPosition = new Vector3( + Math.round(this.cameraPositionToCenter.x / Cell.SIZE), + Math.round(this.cameraPositionToCenter.y / Cell.SIZE), + Math.round(this.cameraPositionToCenter.z / Cell.SIZE) + ); this.updateCells(); + if (this.controller.getActiveCamera().getAbsolutePosition().length() > StarMap.FLOATING_ORIGIN_MAX_DISTANCE) { + const translationToOrigin = this.controller.getTransform().getAbsolutePosition().negate(); + this.controller.getTransform().position = Vector3.Zero(); + this.starMapCenterPosition.addInPlace(translationToOrigin); + for (const mesh of this.scene.meshes) mesh.position.addInPlace(translationToOrigin); + } + this.thickLines.forEach((bondingLine) => bondingLine.update()); }); } @@ -282,7 +284,7 @@ export class StarMap { if (selectedSystemInstance !== null && cell.starInstances.concat(cell.blackHoleInstances).includes(selectedSystemInstance)) continue; // don't remove cells that contain the selected system const position = cell.position; - if (position.add(this.starMapCenterPosition).length() > StarMap.RENDER_RADIUS + 1) { + if (position.subtract(this.cameraPositionToCenter).length() > StarMap.RENDER_RADIUS + 1) { for (const starInstance of cell.starInstances) this.fadeOutThenRecycle(starInstance, this.recycledStars); for (const blackHoleInstance of cell.blackHoleInstances) this.fadeOutThenRecycle(blackHoleInstance, this.recycledBlackHoles); @@ -306,7 +308,7 @@ export class StarMap { this.buildNextStars(Math.min(2000, StarMap.GENERATION_CADENCE * this.controller.speed)); - this.starMapUI.update(); + this.starMapUI.update(this.controller.getActiveCamera()); } private buildNextStars(n: number): void { diff --git a/src/ts/starmap/starMapUI.ts b/src/ts/starmap/starMapUI.ts index 7c535371a..8a3222890 100644 --- a/src/ts/starmap/starMapUI.ts +++ b/src/ts/starmap/starMapUI.ts @@ -10,6 +10,7 @@ import selectedCircle from "../../asset/textures/selectedCircle.png"; import { Animation } from "@babylonjs/core/Animations/animation"; import { Scene } from "@babylonjs/core/scene"; +import { Camera } from "@babylonjs/core/Cameras/camera"; export class StarMapUI { readonly gui: AdvancedDynamicTexture; @@ -89,25 +90,25 @@ export class StarMapUI { this.hoveredSystemRing.animations = [StarMapUI.ALPHA_ANIMATION]; } - update() { + update(activeCamera: Camera) { if (this.systemUI.linkedMesh === null || this.systemUI.linkedMesh === undefined) this.gui.removeControl(this.systemUI); else { this.systemUI.linkOffsetY = -150 - 50 / this.systemUI.linkedMesh.getAbsolutePosition().length(); } if (this.hoveredSystemRing.linkedMesh !== null && this.hoveredSystemRing.linkedMesh !== undefined) { - const distance = this.hoveredSystemRing.linkedMesh.getAbsolutePosition().length(); + const distance = this.hoveredSystemRing.linkedMesh.getAbsolutePosition().subtract(activeCamera.globalPosition).length(); const scale = this.hoveredSystemRing.linkedMesh.scaling.x / distance; this.hoveredSystemRing.scaleX = scale; this.hoveredSystemRing.scaleY = scale; } if (this.selectedSystemRing.linkedMesh !== null && this.selectedSystemRing.linkedMesh !== undefined) { - const distance = this.selectedSystemRing.linkedMesh.getAbsolutePosition().length(); + const distance = this.selectedSystemRing.linkedMesh.getAbsolutePosition().subtract(activeCamera.globalPosition).length(); const scale = Math.max(0.3, this.selectedSystemRing.linkedMesh.scaling.x / distance); this.selectedSystemRing.scaleX = scale; this.selectedSystemRing.scaleY = scale; } if (this.currentSystemRing.linkedMesh !== null && this.currentSystemRing.linkedMesh !== undefined) { - const distance = this.currentSystemRing.linkedMesh.getAbsolutePosition().length(); + const distance = this.currentSystemRing.linkedMesh.getAbsolutePosition().subtract(activeCamera.globalPosition).length(); const scale = Math.max(0.3, this.currentSystemRing.linkedMesh.scaling.x / distance); this.currentSystemRing.scaleX = scale; this.currentSystemRing.scaleY = scale; From 8bfdb3e7224176218a68f190bd6cf447ba7f8544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 24 Oct 2023 19:46:48 +0200 Subject: [PATCH 02/86] huge blackhole optimization Now most of the pixels will be skipped when far enough --- src/shaders/blackhole.glsl | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/shaders/blackhole.glsl b/src/shaders/blackhole.glsl index de1e23898..f00bdd987 100644 --- a/src/shaders/blackhole.glsl +++ b/src/shaders/blackhole.glsl @@ -32,6 +32,8 @@ uniform sampler2D starfieldTexture; #pragma glslify: rotateAround = require(./utils/rotateAround.glsl) +#pragma glslify: rayIntersectSphere = require(./utils/rayIntersectSphere.glsl) + vec3 projectOnPlane(vec3 vector, vec3 planeNormal) { return vector - dot(vector, planeNormal) * planeNormal; } @@ -125,6 +127,17 @@ vec4 raymarchDisk(vec3 rayDir, vec3 initialPosition) { return diskColor; } +/** + * Bends the light ray toward the black hole according to its distance + * The bending is tweaked to reach 0 when far enough so that we can skip some calculations + */ +vec3 bendRay(vec3 rayDir, vec3 blackholeDir, float distanceToCenter2, float maxBendDistance, float stepSize) { + float bendForce = object.radius / distanceToCenter2; //bending force + bendForce -= object.radius / (maxBendDistance * maxBendDistance); // bend force is 0 at maxBendDistance + bendForce = stepSize * max(0.0, bendForce); // multiply by step size, and clamp negative values + return normalize(rayDir + bendForce * blackholeDir); //bend ray towards BH +} + void main() { vec4 screenColor = texture2D(textureSampler, vUV);// the current screen color @@ -136,6 +149,15 @@ void main() { vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion + float maxBendDistance = max(accretionDiskRadius * 3.0, object.radius * 4.0); + + float t0, t1; + if(!rayIntersectSphere(camera.position, rayDir, object.position, maxBendDistance, t0, t1)) { + // the light ray will not be affected by the black hole, we can skip the calculations + gl_FragColor = screenColor; + return; + } + vec4 colOut = vec4(0.0); vec3 positionBHS = camera.position - object.position;// position of the camera in blackhole space @@ -175,8 +197,7 @@ void main() { float closeLimit = distanceToCenter * 0.1 + 0.05 * distanceToCenter2 / object.radius;//limit step size close to BH stepSize = min(stepSize, min(farLimit, closeLimit)); - float bendForce = stepSize * object.radius / distanceToCenter2;//bending force - rayDir = normalize(rayDir + bendForce * blackholeDir);//bend ray towards BH + rayDir = bendRay(rayDir, blackholeDir, distanceToCenter2, maxBendDistance, stepSize); positionBHS += stepSize * rayDir; } From 212513d90b2911e80baf38cc56cc4c71d01d6722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 24 Oct 2023 20:13:16 +0200 Subject: [PATCH 03/86] impressive distortion much wow --- src/shaders/blackhole.glsl | 21 +++++++++++---------- src/ts/blackHoleDemo.ts | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/shaders/blackhole.glsl b/src/shaders/blackhole.glsl index f00bdd987..5e1f9cf7d 100644 --- a/src/shaders/blackhole.glsl +++ b/src/shaders/blackhole.glsl @@ -149,7 +149,7 @@ void main() { vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion - float maxBendDistance = max(accretionDiskRadius * 3.0, object.radius * 4.0); + float maxBendDistance = max(accretionDiskRadius * 3.0, object.radius * 15.0); float t0, t1; if(!rayIntersectSphere(camera.position, rayDir, object.position, maxBendDistance, t0, t1)) { @@ -220,17 +220,18 @@ void main() { } //FIXME: when WebGPU supports texture2D inside if statements, move this to not compute it when occluded - /*vec2 uv = uvFromWorld(positionBHS); + vec2 uv = uvFromWorld(positionBHS); vec4 bg = vec4(0.0); - if(uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) bg = texture2D(textureSampler, uv); - else {*/ - vec2 starfieldUV = vec2( - sign(rayDir.z) * acos(rayDir.x / length(vec2(rayDir.x, rayDir.z))) / 6.28318530718, - acos(rayDir.y) / 3.14159265359 - ); - vec4 bg = texture2D(starfieldTexture, starfieldUV); - //} + if(uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) { + bg = texture2D(textureSampler, uv); + } else { + vec2 starfieldUV = vec2( + sign(rayDir.z) * acos(rayDir.x / length(vec2(rayDir.x, rayDir.z))) / 6.28318530718, + acos(rayDir.y) / 3.14159265359 + ); + bg = texture2D(starfieldTexture, starfieldUV); + } vec4 finalColor = vec4(1.0, 0.0, 0.0, 1.0); diff --git a/src/ts/blackHoleDemo.ts b/src/ts/blackHoleDemo.ts index b7705173f..f1826d1c4 100644 --- a/src/ts/blackHoleDemo.ts +++ b/src/ts/blackHoleDemo.ts @@ -67,7 +67,7 @@ const BH = starSystem.makeBlackHole(0); BH.model.orbit.radius = BH.getRadius() * 4; const planet = starSystem.makeTelluricPlanet(); -planet.model.orbit.radius = 10000e3; +planet.model.orbit.radius = 50000e3; document.addEventListener("keydown", (e) => { if (e.key === "g") { From 9f502316bb654cb7055c04e2ee517055bd13ca0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 24 Oct 2023 20:28:35 +0200 Subject: [PATCH 04/86] working on blackholes --- src/ts/index.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ts/index.ts b/src/ts/index.ts index 69b7185b1..cde969e83 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -26,6 +26,7 @@ import { getMoonSeed } from "./model/planemos/common"; import { NeutronStarModel } from "./model/stellarObjects/neutronStarModel"; import { RingsUniforms } from "./model/ringsUniform"; import { StarModel } from "./model/stellarObjects/starModel"; +import { BlackHoleModel } from "./model/stellarObjects/blackHoleModel"; const engine = new SpaceEngine(); @@ -176,10 +177,10 @@ andromaqueModel.orbit.normalToPlane = Vector3.Up(); const andromaque = starSystem.makeGasPlanet(andromaqueModel); -const mandelbulbModel = new MandelbulbModel(0.5, planetModel); -mandelbulbModel.orbit.period = 60 * 60 * 24 * 365.24; -mandelbulbModel.orbit.radius = 3990 * ares.getRadius(); -const mandelbulb = starSystem.makeMandelbulb(mandelbulbModel); +/*const blackHoleModel = new BlackHoleModel(0.5, sunModel); +blackHoleModel.orbit.period = 60 * 60 * 24 * 365.25; +blackHoleModel.orbit.radius = 100 * ares.getRadius(); +const blackHole = starSystem.makeBlackHole(blackHoleModel);*/ engine.init(); From eb7cfa4e95d9586d4072a9810b60c744ff54638a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 24 Oct 2023 21:26:58 +0200 Subject: [PATCH 05/86] made floating origin in a function That's clearer like that I think --- src/ts/starmap/starMap.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ts/starmap/starMap.ts b/src/ts/starmap/starMap.ts index e77a16f81..e18799e41 100644 --- a/src/ts/starmap/starMap.ts +++ b/src/ts/starmap/starMap.ts @@ -31,7 +31,7 @@ import { TransformTranslationAnimation } from "../controller/uberCore/transforms import { makeNoise3D } from "fast-simplex-noise"; import { seededSquirrelNoise } from "squirrel-noise"; import { Settings } from "../settings"; -import { getForwardDirection, translate } from "../controller/uberCore/transforms/basicTransform"; +import { getForwardDirection } from "../controller/uberCore/transforms/basicTransform"; import { ThickLines } from "../utils/thickLines"; import { Observable } from "@babylonjs/core/Misc/observable"; import { Mouse } from "../controller/inputs/mouse"; @@ -246,16 +246,20 @@ export class StarMap { this.updateCells(); if (this.controller.getActiveCamera().getAbsolutePosition().length() > StarMap.FLOATING_ORIGIN_MAX_DISTANCE) { - const translationToOrigin = this.controller.getTransform().getAbsolutePosition().negate(); - this.controller.getTransform().position = Vector3.Zero(); - this.starMapCenterPosition.addInPlace(translationToOrigin); - for (const mesh of this.scene.meshes) mesh.position.addInPlace(translationToOrigin); + this.translateCameraBackToOrigin(); } this.thickLines.forEach((bondingLine) => bondingLine.update()); }); } + public translateCameraBackToOrigin() { + const translationToOrigin = this.controller.getTransform().getAbsolutePosition().negate(); + this.controller.getTransform().position = Vector3.Zero(); + this.starMapCenterPosition.addInPlace(translationToOrigin); + for (const mesh of this.scene.meshes) mesh.position.addInPlace(translationToOrigin); + } + public setRunning(running: boolean): void { this.isRunning = running; } From f007c4482f22983799828086af709585a13e484b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 24 Oct 2023 21:27:12 +0200 Subject: [PATCH 06/86] working on floating origin v2 for starsystem --- src/ts/controller/starSystem.ts | 9 ++------- src/ts/index.ts | 5 ----- src/ts/view/bodies/abstractObject.ts | 14 +++----------- src/ts/view/common.ts | 2 +- 4 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index a1e757fdf..12b858fdb 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -384,15 +384,12 @@ export class StarSystem { public update(deltaTime: number): void { const controller = this.scene.getActiveController(); - /*const displacementTranslation = controller.aggregate.transformNode.getAbsolutePosition().negate(); - this.translateEverythingNow(displacementTranslation); - translate(controller.aggregate.transformNode, displacementTranslation);*/ - for (const object of this.orbitalObjects) { object.updateInternalClock(deltaTime); const initialPosition = object.transform.getAbsolutePosition().clone(); - const newPosition = object.computeNextOrbitalPosition().clone(); + object.updateOrbitalPosition(); + const newPosition = object.transform.getAbsolutePosition().clone(); // if the controller is close to the body, it will follow its movement const orbitLimit = object instanceof SpaceStation ? 200 : 10; @@ -418,8 +415,6 @@ export class StarSystem { this.registerTranslateAllBodies(displacementTranslation); translate(controller.getTransform(), displacementTranslation); - for (const object of this.orbitalObjects) object.applyNextState(); - for (const body of this.telluricPlanets.concat(this.satellites)) body.updateLOD(controller.getTransform().getAbsolutePosition()); for (const object of this.orbitalObjects) object.computeCulling(controller.getActiveCamera()); diff --git a/src/ts/index.ts b/src/ts/index.ts index 69b7185b1..9552ebc63 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -176,11 +176,6 @@ andromaqueModel.orbit.normalToPlane = Vector3.Up(); const andromaque = starSystem.makeGasPlanet(andromaqueModel); -const mandelbulbModel = new MandelbulbModel(0.5, planetModel); -mandelbulbModel.orbit.period = 60 * 60 * 24 * 365.24; -mandelbulbModel.orbit.radius = 3990 * ares.getRadius(); -const mandelbulb = starSystem.makeMandelbulb(mandelbulbModel); - engine.init(); positionNearObject(scene.getActiveController(), planet, starSystem, 2); diff --git a/src/ts/view/bodies/abstractObject.ts b/src/ts/view/bodies/abstractObject.ts index 26782b676..76718f6cd 100644 --- a/src/ts/view/bodies/abstractObject.ts +++ b/src/ts/view/bodies/abstractObject.ts @@ -83,7 +83,7 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla this.internalClock += deltaTime; } - public computeNextOrbitalPosition(): Vector3 { + public updateOrbitalPosition() { if (this.model.orbit.period > 0) { const barycenter = this.parentObject?.transform.getAbsolutePosition() ?? Vector3.Zero(); /*const orbitalPlaneNormal = this.parentObject?.transform.up ?? Vector3.Up(); @@ -92,11 +92,8 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla const newPosition = getPointOnOrbit(barycenter, this.model.orbit, this.internalClock); this.nextState.position.copyFrom(newPosition); - } else { - this.nextState.position.copyFrom(this.transform.getAbsolutePosition()); + this.transform.setAbsolutePosition(newPosition); } - - return this.nextState.position; } /** @@ -119,16 +116,11 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla const elementaryRotationQuaternion = Quaternion.FromRotationMatrix(elementaryRotationMatrix); const newQuaternion = elementaryRotationQuaternion.multiply(getRotationQuaternion(this.transform)); - this.nextState.rotation.copyFrom(newQuaternion); + setRotationQuaternion(this.transform, newQuaternion); return dtheta; } - public applyNextState(): void { - this.transform.setAbsolutePosition(this.nextState.position); - setRotationQuaternion(this.transform, this.nextState.rotation); - } - public abstract computeCulling(camera: Camera): void; public dispose(): void { diff --git a/src/ts/view/common.ts b/src/ts/view/common.ts index b3aa1ce41..3284b823f 100644 --- a/src/ts/view/common.ts +++ b/src/ts/view/common.ts @@ -8,7 +8,7 @@ export interface OrbitalObject extends ITransformable { model: BaseModel; - computeNextOrbitalPosition(): Vector3; + updateOrbitalPosition(): void; } export interface BaseObject extends BoundingSphere { From d70396a20d6f05864c15ac8f28727a8317c6e7cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 24 Oct 2023 22:16:29 +0200 Subject: [PATCH 07/86] blackhole distortion works --- src/shaders/blackhole.glsl | 20 +++++++++++++++++--- src/ts/blackHoleDemo.ts | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/shaders/blackhole.glsl b/src/shaders/blackhole.glsl index 5e1f9cf7d..fd4c12ab1 100644 --- a/src/shaders/blackhole.glsl +++ b/src/shaders/blackhole.glsl @@ -219,11 +219,25 @@ void main() { } } - //FIXME: when WebGPU supports texture2D inside if statements, move this to not compute it when occluded + // getting the screen coordinate of the end of the bended ray vec2 uv = uvFromWorld(positionBHS); - vec4 bg = vec4(0.0); + // check if there is an object occlusion + vec3 pixelWorldPositionEndRay = worldFromUV(uv);// the pixel position in world space (near plane) + vec3 rayDirToEndRay = normalize(pixelWorldPositionEndRay - camera.position);// normalized direction of the ray + + float epsilon = 0.01; + float depthEndRay1 = texture2D(depthSampler, uv + vec2(epsilon, 0.0)).r;// the depth corresponding to the pixel in the depth map + float depthEndRay2 = texture2D(depthSampler, uv + vec2(-epsilon, 0.0)).r;// the depth corresponding to the pixel in the depth map + float depthEndRay3 = texture2D(depthSampler, uv + vec2(0.0, epsilon)).r;// the depth corresponding to the pixel in the depth map + float depthEndRay4 = texture2D(depthSampler, uv + vec2(0.0 -epsilon)).r;// the depth corresponding to the pixel in the depth map + float depthEndRay = min(min(depthEndRay1, depthEndRay2), min(depthEndRay3, depthEndRay4)); + // closest physical point from the camera in the direction of the pixel (occlusion) + vec3 closestPointEndRay = (pixelWorldPositionEndRay - camera.position) * remap(depthEndRay, 0.0, 1.0, camera.near, camera.far); + float maximumDistanceEndRay = length(closestPointEndRay);// the maxium ray length due to occlusion + float BHDistance = length(camera.position - object.position); - if(uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) { + vec4 bg = vec4(0.0); + if(uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0 && maximumDistanceEndRay > BHDistance - object.radius) { bg = texture2D(textureSampler, uv); } else { vec2 starfieldUV = vec2( diff --git a/src/ts/blackHoleDemo.ts b/src/ts/blackHoleDemo.ts index f1826d1c4..d616114d0 100644 --- a/src/ts/blackHoleDemo.ts +++ b/src/ts/blackHoleDemo.ts @@ -67,7 +67,7 @@ const BH = starSystem.makeBlackHole(0); BH.model.orbit.radius = BH.getRadius() * 4; const planet = starSystem.makeTelluricPlanet(); -planet.model.orbit.radius = 50000e3; +planet.model.orbit.radius = 45000e3; document.addEventListener("keydown", (e) => { if (e.key === "g") { From 6c45d2802eda757ea9fd86692a3934473d2d54a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 09:16:12 +0200 Subject: [PATCH 08/86] experimenting with glow --- src/shaders/blackhole.glsl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/shaders/blackhole.glsl b/src/shaders/blackhole.glsl index fd4c12ab1..025425062 100644 --- a/src/shaders/blackhole.glsl +++ b/src/shaders/blackhole.glsl @@ -169,6 +169,7 @@ void main() { if (maximumDistance < length(positionBHS)) occluded = true; vec4 col = vec4(0.0); + vec4 glow = vec4(0.0); if (!occluded) { for (int disks = 0; disks < 15; disks++) { @@ -200,12 +201,14 @@ void main() { rayDir = bendRay(rayDir, blackholeDir, distanceToCenter2, maxBendDistance, stepSize); positionBHS += stepSize * rayDir; + //TODO: improve glow + //glow += vec4(1.2,1.1,1, 1.0) * (0.2 * (object.radius / distanceToCenter2) * stepSize * clamp(distanceToCenter / object.radius - 1.2, 0.0, 1.0)); //adds fairly cheap glow } if (distanceToCenter < object.radius) { suckedInBH = true; break; - } else if (distanceToCenter > object.radius * 10000.0) { + } else if (distanceToCenter > object.radius * 5000.0) { escapedBH = true; break; } else if (projectedDistance <= accretionDiskHeight) { @@ -254,9 +257,9 @@ void main() { } else if (suckedInBH) { finalColor = vec4(col.rgb * col.a, 1.0); } else if (escapedBH) { - finalColor = vec4(mix(bg.rgb, col.rgb, col.a), 1.0); + finalColor = vec4(mix(bg.rgb, col.rgb + glow.rgb *(col.a + glow.a), col.a), 1.0); } else { - finalColor = vec4(col.rgb, 1.0); + finalColor = vec4(col.rgb + glow.rgb *(col.a + glow.a), 1.0); } gl_FragColor = finalColor; From 7faaec25da2e7a56e048af9c46e6975c0db1042a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 09:36:48 +0200 Subject: [PATCH 09/86] The eagle has landed for the first time --- src/ts/controller/spaceEngine.ts | 2 +- src/ts/controller/starSystem.ts | 29 ++++++++----------- .../controller/uberCore/abstractController.ts | 1 + src/ts/index.ts | 2 +- src/ts/view/bodies/abstractObject.ts | 14 +-------- 5 files changed, 16 insertions(+), 32 deletions(-) diff --git a/src/ts/controller/spaceEngine.ts b/src/ts/controller/spaceEngine.ts index fa5e22571..510deba09 100644 --- a/src/ts/controller/spaceEngine.ts +++ b/src/ts/controller/spaceEngine.ts @@ -244,7 +244,7 @@ export class SpaceEngine { this.getEngine().runRenderLoop(() => this.getActiveScene().render()); }); - this.starSystemScene.registerBeforeRender(() => { + this.starSystemScene.onBeforePhysicsObservable.add(() => { if (this.isPaused()) return; const starSystemScene = this.getStarSystemScene(); diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index 12b858fdb..cca809cd2 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -310,14 +310,6 @@ export class StarSystem { for (const object of this.orbitalObjects) translate(object.transform, displacement); } - /** - * Translates all celestial bodies and spacestations in the system by the given displacement - * @param displacement The displacement applied to all bodies - */ - public registerTranslateAllBodies(displacement: Vector3): void { - for (const object of this.orbitalObjects) object.nextState.position.addInPlace(displacement); - } - /** * Returns the list of all celestial bodies managed by the star system */ @@ -383,6 +375,7 @@ export class StarSystem { */ public update(deltaTime: number): void { const controller = this.scene.getActiveController(); + const nearestBody = this.getNearestBody(this.scene.getActiveUberCamera().position); for (const object of this.orbitalObjects) { object.updateInternalClock(deltaTime); @@ -395,25 +388,28 @@ export class StarSystem { const orbitLimit = object instanceof SpaceStation ? 200 : 10; if (isOrbiting(controller, object, orbitLimit) && this.getNearestObject() === object) { translate(controller.getTransform(), newPosition.subtract(initialPosition)); - - /*const direction = controller.aggregate.transformNode.getAbsolutePosition().subtract(object.nextState.position).normalize(); - const gravity = 9.81; - controller.aggregate.body.applyForce(direction.scale(gravity), controller.aggregate.body.getObjectCenterWorld());*/ } const dtheta = object.updateRotation(deltaTime); // if the controller is close to the object and it is a body, it will follow its rotation if (isOrbiting(controller, object) && this.getNearestBody() === object) { - rotateAround(controller.getTransform(), object.nextState.position, object.getRotationAxis(), dtheta); + rotateAround(controller.getTransform(), object.transform.getAbsolutePosition(), object.getRotationAxis(), dtheta); } } controller.update(deltaTime); - const displacementTranslation = controller.getTransform().getAbsolutePosition().negate(); - this.registerTranslateAllBodies(displacementTranslation); - translate(controller.getTransform(), displacementTranslation); + /*const direction = controller.aggregate.transformNode.getAbsolutePosition().subtract(object.nextState.position).normalize(); + const gravity = 9.81; + controller.aggregate.body.applyForce(direction.scale(gravity), controller.aggregate.body.getObjectCenterWorld());*/ + + // floating origin + if(controller.getActiveCamera().getAbsolutePosition().length() > 1000) { + const displacementTranslation = controller.getTransform().getAbsolutePosition().negate(); + this.translateEverythingNow(displacementTranslation); + translate(controller.getTransform(), displacementTranslation); + } for (const body of this.telluricPlanets.concat(this.satellites)) body.updateLOD(controller.getTransform().getAbsolutePosition()); @@ -425,7 +421,6 @@ export class StarSystem { if (stellarObject instanceof Star) stellarObject.updateMaterial(); } - const nearestBody = this.getNearestBody(this.scene.getActiveUberCamera().position); this.postProcessManager.setBody(nearestBody); const rings = this.postProcessManager.getRings(nearestBody); const switchLimit = rings !== null ? rings.ringsUniforms.ringStart : 2; diff --git a/src/ts/controller/uberCore/abstractController.ts b/src/ts/controller/uberCore/abstractController.ts index 11ca4bac9..f76f00357 100644 --- a/src/ts/controller/uberCore/abstractController.ts +++ b/src/ts/controller/uberCore/abstractController.ts @@ -3,6 +3,7 @@ import { Input } from "../inputs/input"; import { UberCamera } from "./uberCamera"; import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; import { TransformNode } from "@babylonjs/core/Meshes"; +import { ITransformable } from "../../view/common"; export abstract class AbstractController { /** diff --git a/src/ts/index.ts b/src/ts/index.ts index 9552ebc63..5b4456b71 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -51,7 +51,7 @@ spaceshipController.addInput(gamepad); spaceshipController.addInput(mouse); const physicsViewer = new PhysicsViewer(); -//physicsViewer.showBody(spaceshipController.aggregate.body); +physicsViewer.showBody(spaceshipController.aggregate.body); mouse.onMouseLeaveObservable.add(() => { if (scene.getActiveController() === spaceshipController) engine.pause(); diff --git a/src/ts/view/bodies/abstractObject.ts b/src/ts/view/bodies/abstractObject.ts index 76718f6cd..85b45c987 100644 --- a/src/ts/view/bodies/abstractObject.ts +++ b/src/ts/view/bodies/abstractObject.ts @@ -9,19 +9,9 @@ import { TransformNode } from "@babylonjs/core/Meshes"; import { getRotationQuaternion, setRotationQuaternion } from "../../controller/uberCore/transforms/basicTransform"; import { Camera } from "@babylonjs/core/Cameras/camera"; -export interface NextState { - position: Vector3; - rotation: Quaternion; -} - export abstract class AbstractObject implements OrbitalObject, BaseObject, Cullable { readonly transform: TransformNode; - readonly nextState: NextState = { - position: Vector3.Zero(), - rotation: Quaternion.Identity() - }; - readonly postProcesses: PostProcessType[] = []; //TODO: make an universal clock ?? or not it could be funny @@ -88,10 +78,9 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla const barycenter = this.parentObject?.transform.getAbsolutePosition() ?? Vector3.Zero(); /*const orbitalPlaneNormal = this.parentObject?.transform.up ?? Vector3.Up(); - if (this.model.orbit.isPlaneAlignedWithParent) this.model.orbit.normalToPlane = orbitalPlaneNormal;*/ + if (this.model.orbit.isPlaneAlignedWithParent) this.model.orbit.normalToPlane = orbitalPlaneNormal;*/ const newPosition = getPointOnOrbit(barycenter, this.model.orbit, this.internalClock); - this.nextState.position.copyFrom(newPosition); this.transform.setAbsolutePosition(newPosition); } } @@ -103,7 +92,6 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla */ public updateRotation(deltaTime: number): number { if (this.model.physicalProperties.rotationPeriod === 0) { - this.nextState.rotation.copyFrom(getRotationQuaternion(this.transform)); return 0; } From bf36fc04b5a7f4acc1748d9dfa0a53b5c9c45b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 09:56:10 +0200 Subject: [PATCH 10/86] better transformable interface --- src/shaders/flatCloudsFragment.glsl | 2 -- src/ts/blackHoleDemo.ts | 2 +- src/ts/controller/chunks/chunkTree.ts | 2 +- src/ts/controller/chunks/planetChunk.ts | 10 +++++++--- src/ts/controller/starSystem.ts | 14 +++++++------- .../controller/uberCore/abstractController.ts | 4 ++-- src/ts/index.ts | 2 +- src/ts/playground.ts | 8 ++++---- src/ts/randomizer.ts | 2 +- src/ts/ui/bodyEditor/panels/generalPanel.ts | 17 +++++++++-------- src/ts/utils/isObjectVisibleOnScreen.ts | 6 +++--- src/ts/utils/nearestBody.ts | 8 ++++---- src/ts/utils/positionNearObject.ts | 14 +++++++------- src/ts/view/bodies/abstractObject.ts | 8 ++++++-- src/ts/view/bodies/planemos/gasPlanet.ts | 6 +++--- src/ts/view/bodies/planemos/mandelbulb.ts | 2 +- src/ts/view/bodies/planemos/telluricPlanemo.ts | 6 +++--- src/ts/view/bodies/stellarObjects/blackHole.ts | 4 ++-- .../view/bodies/stellarObjects/neutronStar.ts | 2 +- src/ts/view/bodies/stellarObjects/star.ts | 8 ++++---- src/ts/view/common.ts | 9 ++++----- src/ts/view/materials/gasPlanetMaterial.ts | 3 +-- .../view/materials/telluricPlanemoMaterial.ts | 2 +- src/ts/view/orbitRenderer.ts | 4 ++-- .../view/postProcesses/blackHolePostProcess.ts | 2 +- .../view/postProcesses/flatCloudsPostProcess.ts | 7 ------- src/ts/view/postProcesses/oceanPostProcess.ts | 2 +- .../view/postProcesses/starfieldPostProcess.ts | 8 ++++---- src/ts/view/postProcesses/uniforms.ts | 8 ++++---- src/ts/view/spaceStation.ts | 6 +++--- 30 files changed, 88 insertions(+), 90 deletions(-) diff --git a/src/shaders/flatCloudsFragment.glsl b/src/shaders/flatCloudsFragment.glsl index b6a7f9899..11a1bb468 100644 --- a/src/shaders/flatCloudsFragment.glsl +++ b/src/shaders/flatCloudsFragment.glsl @@ -17,8 +17,6 @@ uniform Star stars[MAX_STARS]; #pragma glslify: object = require(./utils/object.glsl) -uniform vec4 planetInverseRotationQuaternion; - struct Clouds { float layerRadius;// atmosphere radius (calculate from planet center) diff --git a/src/ts/blackHoleDemo.ts b/src/ts/blackHoleDemo.ts index b7705173f..1be16cf26 100644 --- a/src/ts/blackHoleDemo.ts +++ b/src/ts/blackHoleDemo.ts @@ -44,7 +44,7 @@ engine.registerStarSystemUpdateCallback(() => { const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); const nearestBody = engine.getStarSystem().getNearestBody(shipPosition); - const distance = nearestBody.transform.getAbsolutePosition().subtract(shipPosition).length(); + const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); const radius = nearestBody.getRadius(); spaceshipController.registerClosestObject(distance, radius); diff --git a/src/ts/controller/chunks/chunkTree.ts b/src/ts/controller/chunks/chunkTree.ts index 0d29114f8..77b4d8b3d 100644 --- a/src/ts/controller/chunks/chunkTree.ts +++ b/src/ts/controller/chunks/chunkTree.ts @@ -203,7 +203,7 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ if (!chunk.isReady()) return; chunk.mesh.setEnabled(true); // this is needed to update the world matrix - chunk.transform.computeWorldMatrix(true); + chunk.getTransform().computeWorldMatrix(true); chunk.mesh.setEnabled(isSizeOnScreenEnough(chunk, camera)); }); diff --git a/src/ts/controller/chunks/planetChunk.ts b/src/ts/controller/chunks/planetChunk.ts index 7e25ba8dd..dba78f289 100644 --- a/src/ts/controller/chunks/planetChunk.ts +++ b/src/ts/controller/chunks/planetChunk.ts @@ -3,7 +3,7 @@ import { getChunkPlaneSpacePositionFromPath } from "../../utils/chunkUtils"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { Mesh } from "@babylonjs/core/Meshes/mesh"; import { Material } from "@babylonjs/core/Materials/material"; -import { ITransformable } from "../../view/common"; +import { Transformable } from "../../view/common"; import { Scene } from "@babylonjs/core/scene"; import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; import "@babylonjs/core/Engines/Extensions/engine.query"; @@ -11,14 +11,14 @@ import { TransformNode, VertexData } from "@babylonjs/core/Meshes"; import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; import { PhysicsShapeMesh } from "@babylonjs/core/Physics/v2/physicsShape"; -export class PlanetChunk implements ITransformable { +export class PlanetChunk implements Transformable { public readonly mesh: Mesh; private readonly depth: number; public readonly cubePosition: Vector3; private ready = false; readonly isMinDepth; - public readonly transform: TransformNode; + private readonly transform: TransformNode; readonly chunkSideLength: number; @@ -68,6 +68,10 @@ export class PlanetChunk implements ITransformable { this.transform.position = position; } + public getTransform(): TransformNode { + return this.transform; + } + public init(vertexData: VertexData) { vertexData.applyToMesh(this.mesh, false); this.mesh.freezeNormals(); diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index cca809cd2..e78aa8ad3 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -307,7 +307,7 @@ export class StarSystem { * @param displacement The displacement applied to all bodies */ public translateEverythingNow(displacement: Vector3): void { - for (const object of this.orbitalObjects) translate(object.transform, displacement); + for (const object of this.orbitalObjects) translate(object.getTransform(), displacement); } /** @@ -325,7 +325,7 @@ export class StarSystem { let nearest = null; let smallerDistance = -1; for (const body of this.celestialBodies) { - const distance = body.transform.getAbsolutePosition().subtract(position).length() - body.model.radius; + const distance = body.getTransform().getAbsolutePosition().subtract(position).length() - body.model.radius; if (nearest === null || distance < smallerDistance) { nearest = body; smallerDistance = distance; @@ -340,7 +340,7 @@ export class StarSystem { let nearest = null; let smallerDistance2 = -1; for (const object of this.orbitalObjects) { - const distance2 = object.transform.getAbsolutePosition().subtract(position).lengthSquared(); + const distance2 = object.getTransform().getAbsolutePosition().subtract(position).lengthSquared(); if (nearest === null || distance2 < smallerDistance2) { nearest = object; smallerDistance2 = distance2; @@ -380,9 +380,9 @@ export class StarSystem { for (const object of this.orbitalObjects) { object.updateInternalClock(deltaTime); - const initialPosition = object.transform.getAbsolutePosition().clone(); + const initialPosition = object.getTransform().getAbsolutePosition().clone(); object.updateOrbitalPosition(); - const newPosition = object.transform.getAbsolutePosition().clone(); + const newPosition = object.getTransform().getAbsolutePosition().clone(); // if the controller is close to the body, it will follow its movement const orbitLimit = object instanceof SpaceStation ? 200 : 10; @@ -394,7 +394,7 @@ export class StarSystem { // if the controller is close to the object and it is a body, it will follow its rotation if (isOrbiting(controller, object) && this.getNearestBody() === object) { - rotateAround(controller.getTransform(), object.transform.getAbsolutePosition(), object.getRotationAxis(), dtheta); + rotateAround(controller.getTransform(), object.getTransform().getAbsolutePosition(), object.getRotationAxis(), dtheta); } } @@ -405,7 +405,7 @@ export class StarSystem { controller.aggregate.body.applyForce(direction.scale(gravity), controller.aggregate.body.getObjectCenterWorld());*/ // floating origin - if(controller.getActiveCamera().getAbsolutePosition().length() > 1000) { + if(controller.getActiveCamera().getAbsolutePosition().length() > 100) { const displacementTranslation = controller.getTransform().getAbsolutePosition().negate(); this.translateEverythingNow(displacementTranslation); translate(controller.getTransform(), displacementTranslation); diff --git a/src/ts/controller/uberCore/abstractController.ts b/src/ts/controller/uberCore/abstractController.ts index f76f00357..fb39b2f20 100644 --- a/src/ts/controller/uberCore/abstractController.ts +++ b/src/ts/controller/uberCore/abstractController.ts @@ -3,9 +3,9 @@ import { Input } from "../inputs/input"; import { UberCamera } from "./uberCamera"; import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; import { TransformNode } from "@babylonjs/core/Meshes"; -import { ITransformable } from "../../view/common"; +import { Transformable } from "../../view/common"; -export abstract class AbstractController { +export abstract class AbstractController implements Transformable { /** * The inputs that this controller listens to */ diff --git a/src/ts/index.ts b/src/ts/index.ts index 5b4456b71..fcbd0a7a2 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -65,7 +65,7 @@ engine.registerStarSystemUpdateCallback(() => { const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); const nearestBody = engine.getStarSystem().getNearestObject(shipPosition); - const distance = nearestBody.transform.getAbsolutePosition().subtract(shipPosition).length(); + const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); const radius = nearestBody.getBoundingRadius(); spaceshipController.registerClosestObject(distance, radius); diff --git a/src/ts/playground.ts b/src/ts/playground.ts index 73e9fe48e..9dd51dba8 100644 --- a/src/ts/playground.ts +++ b/src/ts/playground.ts @@ -91,11 +91,11 @@ shadowGenerator.addShadowCaster(capsule); const auroraModel = new StarModel(984); const aurora = new Star("Aurora", scene, auroraModel); -aurora.transform.setAbsolutePosition(new Vector3(0, aurora.getRadius() * 10.0, 0)); +aurora.getTransform().setAbsolutePosition(new Vector3(0, aurora.getRadius() * 10.0, 0)); const newtonModel = new TelluricPlanemoModel(152); const newton = new TelluricPlanemo("newton", scene, newtonModel); -newton.transform.setAbsolutePosition(new Vector3(0, -newtonModel.radius - 11.18e3, 0)); +newton.getTransform().setAbsolutePosition(new Vector3(0, -newtonModel.radius - 11.18e3, 0)); newton.updateLOD(camera.globalPosition); const viewer = new PhysicsViewer(); @@ -113,12 +113,12 @@ const aggregates = [sphereAggregate, boxAggregate, capsuleAggregate, spaceship.g for (const aggregate of aggregates) { aggregate.body.disablePreStep = false; } -const meshes = [sphere, box, capsule, spaceship.instanceRoot, newton.transform]; +const meshes = [sphere, box, capsule, spaceship.instanceRoot, newton.getTransform()]; const fallingAggregates = [sphereAggregate, boxAggregate, capsuleAggregate, spaceship.getAggregate()]; viewer.showBody(spaceship.getAggregate().body); -const gravityOrigin = newton.transform.getAbsolutePosition(); +const gravityOrigin = newton.getTransform().getAbsolutePosition(); const gravity = -9.81; let clockSeconds = 0; diff --git a/src/ts/randomizer.ts b/src/ts/randomizer.ts index 4875db933..6b22ed29c 100644 --- a/src/ts/randomizer.ts +++ b/src/ts/randomizer.ts @@ -46,7 +46,7 @@ engine.registerStarSystemUpdateCallback(() => { const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); const nearestBody = engine.getStarSystem().getNearestBody(shipPosition); - const distance = nearestBody.transform.getAbsolutePosition().subtract(shipPosition).length(); + const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); const radius = nearestBody.getRadius(); spaceshipController.registerClosestObject(distance, radius); diff --git a/src/ts/ui/bodyEditor/panels/generalPanel.ts b/src/ts/ui/bodyEditor/panels/generalPanel.ts index 011ed3c52..c05f0f5d2 100644 --- a/src/ts/ui/bodyEditor/panels/generalPanel.ts +++ b/src/ts/ui/bodyEditor/panels/generalPanel.ts @@ -1,5 +1,4 @@ import { EditorPanel } from "../editorPanel"; -import { AbstractBody } from "../../../view/bodies/abstractBody"; import { stripAxisFromQuaternion } from "../../../utils/algebra"; import { Axis } from "@babylonjs/core/Maths/math.axis"; import { Slider } from "handle-sliderjs"; @@ -8,40 +7,42 @@ import { UberScene } from "../../../controller/uberCore/uberScene"; import { isOrbiting } from "../../../utils/nearestBody"; import { ColorCorrection } from "../../../controller/uberCore/postProcesses/colorCorrection"; import { getRotationQuaternion } from "../../../controller/uberCore/transforms/basicTransform"; +import { BoundingSphere, Transformable } from "../../../view/common"; export class GeneralPanel extends EditorPanel { constructor() { super("general"); } - init(body: AbstractBody, colorCorrection: ColorCorrection, scene: UberScene) { + + init(body: Transformable & BoundingSphere, colorCorrection: ColorCorrection, scene: UberScene) { this.enable(); for (const slider of this.sliders) slider.remove(); - let axialTiltX = stripAxisFromQuaternion(getRotationQuaternion(body.transform), Axis.Y).toEulerAngles().x; - let axialTiltZ = stripAxisFromQuaternion(getRotationQuaternion(body.transform), Axis.Y).toEulerAngles().z; + let axialTiltX = stripAxisFromQuaternion(getRotationQuaternion(body.getTransform()), Axis.Y).toEulerAngles().x; + let axialTiltZ = stripAxisFromQuaternion(getRotationQuaternion(body.getTransform()), Axis.Y).toEulerAngles().z; //TODO: do not hardcode here const power = 1.4; this.sliders = [ new Slider("axialTiltX", document.getElementById("axialTiltX") as HTMLElement, -180, 180, Math.round((180 * axialTiltX) / Math.PI), (val: number) => { const newAxialTilt = (val * Math.PI) / 180; - body.transform.rotate(Axis.X, newAxialTilt - axialTiltX); + body.getTransform().rotate(Axis.X, newAxialTilt - axialTiltX); if (isOrbiting(scene.getActiveController(), body)) scene .getActiveController() .getTransform() - .rotateAround(body.transform.getAbsolutePosition(), Axis.X, newAxialTilt - axialTiltX); + .rotateAround(body.getTransform().getAbsolutePosition(), Axis.X, newAxialTilt - axialTiltX); axialTiltX = newAxialTilt; }), new Slider("axialTiltZ", document.getElementById("axialTiltZ") as HTMLElement, -180, 180, Math.round((180 * axialTiltZ) / Math.PI), (val: number) => { const newAxialTilt = (val * Math.PI) / 180; - body.transform.rotate(Axis.Z, newAxialTilt - axialTiltZ); + body.getTransform().rotate(Axis.Z, newAxialTilt - axialTiltZ); if (isOrbiting(scene.getActiveController(), body)) scene .getActiveController() .getTransform() - .rotateAround(body.transform.getAbsolutePosition(), Axis.Z, newAxialTilt - axialTiltZ); + .rotateAround(body.getTransform().getAbsolutePosition(), Axis.Z, newAxialTilt - axialTiltZ); axialTiltZ = newAxialTilt; }), new Slider( diff --git a/src/ts/utils/isObjectVisibleOnScreen.ts b/src/ts/utils/isObjectVisibleOnScreen.ts index 3a52bfecc..1b1580f13 100644 --- a/src/ts/utils/isObjectVisibleOnScreen.ts +++ b/src/ts/utils/isObjectVisibleOnScreen.ts @@ -1,5 +1,5 @@ import { Vector3 } from "@babylonjs/core/Maths/math"; -import { BoundingSphere, ITransformable } from "../view/common"; +import { BoundingSphere, Transformable } from "../view/common"; import { Camera } from "@babylonjs/core/Cameras/camera"; /** @@ -21,8 +21,8 @@ export function getAngularSize(objectPosition: Vector3, objectRadius: number, ca * @param threshold The size threshold * @returns Whether the object is bigger than the threshold */ -export function isSizeOnScreenEnough(object: BoundingSphere & ITransformable, camera: Camera, threshold = 0.002) { - const angularSize = getAngularSize(object.transform.getAbsolutePosition(), object.getBoundingRadius(), camera.globalPosition); +export function isSizeOnScreenEnough(object: BoundingSphere & Transformable, camera: Camera, threshold = 0.002) { + const angularSize = getAngularSize(object.getTransform().getAbsolutePosition(), object.getBoundingRadius(), camera.globalPosition); return angularSize / camera.fov > threshold; } diff --git a/src/ts/utils/nearestBody.ts b/src/ts/utils/nearestBody.ts index 17182a614..0a58e7fba 100644 --- a/src/ts/utils/nearestBody.ts +++ b/src/ts/utils/nearestBody.ts @@ -1,6 +1,6 @@ import { AbstractBody } from "../view/bodies/abstractBody"; import { AbstractController } from "../controller/uberCore/abstractController"; -import { BaseObject } from "../view/common"; +import { BoundingSphere, Transformable } from "../view/common"; import { TransformNode } from "@babylonjs/core/Meshes"; export function nearestBody(object: TransformNode, bodies: AbstractBody[]): AbstractBody { @@ -8,7 +8,7 @@ export function nearestBody(object: TransformNode, bodies: AbstractBody[]): Abst if (bodies.length === 0) throw new Error("no bodieees !"); let nearest = bodies[0]; for (const body of bodies) { - const newDistance = object.getAbsolutePosition().subtract(body.transform.getAbsolutePosition()).length(); + const newDistance = object.getAbsolutePosition().subtract(body.getTransform().getAbsolutePosition()).length(); if (distance === -1 || newDistance < distance) { nearest = body; distance = newDistance; @@ -23,6 +23,6 @@ export function nearestBody(object: TransformNode, bodies: AbstractBody[]): Abst * @param body the body to check whereas the player is orbiting * @param orbitLimitFactor the boundary of the orbit detection (multiplied by planet radius) */ -export function isOrbiting(controller: AbstractController, body: BaseObject, orbitLimitFactor = 2.5): boolean { - return body.transform.getAbsolutePosition().subtract(controller.getTransform().getAbsolutePosition()).lengthSquared() < (orbitLimitFactor * body.getBoundingRadius()) ** 2; +export function isOrbiting(controller: AbstractController, body: Transformable & BoundingSphere, orbitLimitFactor = 2.5): boolean { + return body.getTransform().getAbsolutePosition().subtract(controller.getTransform().getAbsolutePosition()).lengthSquared() < (orbitLimitFactor * body.getBoundingRadius()) ** 2; } diff --git a/src/ts/utils/positionNearObject.ts b/src/ts/utils/positionNearObject.ts index 9e9c36254..6995c8a12 100644 --- a/src/ts/utils/positionNearObject.ts +++ b/src/ts/utils/positionNearObject.ts @@ -2,26 +2,26 @@ import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { AbstractController } from "../controller/uberCore/abstractController"; import { StarSystem } from "../controller/starSystem"; import { nearestBody } from "./nearestBody"; -import { AbstractObject } from "../view/bodies/abstractObject"; +import { BoundingSphere, Transformable } from "../view/common"; -export function positionNearObject(controller: AbstractController, object: AbstractObject, starSystem: StarSystem, nRadius = 3): void { +export function positionNearObject(controller: AbstractController, object: Transformable & BoundingSphere, starSystem: StarSystem, nRadius = 3): void { // go from the nearest star to be on the sunny side of the object - const nearestStar = nearestBody(object.transform, starSystem.stellarObjects); + const nearestStar = nearestBody(object.getTransform(), starSystem.stellarObjects); if (nearestStar === object) { // the object is the nearest star - controller.getTransform().setAbsolutePosition(object.transform.getAbsolutePosition().add(new Vector3(0, 0.2, 1).scaleInPlace(object.getBoundingRadius() * nRadius))); + controller.getTransform().setAbsolutePosition(object.getTransform().getAbsolutePosition().add(new Vector3(0, 0.2, 1).scaleInPlace(object.getBoundingRadius() * nRadius))); } else { - const dirBodyToStar = object.transform.getAbsolutePosition().subtract(nearestStar.transform.getAbsolutePosition()); + const dirBodyToStar = object.getTransform().getAbsolutePosition().subtract(nearestStar.getTransform().getAbsolutePosition()); const distBodyToStar = dirBodyToStar.length(); dirBodyToStar.scaleInPlace(1 / distBodyToStar); - const displacement = nearestStar.transform.getAbsolutePosition().add(dirBodyToStar.scale(distBodyToStar - nRadius * object.getBoundingRadius())); + const displacement = nearestStar.getTransform().getAbsolutePosition().add(dirBodyToStar.scale(distBodyToStar - nRadius * object.getBoundingRadius())); controller.getTransform().setAbsolutePosition(displacement); } starSystem.translateEverythingNow(controller.getTransform().getAbsolutePosition().negate()); controller.getTransform().setAbsolutePosition(Vector3.Zero()); - controller.getTransform().lookAt(object.transform.getAbsolutePosition()); + controller.getTransform().lookAt(object.getTransform().getAbsolutePosition()); } diff --git a/src/ts/view/bodies/abstractObject.ts b/src/ts/view/bodies/abstractObject.ts index 85b45c987..c31ba8240 100644 --- a/src/ts/view/bodies/abstractObject.ts +++ b/src/ts/view/bodies/abstractObject.ts @@ -10,7 +10,7 @@ import { getRotationQuaternion, setRotationQuaternion } from "../../controller/u import { Camera } from "@babylonjs/core/Cameras/camera"; export abstract class AbstractObject implements OrbitalObject, BaseObject, Cullable { - readonly transform: TransformNode; + private readonly transform: TransformNode; readonly postProcesses: PostProcessType[] = []; @@ -40,6 +40,10 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla this.transform = new TransformNode(name, scene); } + public getTransform(): TransformNode { + return this.transform; + } + public abstract getBoundingRadius(): number; /** @@ -75,7 +79,7 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla public updateOrbitalPosition() { if (this.model.orbit.period > 0) { - const barycenter = this.parentObject?.transform.getAbsolutePosition() ?? Vector3.Zero(); + const barycenter = this.parentObject?.getTransform().getAbsolutePosition() ?? Vector3.Zero(); /*const orbitalPlaneNormal = this.parentObject?.transform.up ?? Vector3.Up(); if (this.model.orbit.isPlaneAlignedWithParent) this.model.orbit.normalToPlane = orbitalPlaneNormal;*/ diff --git a/src/ts/view/bodies/planemos/gasPlanet.ts b/src/ts/view/bodies/planemos/gasPlanet.ts index 407cda20e..e52f65447 100644 --- a/src/ts/view/bodies/planemos/gasPlanet.ts +++ b/src/ts/view/bodies/planemos/gasPlanet.ts @@ -39,15 +39,15 @@ export class GasPlanet extends AbstractBody implements Planemo, PlanemoMaterial }, scene ); - this.mesh.parent = this.transform; + this.mesh.parent = this.getTransform(); - this.material = new GasPlanetMaterial(this.name, this.transform, this.model, scene); + this.material = new GasPlanetMaterial(this.name, this.getTransform(), this.model, scene); this.mesh.material = this.material; this.postProcesses.push(PostProcessType.OVERLAY, PostProcessType.ATMOSPHERE, PostProcessType.SHADOW); if (this.model.ringsUniforms !== null) this.postProcesses.push(PostProcessType.RING); - this.transform.rotate(Axis.X, this.model.physicalProperties.axialTilt); + this.getTransform().rotate(Axis.X, this.model.physicalProperties.axialTilt); } updateMaterial(controller: AbstractController, stellarObjects: StellarObject[], deltaTime: number): void { diff --git a/src/ts/view/bodies/planemos/mandelbulb.ts b/src/ts/view/bodies/planemos/mandelbulb.ts index 9aea3597d..ebe8a67a9 100644 --- a/src/ts/view/bodies/planemos/mandelbulb.ts +++ b/src/ts/view/bodies/planemos/mandelbulb.ts @@ -23,7 +23,7 @@ export class Mandelbulb extends AbstractBody implements Planemo { this.postProcesses.push(PostProcessType.OVERLAY, PostProcessType.MANDELBULB); - this.transform.rotate(Axis.X, this.model.physicalProperties.axialTilt); + this.getTransform().rotate(Axis.X, this.model.physicalProperties.axialTilt); } public override computeCulling(camera: Camera): void { diff --git a/src/ts/view/bodies/planemos/telluricPlanemo.ts b/src/ts/view/bodies/planemos/telluricPlanemo.ts index f29da8ed0..1382e91d7 100644 --- a/src/ts/view/bodies/planemos/telluricPlanemo.ts +++ b/src/ts/view/bodies/planemos/telluricPlanemo.ts @@ -38,7 +38,7 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat this.model = model instanceof TelluricPlanemoModel ? model : new TelluricPlanemoModel(model, parentBody?.model); - this.transform.rotate(Axis.X, this.model.physicalProperties.axialTilt); + this.getTransform().rotate(Axis.X, this.model.physicalProperties.axialTilt); this.postProcesses.push(PostProcessType.OVERLAY, PostProcessType.SHADOW); @@ -59,10 +59,10 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat if (this.model.ringsUniforms !== null) this.postProcesses.push(PostProcessType.RING); - this.material = new TelluricPlanemoMaterial(this.name, this.transform, this.model, scene); + this.material = new TelluricPlanemoMaterial(this.name, this.getTransform(), this.model, scene); this.aggregate = new PhysicsAggregate( - this.transform, + this.getTransform(), PhysicsShapeType.CONTAINER, { mass: 0, diff --git a/src/ts/view/bodies/stellarObjects/blackHole.ts b/src/ts/view/bodies/stellarObjects/blackHole.ts index 45997a6b0..f4676f0bb 100644 --- a/src/ts/view/bodies/stellarObjects/blackHole.ts +++ b/src/ts/view/bodies/stellarObjects/blackHole.ts @@ -18,12 +18,12 @@ export class BlackHole extends AbstractBody { this.model = model instanceof BlackHoleModel ? model : new BlackHoleModel(model); - this.transform.rotate(Axis.X, this.model.physicalProperties.axialTilt); + this.getTransform().rotate(Axis.X, this.model.physicalProperties.axialTilt); this.light = new PointLight(`${name}Light`, Vector3.Zero(), scene); //this.light.diffuse.fromArray(getRgbFromTemperature(this.model.physicalProperties.temperature).asArray()); this.light.falloffType = Light.FALLOFF_STANDARD; - this.light.parent = this.transform; + this.light.parent = this.getTransform(); if (this.model.physicalProperties.accretionDiskRadius === 0) this.light.intensity = 0; this.postProcesses.push(PostProcessType.OVERLAY, PostProcessType.BLACK_HOLE); diff --git a/src/ts/view/bodies/stellarObjects/neutronStar.ts b/src/ts/view/bodies/stellarObjects/neutronStar.ts index 9409e46b6..9220557d4 100644 --- a/src/ts/view/bodies/stellarObjects/neutronStar.ts +++ b/src/ts/view/bodies/stellarObjects/neutronStar.ts @@ -13,7 +13,7 @@ export class NeutronStar extends Star { * @param name The name of the star * @param scene * @param model The seed of the star in [-1, 1] - * @param parentBodies The bodies the star is orbiting + * @param parentBody */ constructor(name: string, scene: UberScene, model: number | NeutronStarModel, parentBody?: AbstractBody) { super(name, scene, model, parentBody); diff --git a/src/ts/view/bodies/stellarObjects/star.ts b/src/ts/view/bodies/stellarObjects/star.ts index f112ce37f..32f4ab8a1 100644 --- a/src/ts/view/bodies/stellarObjects/star.ts +++ b/src/ts/view/bodies/stellarObjects/star.ts @@ -48,7 +48,7 @@ export class Star extends AbstractBody { scene ) : Assets.CreateBananaClone(this.model.radius * 2); - this.mesh.parent = this.transform; + this.mesh.parent = this.getTransform(); /*this.aggregate = new PhysicsAggregate(this.mesh, PhysicsShapeType.SPHERE); this.aggregate.body.setMassProperties({ inertia: Vector3.Zero(), mass: 0 }); @@ -57,13 +57,13 @@ export class Star extends AbstractBody { this.light = new PointLight(`${name}Light`, Vector3.Zero(), scene); this.light.diffuse.fromArray(getRgbFromTemperature(this.model.physicalProperties.temperature).asArray()); this.light.falloffType = Light.FALLOFF_STANDARD; - this.light.parent = this.transform; + this.light.parent = this.getTransform(); - this.material = new StarMaterial(this.transform, this.model, scene); + this.material = new StarMaterial(this.getTransform(), this.model, scene); this.mesh.material = this.material; // TODO: remove when rotation is transmitted to children - setRotationQuaternion(this.transform, Quaternion.Identity()); + setRotationQuaternion(this.getTransform(), Quaternion.Identity()); this.postProcesses.push(PostProcessType.OVERLAY, PostProcessType.VOLUMETRIC_LIGHT, PostProcessType.LENS_FLARE); if (this.model.ringsUniforms !== null) this.postProcesses.push(PostProcessType.RING); diff --git a/src/ts/view/common.ts b/src/ts/view/common.ts index 3284b823f..e6586d3d9 100644 --- a/src/ts/view/common.ts +++ b/src/ts/view/common.ts @@ -1,9 +1,8 @@ -import { Vector3 } from "@babylonjs/core/Maths/math"; import { BaseModel } from "../model/common"; import { PostProcessType } from "./postProcesses/postProcessTypes"; import { TransformNode } from "@babylonjs/core/Meshes"; -export interface OrbitalObject extends ITransformable { +export interface OrbitalObject extends Transformable { parentObject: OrbitalObject | null; model: BaseModel; @@ -16,11 +15,11 @@ export interface BaseObject extends BoundingSphere { postProcesses: PostProcessType[]; } -export interface ITransformable { - transform: TransformNode; +export interface Transformable { + getTransform(): TransformNode; } -export interface BoundingSphere extends ITransformable { +export interface BoundingSphere extends Transformable { /** * Returns apparent radius of the celestial body (can be greater than the actual radius for example : ocean) */ diff --git a/src/ts/view/materials/gasPlanetMaterial.ts b/src/ts/view/materials/gasPlanetMaterial.ts index 77048b20d..f7afda586 100644 --- a/src/ts/view/materials/gasPlanetMaterial.ts +++ b/src/ts/view/materials/gasPlanetMaterial.ts @@ -4,7 +4,6 @@ import surfaceMaterialFragment from "../../../shaders/gasPlanetMaterial/fragment import surfaceMaterialVertex from "../../../shaders/gasPlanetMaterial/vertex.glsl"; import { GazColorSettings } from "./colorSettingsInterface"; import { normalRandom, randRange, randRangeInt } from "extended-random"; -import { flattenVector3Array } from "../../utils/algebra"; import { GasPlanetModel } from "../../model/planemos/gasPlanetModel"; import { StellarObject } from "../bodies/stellarObjects/stellarObject"; import { ShaderMaterial } from "@babylonjs/core/Materials/shaderMaterial"; @@ -104,7 +103,7 @@ export class GasPlanetMaterial extends ShaderMaterial { for (let i = 0; i < stellarObjects.length; i++) { const star = stellarObjects[i]; - this.setVector3(`stars[${i}].position`, star.transform.getAbsolutePosition()); + this.setVector3(`stars[${i}].position`, star.getTransform().getAbsolutePosition()); this.setVector3(`stars[${i}].color`, star instanceof Star ? star.model.surfaceColor : Vector3.One()); } this.setInt("nbStars", stellarObjects.length); diff --git a/src/ts/view/materials/telluricPlanemoMaterial.ts b/src/ts/view/materials/telluricPlanemoMaterial.ts index 65e641f22..edee2e1ad 100644 --- a/src/ts/view/materials/telluricPlanemoMaterial.ts +++ b/src/ts/view/materials/telluricPlanemoMaterial.ts @@ -173,7 +173,7 @@ export class TelluricPlanemoMaterial extends ShaderMaterial { for (let i = 0; i < stellarObjects.length; i++) { const star = stellarObjects[i]; - this.setVector3(`stars[${i}].position`, star.transform.getAbsolutePosition()); + this.setVector3(`stars[${i}].position`, star.getTransform().getAbsolutePosition()); this.setVector3(`stars[${i}].color`, star instanceof Star ? star.model.surfaceColor : Vector3.One()); } this.setInt("nbStars", stellarObjects.length); diff --git a/src/ts/view/orbitRenderer.ts b/src/ts/view/orbitRenderer.ts index 08f92eb86..e68a71602 100644 --- a/src/ts/view/orbitRenderer.ts +++ b/src/ts/view/orbitRenderer.ts @@ -36,7 +36,7 @@ export class OrbitRenderer { } points.push(points[0]); - const orbitMesh = MeshBuilder.CreateLines("orbit", { points: points }, orbitalObject.transform.getScene()); + const orbitMesh = MeshBuilder.CreateLines("orbit", { points: points }, orbitalObject.getTransform().getScene()); if (this.orbitMaterial === null) throw new Error("Orbit material is null"); orbitMesh.material = this.orbitMaterial; this.orbitMeshes.push(orbitMesh); @@ -58,7 +58,7 @@ export class OrbitRenderer { const orbitalObject = this.orbitalObjects[i]; const orbitMesh = this.orbitMeshes[i]; - orbitMesh.position = orbitalObject.parentObject?.transform.position ?? Vector3.Zero(); + orbitMesh.position = orbitalObject.parentObject?.getTransform().position ?? Vector3.Zero(); } } diff --git a/src/ts/view/postProcesses/blackHolePostProcess.ts b/src/ts/view/postProcesses/blackHolePostProcess.ts index 58a651724..87d3c6255 100644 --- a/src/ts/view/postProcesses/blackHolePostProcess.ts +++ b/src/ts/view/postProcesses/blackHolePostProcess.ts @@ -62,7 +62,7 @@ export class BlackHolePostProcess extends UberPostProcess implements ObjectPostP name: "forwardAxis", type: UniformEnumType.Vector3, get: () => { - return getForwardDirection(blackHole.transform); + return getForwardDirection(blackHole.getTransform()); } } ]; diff --git a/src/ts/view/postProcesses/flatCloudsPostProcess.ts b/src/ts/view/postProcesses/flatCloudsPostProcess.ts index 9e923e23a..d54945fc7 100644 --- a/src/ts/view/postProcesses/flatCloudsPostProcess.ts +++ b/src/ts/view/postProcesses/flatCloudsPostProcess.ts @@ -125,13 +125,6 @@ export class FlatCloudsPostProcess extends UberPostProcess implements ObjectPost return cloudUniforms.specularPower; } }, - { - name: "planetInverseRotationQuaternion", - type: UniformEnumType.Quaternion, - get: () => { - return getInverseRotationQuaternion(planet.transform); - } - }, { name: "time", type: UniformEnumType.Float, diff --git a/src/ts/view/postProcesses/oceanPostProcess.ts b/src/ts/view/postProcesses/oceanPostProcess.ts index 1f415e3f6..e02a5e52e 100644 --- a/src/ts/view/postProcesses/oceanPostProcess.ts +++ b/src/ts/view/postProcesses/oceanPostProcess.ts @@ -87,7 +87,7 @@ export class OceanPostProcess extends UberPostProcess implements ObjectPostProce name: "planetInverseRotationQuaternion", type: UniformEnumType.Quaternion, get: () => { - return getInverseRotationQuaternion(planet.transform); + return getInverseRotationQuaternion(planet.getTransform()); } }, { diff --git a/src/ts/view/postProcesses/starfieldPostProcess.ts b/src/ts/view/postProcesses/starfieldPostProcess.ts index 91ad14ccc..b185350ee 100644 --- a/src/ts/view/postProcesses/starfieldPostProcess.ts +++ b/src/ts/view/postProcesses/starfieldPostProcess.ts @@ -43,7 +43,7 @@ export class StarfieldPostProcess extends UberPostProcess { if (star instanceof BlackHole) return 1; vis = Math.min( vis, - 1.0 + Vector3.Dot(star.transform.getAbsolutePosition().normalizeToNew(), scene.getActiveController().getActiveCamera().getDirection(Axis.Z)) + 1.0 + Vector3.Dot(star.getTransform().getAbsolutePosition().normalizeToNew(), scene.getActiveController().getActiveCamera().getDirection(Axis.Z)) ); } vis = 0.5 + vis * 0.5; @@ -52,14 +52,14 @@ export class StarfieldPostProcess extends UberPostProcess { if (nearest instanceof TelluricPlanemo) { const planet = nearest as TelluricPlanemo; if (planet.postProcesses.includes(PostProcessType.ATMOSPHERE)) { - const height = planet.transform.getAbsolutePosition().length(); + const height = planet.getTransform().getAbsolutePosition().length(); //FIXME: has to be dynamic const maxHeight = Settings.ATMOSPHERE_HEIGHT; for (const star of stellarObjects) { - const sunDir = planet.transform.getAbsolutePosition().subtract(star.transform.getAbsolutePosition()).normalize(); + const sunDir = planet.getTransform().getAbsolutePosition().subtract(star.getTransform().getAbsolutePosition()).normalize(); vis2 = Math.min( vis2, - (height / maxHeight) ** 128 + Math.max(Vector3.Dot(sunDir, planet.transform.getAbsolutePosition().negate().normalize()), 0.0) ** 0.5 + (height / maxHeight) ** 128 + Math.max(Vector3.Dot(sunDir, planet.getTransform().getAbsolutePosition().negate().normalize()), 0.0) ** 0.5 ); } } diff --git a/src/ts/view/postProcesses/uniforms.ts b/src/ts/view/postProcesses/uniforms.ts index 19b212480..76b0ce557 100644 --- a/src/ts/view/postProcesses/uniforms.ts +++ b/src/ts/view/postProcesses/uniforms.ts @@ -49,13 +49,13 @@ export function getStellarObjectsUniforms(stars: OrbitalObject[]): ShaderUniform return { name: `stars[${index}].position`, type: UniformEnumType.Vector3, - get: () => star.transform.getAbsolutePosition() + get: () => star.getTransform().getAbsolutePosition() }; }), { name: "starPositions", type: UniformEnumType.Vector3Array, - get: () => stars.map((star) => star.transform.getAbsolutePosition()) + get: () => stars.map((star) => star.getTransform().getAbsolutePosition()) }, { name: "nbStars", @@ -70,7 +70,7 @@ export function getObjectUniforms(object: BaseObject): ShaderUniforms { { name: "object.position", type: UniformEnumType.Vector3, - get: () => object.transform.getAbsolutePosition() + get: () => object.getTransform().getAbsolutePosition() }, { name: "object.radius", @@ -80,7 +80,7 @@ export function getObjectUniforms(object: BaseObject): ShaderUniforms { { name: "object.rotationAxis", type: UniformEnumType.Vector3, - get: () => object.transform.up + get: () => object.getTransform().up } ]; } diff --git a/src/ts/view/spaceStation.ts b/src/ts/view/spaceStation.ts index 874b382a0..28f1e7f46 100644 --- a/src/ts/view/spaceStation.ts +++ b/src/ts/view/spaceStation.ts @@ -26,7 +26,7 @@ export class SpaceStation extends AbstractObject { this.model = new SpaceStationModel(seed, parentBody?.model); this.instance = Assets.CreateSpaceStationInstance(); - this.instance.parent = this.transform; + this.instance.parent = this.getTransform(); for (const mesh of this.instance.getChildMeshes()) { if (mesh.name.includes("ring")) { @@ -34,8 +34,8 @@ export class SpaceStation extends AbstractObject { } } - this.transform.rotate(Axis.X, this.model.physicalProperties.axialTilt); - this.transform.rotate(Axis.Y, this.model.physicalProperties.axialTilt); + this.getTransform().rotate(Axis.X, this.model.physicalProperties.axialTilt); + this.getTransform().rotate(Axis.Y, this.model.physicalProperties.axialTilt); this.postProcesses.push(PostProcessType.OVERLAY); } From df140cc8682ab7efb0bae948cbef1a1c952aa7a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 10:04:12 +0200 Subject: [PATCH 11/86] update physics playground to new floating origin system --- src/ts/playground.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/ts/playground.ts b/src/ts/playground.ts index 9dd51dba8..25c9c905d 100644 --- a/src/ts/playground.ts +++ b/src/ts/playground.ts @@ -28,6 +28,7 @@ import { UberScene } from "./controller/uberCore/uberScene"; import { Settings } from "./settings"; import { StarModel } from "./model/stellarObjects/starModel"; import { Star } from "./view/bodies/stellarObjects/star"; +import { translate } from "./controller/uberCore/transforms/basicTransform"; const canvas = document.getElementById("renderer") as HTMLCanvasElement; canvas.width = window.innerWidth; @@ -136,6 +137,13 @@ function updateBeforeHavok() { aggregate.body.applyForce(gravityDirection.scaleInPlace(gravity * mass), aggregate.body.getObjectCenterWorld()); } + if(spaceship.getAggregate().transformNode.getAbsolutePosition().length() > 100) { + const displacement = spaceship.getAggregate().transformNode.getAbsolutePosition().negate(); + for(const mesh of meshes) { + translate(mesh, displacement); + } + } + // planet thingy newton.updateInternalClock(-deltaTime / 10); aurora.updateInternalClock(-deltaTime / 10); @@ -147,17 +155,8 @@ newton.applyNextState();*/ Assets.ChunkForge.update(); } -function updateAfterHavok() { - const spaceshipPosition = spaceship.getAbsolutePosition(); - - for (const mesh of meshes) { - mesh.position.subtractInPlace(spaceshipPosition); - } -} - scene.executeWhenReady(() => { engine.loadingScreen.hideLoadingUI(); - scene.onAfterPhysicsObservable.add(updateAfterHavok); scene.onBeforePhysicsObservable.add(updateBeforeHavok); engine.runRenderLoop(() => scene.render()); }); From cb85c44517fa18423d3ce0f895cf74e7bbae94d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 16:27:15 +0200 Subject: [PATCH 12/86] fixed depth error in shaders The variable closest point was not the actual closest point to camera, the error was not big which explains in went unnoticed --- src/shaders/atmosphericScatteringFragment.glsl | 5 ++--- src/shaders/blackhole.glsl | 6 +++--- src/shaders/flatCloudsFragment.glsl | 5 +++-- src/shaders/lensflare.glsl | 5 ++++- src/shaders/mandelbulb.glsl | 5 ++--- src/shaders/matterjet.glsl | 5 ++--- src/shaders/oceanFragment.glsl | 5 ++--- src/shaders/overlayFragment.glsl | 8 +++++--- src/shaders/ringsFragment.glsl | 5 ++--- src/shaders/shadowFragment.glsl | 13 ++++++------- src/shaders/sierpinski.glsl | 7 +++---- src/shaders/utils/removeAxialTilt.glsl | 2 +- src/shaders/volumetricCloudsFragment.glsl | 5 ++--- 13 files changed, 37 insertions(+), 39 deletions(-) diff --git a/src/shaders/atmosphericScatteringFragment.glsl b/src/shaders/atmosphericScatteringFragment.glsl index f80f82965..5b4fc35ab 100644 --- a/src/shaders/atmosphericScatteringFragment.glsl +++ b/src/shaders/atmosphericScatteringFragment.glsl @@ -167,9 +167,8 @@ void main() { vec3 rayDir = normalize(pixelWorldPosition - camera.position);// normalized direction of the ray - // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); - float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion + // actual depth of the scene + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); // Cohabitation avec le shader d'océan (un jour je merge) float waterImpact, waterEscape; diff --git a/src/shaders/blackhole.glsl b/src/shaders/blackhole.glsl index de1e23898..3db7e2fa4 100644 --- a/src/shaders/blackhole.glsl +++ b/src/shaders/blackhole.glsl @@ -132,9 +132,9 @@ void main() { vec3 rayDir = normalize(pixelWorldPosition - camera.position);// normalized direction of the ray float depth = texture2D(depthSampler, vUV).r;// the depth corresponding to the pixel in the depth map - // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); - float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion + + // actual depth of the scene + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); vec4 colOut = vec4(0.0); diff --git a/src/shaders/flatCloudsFragment.glsl b/src/shaders/flatCloudsFragment.glsl index 11a1bb468..4a701b251 100644 --- a/src/shaders/flatCloudsFragment.glsl +++ b/src/shaders/flatCloudsFragment.glsl @@ -147,11 +147,12 @@ void main() { vec3 pixelWorldPosition = worldFromUV(vUV);// the pixel position in world space (near plane) // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); - float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); vec3 rayDir = normalize(pixelWorldPosition - camera.position);// normalized direction of the ray + vec3 closestPoint = camera.position + rayDir * maximumDistance; + vec4 finalColor = screenColor; if (length(closestPoint - object.position) < clouds.layerRadius) finalColor.rgb *= cloudShadows(closestPoint); diff --git a/src/shaders/lensflare.glsl b/src/shaders/lensflare.glsl index 7e0336317..cc825e4b3 100644 --- a/src/shaders/lensflare.glsl +++ b/src/shaders/lensflare.glsl @@ -108,8 +108,11 @@ void main() { float depth = texture2D(depthSampler, vUV).r;// the depth corresponding to the pixel in the depth map vec3 pixelWorldPosition = worldFromUV(vUV);// the pixel position in world space (near plane) + // actual depth of the scene + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); + vec3 rayDir = normalize(pixelWorldPosition - camera.position); // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); + vec3 closestPoint = camera.position + rayDir * maximumDistance; float objectDistance = length(object.position - camera.position); vec3 objectDirection = (object.position - camera.position) / objectDistance; diff --git a/src/shaders/mandelbulb.glsl b/src/shaders/mandelbulb.glsl index 73fa3b155..8eb30525d 100644 --- a/src/shaders/mandelbulb.glsl +++ b/src/shaders/mandelbulb.glsl @@ -129,9 +129,8 @@ void main() { vec3 rayDir = normalize(pixelWorldPosition - camera.position);// normalized direction of the ray float depth = texture2D(depthSampler, vUV).r;// the depth corresponding to the pixel in the depth map - // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); - float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion + // actual depth of the scene + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); float impactPoint, escapePoint; if (!(rayIntersectSphere(camera.position, rayDir, object.position, object.radius, impactPoint, escapePoint))) { diff --git a/src/shaders/matterjet.glsl b/src/shaders/matterjet.glsl index 32fbdd80c..ce1a174b3 100644 --- a/src/shaders/matterjet.glsl +++ b/src/shaders/matterjet.glsl @@ -101,9 +101,8 @@ void main() { vec3 pixelWorldPosition = worldFromUV(vUV);// the pixel position in world space (near plane) - // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); - float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion + // actual depth of the scene + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); vec3 rayDir = normalize(pixelWorldPosition - camera.position);// normalized direction of the ray diff --git a/src/shaders/oceanFragment.glsl b/src/shaders/oceanFragment.glsl index 0533bf234..ef7b674d1 100644 --- a/src/shaders/oceanFragment.glsl +++ b/src/shaders/oceanFragment.glsl @@ -138,9 +138,8 @@ void main() { vec3 pixelWorldPosition = worldFromUV(vUV);// the pixel position in world space (near plane) - // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); - float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion + // actual depth of the scene + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); vec3 rayDir = normalize(pixelWorldPosition - camera.position);// normalized direction of the ray diff --git a/src/shaders/overlayFragment.glsl b/src/shaders/overlayFragment.glsl index 85309655a..0a453e2eb 100644 --- a/src/shaders/overlayFragment.glsl +++ b/src/shaders/overlayFragment.glsl @@ -28,9 +28,11 @@ void main() { float depth = texture2D(depthSampler, vUV).r;// the depth corresponding to the pixel in the depth map vec3 pixelWorldPosition = worldFromUV(vUV);// the pixel position in world space (near plane) - // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); - float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion + // actual depth of the scene + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); + vec3 rayDir = normalize(pixelWorldPosition - camera.position); + + vec3 closestPoint = camera.position + rayDir * maximumDistance; if (maximumDistance < camera.far) { gl_FragColor = screenColor; diff --git a/src/shaders/ringsFragment.glsl b/src/shaders/ringsFragment.glsl index 68f501eb1..4e95d6e57 100644 --- a/src/shaders/ringsFragment.glsl +++ b/src/shaders/ringsFragment.glsl @@ -35,9 +35,8 @@ void main() { vec3 pixelWorldPosition = worldFromUV(vUV);// the pixel position in world space (near plane) - // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); - float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion + // actual depth of the scene + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); vec3 rayDir = normalize(pixelWorldPosition - camera.position);// normalized direction of the ray diff --git a/src/shaders/shadowFragment.glsl b/src/shaders/shadowFragment.glsl index 84656ad3a..189de4c7f 100644 --- a/src/shaders/shadowFragment.glsl +++ b/src/shaders/shadowFragment.glsl @@ -50,17 +50,17 @@ float sphereOccultation(vec3 rayDir, float maximumDistance) { return 1.0; } -float ringOccultation(vec3 samplePoint) { +float ringOccultation(vec3 rayDir, float maximumDistance) { if (!shadowUniforms.hasRings) { return 1.0; } float accDensity = 0.0; for (int i = 0; i < nbStars; i++) { - vec3 towardLight = normalize(stars[i].position - samplePoint); + vec3 towardLight = normalize(stars[i].position - (camera.position + rayDir * maximumDistance)); float t2; - if (rayIntersectsPlane(samplePoint, towardLight, object.position, object.rotationAxis, 0.001, t2)) { - vec3 shadowSamplePoint = samplePoint + t2 * towardLight; + if (rayIntersectsPlane(camera.position + rayDir * maximumDistance, towardLight, object.position, object.rotationAxis, 0.001, t2)) { + vec3 shadowSamplePoint = camera.position + rayDir * maximumDistance + t2 * towardLight; accDensity += ringDensityAtPoint(shadowSamplePoint) * rings.opacity; } } @@ -75,8 +75,7 @@ void main() { vec3 pixelWorldPosition = worldFromUV(vUV);// the pixel position in world space (near plane) // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); - float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); vec3 rayDir = normalize(pixelWorldPosition - camera.position);// normalized direction of the ray @@ -88,7 +87,7 @@ void main() { float sphereShadow = sphereOccultation(rayDir, maximumDistance); // maybe it is in the shadow of the rings - float ringShadow = ringOccultation(closestPoint); + float ringShadow = ringOccultation(rayDir, maximumDistance); finalColor.rgb *= min(sphereShadow, ringShadow); } diff --git a/src/shaders/sierpinski.glsl b/src/shaders/sierpinski.glsl index 684a8a119..ace1611f2 100644 --- a/src/shaders/sierpinski.glsl +++ b/src/shaders/sierpinski.glsl @@ -124,10 +124,9 @@ void main() { vec3 rayDir = normalize(pixelWorldPosition - cameraPosition);// normalized direction of the ray float depth = texture2D(depthSampler, vUV).r;// the depth corresponding to the pixel in the depth map - // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - cameraPosition) * remap(depth, 0.0, 1.0, cameraNear, cameraFar); - float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion - + // actual depth of the scene + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); + float impactPoint, escapePoint; if (!(rayIntersectSphere(cameraPosition, rayDir, planetPosition, planetRadius, impactPoint, escapePoint))) { gl_FragColor = screenColor;// if not intersecting with atmosphere, return original color diff --git a/src/shaders/utils/removeAxialTilt.glsl b/src/shaders/utils/removeAxialTilt.glsl index 0d05b01ca..365bde74d 100644 --- a/src/shaders/utils/removeAxialTilt.glsl +++ b/src/shaders/utils/removeAxialTilt.glsl @@ -3,7 +3,7 @@ vec3 removeAxialTilt(vec3 tiltedVector, vec3 tiltedAxis) { vec3 targetAxis = vec3(0.0, 1.0, 0.0); vec3 rotationRemovalAxis = cross(tiltedAxis, targetAxis); - return rotateAround(tiltedVector, rotationRemovalAxis, -acos(dot(tiltedAxis, targetAxis))); + return rotateAround(tiltedVector, rotationRemovalAxis, acos(dot(tiltedAxis, targetAxis))); } #pragma glslify: export(removeAxialTilt) \ No newline at end of file diff --git a/src/shaders/volumetricCloudsFragment.glsl b/src/shaders/volumetricCloudsFragment.glsl index 4350e3fa9..fae04ec0d 100644 --- a/src/shaders/volumetricCloudsFragment.glsl +++ b/src/shaders/volumetricCloudsFragment.glsl @@ -165,9 +165,8 @@ void main() { vec3 pixelWorldPosition = worldFromUV(vUV);// the pixel position in world space (near plane) - // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = (pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); - float maximumDistance = length(closestPoint);// the maxium ray length due to occlusion + // actual depth of the scene + float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); vec3 rayDir = normalize(pixelWorldPosition - camera.position);// normalized direction of the ray From f3c7572ed9fc323fa89d21518f9e5da9a9fc1868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 16:27:55 +0200 Subject: [PATCH 13/86] removed useless lines --- src/ts/controller/chunks/planetChunk.ts | 1 - src/ts/controller/uberCore/uberCamera.ts | 1 + src/ts/view/materials/telluricPlanemoMaterial.ts | 3 --- src/ts/view/postProcesses/uniforms.ts | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/ts/controller/chunks/planetChunk.ts b/src/ts/controller/chunks/planetChunk.ts index dba78f289..b01b4e070 100644 --- a/src/ts/controller/chunks/planetChunk.ts +++ b/src/ts/controller/chunks/planetChunk.ts @@ -40,7 +40,6 @@ export class PlanetChunk implements Transformable { this.mesh = new Mesh(`Chunk${id}`, scene); this.mesh.setEnabled(false); - this.mesh.isBlocker = true; this.mesh.material = material; /*this.mesh.material = Assets.DebugMaterial(id); //material; (this.mesh.material as StandardMaterial).disableLighting = true; diff --git a/src/ts/controller/uberCore/uberCamera.ts b/src/ts/controller/uberCore/uberCamera.ts index 4ba96c99e..12d600282 100644 --- a/src/ts/controller/uberCore/uberCamera.ts +++ b/src/ts/controller/uberCore/uberCamera.ts @@ -27,6 +27,7 @@ export class UberCamera extends FreeCamera { } getAbsolutePosition(): Vector3 { + this.computeWorldMatrix(); return this.globalPosition; } } diff --git a/src/ts/view/materials/telluricPlanemoMaterial.ts b/src/ts/view/materials/telluricPlanemoMaterial.ts index edee2e1ad..4f30c6b83 100644 --- a/src/ts/view/materials/telluricPlanemoMaterial.ts +++ b/src/ts/view/materials/telluricPlanemoMaterial.ts @@ -3,7 +3,6 @@ import { ColorMode, ColorSettings } from "./colorSettingsInterface"; import surfaceMaterialFragment from "../../../shaders/telluricPlanetMaterial/fragment.glsl"; import surfaceMaterialVertex from "../../../shaders/telluricPlanetMaterial/vertex.glsl"; import { Assets } from "../../controller/assets"; -import { flattenVector3Array } from "../../utils/algebra"; import { UberScene } from "../../controller/uberCore/uberScene"; import { TerrainSettings } from "../../model/terrain/terrainSettings"; import { SolidPhysicalProperties } from "../../model/common"; @@ -164,8 +163,6 @@ export class TelluricPlanemoMaterial extends ShaderMaterial { } public update(activeControllerPosition: Vector3, stellarObjects: StellarObject[]) { - this.planet.updateCache(true); - this.setMatrix("normalMatrix", this.planet.getWorldMatrix().clone().invert().transpose()); this.setMatrix("planetInverseRotationMatrix", getInverseRotationMatrix(this.planet)); diff --git a/src/ts/view/postProcesses/uniforms.ts b/src/ts/view/postProcesses/uniforms.ts index 76b0ce557..55a1434e1 100644 --- a/src/ts/view/postProcesses/uniforms.ts +++ b/src/ts/view/postProcesses/uniforms.ts @@ -1,7 +1,6 @@ import { UberScene } from "../../controller/uberCore/uberScene"; import { BaseObject, OrbitalObject } from "../common"; import { UniformEnumType, ShaderSamplers, ShaderUniforms, SamplerEnumType } from "../../controller/uberCore/postProcesses/types"; -import { Vector3 } from "@babylonjs/core/Maths/math.vector"; export function getActiveCameraUniforms(scene: UberScene): ShaderUniforms { return [ From ab3755d18b533fc491bbcd72e0b3eed36c197a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 17:55:11 +0200 Subject: [PATCH 14/86] small material tweaks --- src/shaders/gasPlanetMaterial/fragment.glsl | 24 ++++++-------- src/shaders/gasPlanetMaterial/vertex.glsl | 18 +++++------ src/shaders/starMaterial/fragment.glsl | 24 +++++++------- src/shaders/starMaterial/vertex.glsl | 2 +- src/ts/ui/bodyEditor/panels/gasCloudsPanel.ts | 2 +- src/ts/view/materials/gasPlanetMaterial.ts | 31 ++++++++----------- src/ts/view/materials/starMaterial.ts | 9 +++++- 7 files changed, 52 insertions(+), 58 deletions(-) diff --git a/src/shaders/gasPlanetMaterial/fragment.glsl b/src/shaders/gasPlanetMaterial/fragment.glsl index 13c964402..990e59f37 100644 --- a/src/shaders/gasPlanetMaterial/fragment.glsl +++ b/src/shaders/gasPlanetMaterial/fragment.glsl @@ -1,21 +1,10 @@ -precision lowp float; +precision highp float; #ifdef LOGARITHMICDEPTH uniform float logarithmicDepthConstant; in float vFragmentDepth; #endif -in vec3 vPositionW; -in vec3 vNormalW; -in vec3 vUnitSamplePoint; -in vec3 vSphereNormalW; - -in vec3 vPosition;// position of the vertex in sphere space - -uniform mat4 world; - -uniform vec3 playerPosition;// camera position in world space - #define MAX_STARS 5 uniform int nbStars;// number of stars struct Star { @@ -24,6 +13,14 @@ struct Star { }; uniform Star stars[MAX_STARS]; +in vec3 vPositionW; +in vec3 vNormalW; +in vec3 vUnitSamplePoint; + +in vec3 vPosition;// position of the vertex in sphere space + +uniform vec3 playerPosition;// camera position in world space + uniform vec3 color1; uniform vec3 color2; uniform vec3 color3; @@ -44,14 +41,13 @@ uniform float seed; void main() { vec3 viewRayW = normalize(playerPosition - vPositionW);// view direction in world space - vec3 sphereNormalW = vSphereNormalW; vec3 normalW = vNormalW; vec3 ndl = vec3(0.0); float specComp = 0.0; for (int i = 0; i < nbStars; i++) { vec3 starLightRayW = normalize(stars[i].position - vPositionW);// light ray direction in world space - ndl += max(0.0, dot(sphereNormalW, starLightRayW)) * stars[i].color;// diffuse lighting + ndl += max(0.0, dot(normalW, starLightRayW)) * stars[i].color;// diffuse lighting vec3 angleW = normalize(viewRayW + starLightRayW); specComp += max(0.0, dot(normalW, angleW)); diff --git a/src/shaders/gasPlanetMaterial/vertex.glsl b/src/shaders/gasPlanetMaterial/vertex.glsl index f507af6c2..a631d1e5f 100644 --- a/src/shaders/gasPlanetMaterial/vertex.glsl +++ b/src/shaders/gasPlanetMaterial/vertex.glsl @@ -1,4 +1,4 @@ -precision lowp float; +precision highp float; attribute vec3 position; attribute vec3 normal; @@ -10,21 +10,17 @@ out float vFragmentDepth; uniform mat4 world; uniform mat4 worldViewProjection; +uniform mat4 normalMatrix; -uniform vec3 planetPosition; // nécessaire temporairement le temps de régler le problème des floats - -uniform vec4 planetInverseRotationQuaternion; +uniform mat4 planetInverseRotationMatrix; out vec3 vPositionW; out vec3 vNormalW; -out vec3 vSphereNormalW; out vec3 vPosition; out vec3 vUnitSamplePoint; -#pragma glslify: applyQuaternion = require(../utils/applyQuaternion.glsl) - void main() { vec4 outPosition = worldViewProjection * vec4(position, 1.0); @@ -35,10 +31,10 @@ void main() { #endif vPositionW = vec3(world * vec4(position, 1.0)); - vNormalW = vec3(world * vec4(normal, 0.0)); - vPosition = vPositionW - planetPosition; + vNormalW = normalize(mat3(normalMatrix) * normal); + + vPosition = position; - vUnitSamplePoint = applyQuaternion(planetInverseRotationQuaternion, normalize(vPosition)); - vSphereNormalW = vec3(world * vec4(vUnitSamplePoint, 0.0)); + vUnitSamplePoint = mat3(planetInverseRotationMatrix) * normalize(vPosition); } \ No newline at end of file diff --git a/src/shaders/starMaterial/fragment.glsl b/src/shaders/starMaterial/fragment.glsl index ff7ca9d7c..9eab0e903 100644 --- a/src/shaders/starMaterial/fragment.glsl +++ b/src/shaders/starMaterial/fragment.glsl @@ -1,11 +1,11 @@ -precision lowp float; +precision highp float; -in vec3 vPosition; // position of the vertex in sphere space +in vec3 vPosition;// position of the vertex in sphere space in vec3 vUnitSamplePoint; #ifdef LOGARITHMICDEPTH - uniform float logarithmicDepthConstant; - in float vFragmentDepth; +uniform float logarithmicDepthConstant; +in float vFragmentDepth; #endif uniform vec3 starColor; @@ -18,17 +18,17 @@ uniform float seed; #pragma glslify: fractalSimplex4 = require(../utils/simplex4.glsl) void main() { - float plasmaSpeed = 0.005; - vec4 seededSamplePoint = vec4(rotateAround(vUnitSamplePoint, vec3(0.0, 1.0, 0.0), time * plasmaSpeed), mod(seed, 1e3)); + float plasmaSpeed = 0.005; + vec4 seededSamplePoint = vec4(rotateAround(vUnitSamplePoint, vec3(0.0, 1.0, 0.0), time * plasmaSpeed), mod(seed, 1e3)); - float noiseValue = fractalSimplex4(seededSamplePoint * 5.0, 8, 2.0, 2.0); + float noiseValue = fractalSimplex4(seededSamplePoint * 5.0, 8, 2.0, 2.0); - vec3 finalColor = starColor; + vec3 finalColor = starColor; - finalColor -= vec3(pow(noiseValue, 4.0)); + finalColor -= vec3(pow(noiseValue, 4.0)); - gl_FragColor = vec4(finalColor, 1.0); // apply color and lighting - #ifdef LOGARITHMICDEPTH - gl_FragDepthEXT = log2(vFragmentDepth) * logarithmicDepthConstant * 0.5; + gl_FragColor = vec4(finalColor, 1.0);// apply color and lighting + #ifdef LOGARITHMICDEPTH + gl_FragDepthEXT = log2(vFragmentDepth) * logarithmicDepthConstant * 0.5; #endif } \ No newline at end of file diff --git a/src/shaders/starMaterial/vertex.glsl b/src/shaders/starMaterial/vertex.glsl index 8e8ce6dd6..e87bfeddd 100644 --- a/src/shaders/starMaterial/vertex.glsl +++ b/src/shaders/starMaterial/vertex.glsl @@ -1,4 +1,4 @@ -precision lowp float; +precision highp float; attribute vec3 position; diff --git a/src/ts/ui/bodyEditor/panels/gasCloudsPanel.ts b/src/ts/ui/bodyEditor/panels/gasCloudsPanel.ts index 92db71dd4..a6a077447 100644 --- a/src/ts/ui/bodyEditor/panels/gasCloudsPanel.ts +++ b/src/ts/ui/bodyEditor/panels/gasCloudsPanel.ts @@ -35,7 +35,7 @@ export class GasCloudsPanel extends EditorPanel { this.sliders = [ new Slider("colorSharpness", document.getElementById("colorSharpness") as HTMLElement, 0, 100, planet.material.colorSettings.colorSharpness * 10, (val: number) => { colorSettings.colorSharpness = val / 10; - material.updateManual(); + material.updateConstants(); }) ]; } diff --git a/src/ts/view/materials/gasPlanetMaterial.ts b/src/ts/view/materials/gasPlanetMaterial.ts index f7afda586..8d0c9d8b0 100644 --- a/src/ts/view/materials/gasPlanetMaterial.ts +++ b/src/ts/view/materials/gasPlanetMaterial.ts @@ -13,10 +13,10 @@ import { Color3 } from "@babylonjs/core/Maths/math.color"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { MaterialHelper } from "@babylonjs/core/Materials/materialHelper"; import { TransformNode } from "@babylonjs/core/Meshes"; -import { getInverseRotationQuaternion } from "../../controller/uberCore/transforms/basicTransform"; +import { getInverseRotationMatrix } from "../../controller/uberCore/transforms/basicTransform"; import { Star } from "../bodies/stellarObjects/star"; -const shaderName = "gazPlanetMaterial"; +const shaderName = "gasPlanetMaterial"; Effect.ShadersStore[`${shaderName}FragmentShader`] = surfaceMaterialFragment; Effect.ShadersStore[`${shaderName}VertexShader`] = surfaceMaterialVertex; @@ -26,16 +26,15 @@ export class GasPlanetMaterial extends ShaderMaterial { private clock = 0; constructor(planetName: string, planet: TransformNode, model: GasPlanetModel, scene: Scene) { - super(`${planetName}SurfaceColor`, scene, shaderName, { + super(`${planetName}GasSurfaceColor`, scene, shaderName, { attributes: ["position", "normal"], uniforms: [ "world", "worldViewProjection", + "normalMatrix", "seed", - "planetPosition", - "stars", "nbStars", @@ -46,13 +45,13 @@ export class GasPlanetMaterial extends ShaderMaterial { "time", - "planetInverseRotationQuaternion", + "planetInverseRotationMatrix", "playerPosition", "logarithmicDepthConstant" ], - defines: ["#define LOGARITHMICDEPTH"] + //defines: ["#define LOGARITHMICDEPTH"] }); this.planet = planet; @@ -73,33 +72,31 @@ export class GasPlanetMaterial extends ShaderMaterial { colorSharpness: randRangeInt(40, 80, model.rng, 80) / 10 }; - this.onBindObservable.add(() => { + /*this.onBindObservable.add(() => { const effect = this.getEffect(); MaterialHelper.BindLogDepth(null, effect, scene); - }); + });*/ this.setFloat("seed", model.seed); - this.setVector3("playerPosition", Vector3.Zero()); - this.setVector3("planetPosition", this.planet.getAbsolutePosition()); - this.setColor3("color1", this.colorSettings.color1); this.setColor3("color2", this.colorSettings.color2); this.setColor3("color3", this.colorSettings.color3); - this.updateManual(); + this.updateConstants(); } - public updateManual(): void { + public updateConstants(): void { this.setFloat("colorSharpness", this.colorSettings.colorSharpness); } public update(player: AbstractController, stellarObjects: StellarObject[], deltaTime: number) { this.clock += deltaTime; - this.setQuaternion("planetInverseRotationQuaternion", getInverseRotationQuaternion(this.planet)); + this.setMatrix("normalMatrix", this.planet.getWorldMatrix().clone().invert().transpose()); + this.setMatrix("planetInverseRotationMatrix", getInverseRotationMatrix(this.planet)); - this.setVector3("playerPosition", player.getTransform().getAbsolutePosition()); + this.setVector3("playerPosition", player.getActiveCamera().getAbsolutePosition()); for (let i = 0; i < stellarObjects.length; i++) { const star = stellarObjects[i]; @@ -108,8 +105,6 @@ export class GasPlanetMaterial extends ShaderMaterial { } this.setInt("nbStars", stellarObjects.length); - this.setVector3("planetPosition", this.planet.getAbsolutePosition()); - this.setFloat("time", this.clock % 100000); } } diff --git a/src/ts/view/materials/starMaterial.ts b/src/ts/view/materials/starMaterial.ts index 745677d05..6214f629f 100644 --- a/src/ts/view/materials/starMaterial.ts +++ b/src/ts/view/materials/starMaterial.ts @@ -9,6 +9,7 @@ import { ShaderMaterial } from "@babylonjs/core/Materials/shaderMaterial"; import { Scene } from "@babylonjs/core/scene"; import { TransformNode } from "@babylonjs/core/Meshes"; import { getInverseRotationQuaternion } from "../../controller/uberCore/transforms/basicTransform"; +import { MaterialHelper } from "@babylonjs/core/Materials/materialHelper"; const shaderName = "starMaterial"; Effect.ShadersStore[`${shaderName}FragmentShader`] = starMaterialFragment; @@ -22,11 +23,17 @@ export class StarMaterial extends ShaderMaterial { constructor(star: TransformNode, model: StarModel, scene: Scene) { super("starColor", scene, shaderName, { attributes: ["position"], - uniforms: ["world", "worldViewProjection", "seed", "starColor", "starPosition", "starInverseRotationQuaternion", "time", "logarithmicDepthConstant"] + uniforms: ["world", "worldViewProjection", "seed", "starColor", "starPosition", "starInverseRotationQuaternion", "time", "logarithmicDepthConstant"], + //defines: ["#define LOGARITHMICDEPTH"] }); this.star = star; this.physicalProperties = model.physicalProperties; this.starSeed = model.seed; + + /*this.onBindObservable.add(() => { + const effect = this.getEffect(); + MaterialHelper.BindLogDepth(null, effect, scene); + });*/ } public update(internalTime: number) { From 90b2da62886d7d73f5fd78701b18c2b0abb7043c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 18:35:11 +0200 Subject: [PATCH 15/86] first version of non moving nearest body The main issue is that the starry sky must rotate as well but this is not the case yet --- src/ts/controller/starSystem.ts | 54 +++++++++++-------- .../uberCore/transforms/basicTransform.ts | 2 + src/ts/index.ts | 2 +- src/ts/view/bodies/abstractObject.ts | 37 +++++-------- src/ts/view/common.ts | 2 +- 5 files changed, 50 insertions(+), 47 deletions(-) diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index e78aa8ad3..00c86d1f3 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -25,6 +25,7 @@ import { MandelbulbModel } from "../model/planemos/mandelbulbModel"; import { Mandelbulb } from "../view/bodies/planemos/mandelbulb"; import { getMoonSeed } from "../model/planemos/common"; import { NeutronStarModel } from "../model/stellarObjects/neutronStarModel"; +import { ShipController } from "../spaceship/shipController"; export class StarSystem { private readonly scene: UberScene; @@ -377,45 +378,54 @@ export class StarSystem { const controller = this.scene.getActiveController(); const nearestBody = this.getNearestBody(this.scene.getActiveUberCamera().position); - for (const object of this.orbitalObjects) { - object.updateInternalClock(deltaTime); + nearestBody.updateInternalClock(deltaTime); + const initialPosition = nearestBody.getTransform().getAbsolutePosition().clone(); + nearestBody.updateOrbitalPosition(deltaTime); + const newPosition = nearestBody.getTransform().getAbsolutePosition().clone(); + const nearestBodyDisplacement = newPosition.subtract(initialPosition); + translate(nearestBody.getTransform(), nearestBodyDisplacement.negate()); - const initialPosition = object.getTransform().getAbsolutePosition().clone(); - object.updateOrbitalPosition(); - const newPosition = object.getTransform().getAbsolutePosition().clone(); + const dthetaNearest = nearestBody.updateRotation(deltaTime); + nearestBody.updateRotation(-deltaTime); - // if the controller is close to the body, it will follow its movement - const orbitLimit = object instanceof SpaceStation ? 200 : 10; - if (isOrbiting(controller, object, orbitLimit) && this.getNearestObject() === object) { - translate(controller.getTransform(), newPosition.subtract(initialPosition)); - } + // As the nearest object is kept in place, we need to transfer its movement to other bodies + for (const object of this.orbitalObjects) { + if (object === nearestBody) continue; + translate(object.getTransform(), nearestBodyDisplacement.negate()); + rotateAround(object.getTransform(), nearestBody.getTransform().getAbsolutePosition(), nearestBody.getRotationAxis(), -dthetaNearest); + } - const dtheta = object.updateRotation(deltaTime); + for (const object of this.orbitalObjects) { + if(object === nearestBody) continue; - // if the controller is close to the object and it is a body, it will follow its rotation - if (isOrbiting(controller, object) && this.getNearestBody() === object) { - rotateAround(controller.getTransform(), object.getTransform().getAbsolutePosition(), object.getRotationAxis(), dtheta); - } + object.updateInternalClock(deltaTime); + object.updateOrbitalPosition(deltaTime); + object.updateRotation(deltaTime); } controller.update(deltaTime); - /*const direction = controller.aggregate.transformNode.getAbsolutePosition().subtract(object.nextState.position).normalize(); - const gravity = 9.81; - controller.aggregate.body.applyForce(direction.scale(gravity), controller.aggregate.body.getObjectCenterWorld());*/ + for (const body of this.telluricPlanets.concat(this.satellites)) body.updateLOD(controller.getTransform().getAbsolutePosition()); + + for (const object of this.orbitalObjects) object.computeCulling(controller.getActiveCamera()); // floating origin - if(controller.getActiveCamera().getAbsolutePosition().length() > 100) { + if (controller.getActiveCamera().getAbsolutePosition().length() > 0) { const displacementTranslation = controller.getTransform().getAbsolutePosition().negate(); this.translateEverythingNow(displacementTranslation); translate(controller.getTransform(), displacementTranslation); } - for (const body of this.telluricPlanets.concat(this.satellites)) body.updateLOD(controller.getTransform().getAbsolutePosition()); + this.updateShaders(deltaTime); + } - for (const object of this.orbitalObjects) object.computeCulling(controller.getActiveCamera()); + public updateShaders(deltaTime: number) { + const controller = this.scene.getActiveController(); + const nearestBody = this.getNearestBody(this.scene.getActiveUberCamera().position); - for (const planet of this.planemosWithMaterial) planet.updateMaterial(controller, this.stellarObjects, deltaTime); + for (const planet of this.planemosWithMaterial) { + planet.updateMaterial(controller, this.stellarObjects, deltaTime); + } for (const stellarObject of this.stellarObjects) { if (stellarObject instanceof Star) stellarObject.updateMaterial(); diff --git a/src/ts/controller/uberCore/transforms/basicTransform.ts b/src/ts/controller/uberCore/transforms/basicTransform.ts index 4504793c1..c452e10f1 100644 --- a/src/ts/controller/uberCore/transforms/basicTransform.ts +++ b/src/ts/controller/uberCore/transforms/basicTransform.ts @@ -8,6 +8,7 @@ export function getPosition(transformNode: TransformNode): Vector3 { export function translate(transformNode: TransformNode, displacement: Vector3): void { transformNode.setAbsolutePosition(transformNode.getAbsolutePosition().add(displacement)); + transformNode.computeWorldMatrix(true); } export function rotateAround(transformNode: TransformNode, pivot: Vector3, axis: Vector3, amount: number): void { @@ -31,6 +32,7 @@ export function getInverseRotationQuaternion(transformNode: TransformNode): Quat export function setRotationQuaternion(transformNode: TransformNode, newRotation: Quaternion): void { transformNode.rotationQuaternion = newRotation; + transformNode.computeWorldMatrix(true); } export function getRotationMatrix(transformNode: TransformNode): Matrix { diff --git a/src/ts/index.ts b/src/ts/index.ts index fcbd0a7a2..15c527b22 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -51,7 +51,7 @@ spaceshipController.addInput(gamepad); spaceshipController.addInput(mouse); const physicsViewer = new PhysicsViewer(); -physicsViewer.showBody(spaceshipController.aggregate.body); +//physicsViewer.showBody(spaceshipController.aggregate.body); mouse.onMouseLeaveObservable.add(() => { if (scene.getActiveController() === spaceshipController) engine.pause(); diff --git a/src/ts/view/bodies/abstractObject.ts b/src/ts/view/bodies/abstractObject.ts index c31ba8240..4756a66cc 100644 --- a/src/ts/view/bodies/abstractObject.ts +++ b/src/ts/view/bodies/abstractObject.ts @@ -6,7 +6,11 @@ import { getPointOnOrbit } from "../../model/orbit/orbit"; import { PostProcessType } from "../postProcesses/postProcessTypes"; import { Cullable } from "./cullable"; import { TransformNode } from "@babylonjs/core/Meshes"; -import { getRotationQuaternion, setRotationQuaternion } from "../../controller/uberCore/transforms/basicTransform"; +import { + getRotationQuaternion, + setRotationQuaternion, + translate +} from "../../controller/uberCore/transforms/basicTransform"; import { Camera } from "@babylonjs/core/Cameras/camera"; export abstract class AbstractObject implements OrbitalObject, BaseObject, Cullable { @@ -17,9 +21,6 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla //TODO: make an universal clock ?? or not it could be funny private internalClock = 0; - private theta = 0; - readonly rotationMatrixAroundAxis = new Matrix(); - readonly name: string; abstract readonly model: BaseModel; @@ -53,14 +54,6 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla return this.transform.up; } - /** - * Returns the rotation angle of the body around its axis - * @returns the rotation angle of the body around its axis - */ - public getRotationAngle(): number { - return this.theta; - } - /** * Returns the internal clock of the body (in seconds) * @returns the internal clock of the body (in seconds) @@ -77,15 +70,17 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla this.internalClock += deltaTime; } - public updateOrbitalPosition() { - if (this.model.orbit.period > 0) { - const barycenter = this.parentObject?.getTransform().getAbsolutePosition() ?? Vector3.Zero(); + public updateOrbitalPosition(deltaTime: number) { + if (this.model.orbit.period > 0 && this.parentObject !== null) { + this.parentObject.getTransform().computeWorldMatrix(true); + const barycenter = this.parentObject.getTransform().getAbsolutePosition(); /*const orbitalPlaneNormal = this.parentObject?.transform.up ?? Vector3.Up(); - - if (this.model.orbit.isPlaneAlignedWithParent) this.model.orbit.normalToPlane = orbitalPlaneNormal;*/ +if (this.model.orbit.isPlaneAlignedWithParent) this.model.orbit.normalToPlane = orbitalPlaneNormal;*/ const newPosition = getPointOnOrbit(barycenter, this.model.orbit, this.internalClock); - this.transform.setAbsolutePosition(newPosition); + const oldPosition = getPointOnOrbit(barycenter, this.model.orbit, this.internalClock - deltaTime); + const translation = newPosition.subtract(oldPosition); + translate(this.transform, translation); } } @@ -100,12 +95,8 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla } const dtheta = (2 * Math.PI * deltaTime) / this.model.physicalProperties.rotationPeriod; - this.theta += dtheta; - - this.rotationMatrixAroundAxis.copyFrom(Matrix.RotationAxis(new Vector3(0, 1, 0), this.theta)); - const elementaryRotationMatrix = Matrix.RotationAxis(this.getRotationAxis(), dtheta); - const elementaryRotationQuaternion = Quaternion.FromRotationMatrix(elementaryRotationMatrix); + const elementaryRotationQuaternion = Quaternion.RotationAxis(this.getRotationAxis(), dtheta); const newQuaternion = elementaryRotationQuaternion.multiply(getRotationQuaternion(this.transform)); setRotationQuaternion(this.transform, newQuaternion); diff --git a/src/ts/view/common.ts b/src/ts/view/common.ts index e6586d3d9..f8e7509ea 100644 --- a/src/ts/view/common.ts +++ b/src/ts/view/common.ts @@ -7,7 +7,7 @@ export interface OrbitalObject extends Transformable { model: BaseModel; - updateOrbitalPosition(): void; + updateOrbitalPosition(deltaTime: number): void; } export interface BaseObject extends BoundingSphere { From bb63596fd0c72f632d486323ff2c575b4bb04e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 18:58:15 +0200 Subject: [PATCH 16/86] starfield rotates as well it accounts for the stillness of the nearest body --- src/shaders/starfieldFragment.glsl | 4 +++ src/ts/controller/postProcessManager.ts | 5 +-- src/ts/controller/starSystem.ts | 8 ++++- .../postProcesses/starfieldPostProcess.ts | 31 +++++++++++-------- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/shaders/starfieldFragment.glsl b/src/shaders/starfieldFragment.glsl index 429d47e95..b9aea534d 100644 --- a/src/shaders/starfieldFragment.glsl +++ b/src/shaders/starfieldFragment.glsl @@ -7,6 +7,8 @@ uniform sampler2D depthSampler;// the depth map of the camera uniform sampler2D starfieldTexture;// the starfield texture +uniform mat4 starfieldRotation; + #pragma glslify: camera = require(./utils/camera.glsl) uniform float visibility;// visibility of the starfield @@ -22,6 +24,8 @@ void main() { vec3 rayDir = normalize(pixelWorldPosition - camera.position);// normalized direction of the ray + rayDir = vec3(starfieldRotation * vec4(rayDir, 1.0)); + vec4 finalColor = screenColor; if (screenColor == vec4(0.0)) { diff --git a/src/ts/controller/postProcessManager.ts b/src/ts/controller/postProcessManager.ts index cbe4294ff..994945b37 100644 --- a/src/ts/controller/postProcessManager.ts +++ b/src/ts/controller/postProcessManager.ts @@ -34,6 +34,7 @@ import { MatterJetPostProcess } from "../view/postProcesses/matterJetPostProcess import { NeutronStar } from "../view/bodies/stellarObjects/neutronStar"; import { ShadowPostProcess } from "../view/postProcesses/shadowPostProcess"; import { LensFlarePostProcess } from "../view/postProcesses/lensFlarePostProcess"; +import { Quaternion } from "@babylonjs/core/Maths/math"; /** * The order in which the post processes are rendered when away from a planet @@ -257,8 +258,8 @@ export class PostProcessManager { * @param stellarObjects An array of stars or black holes * @param planets An array of planets */ - public addStarField(stellarObjects: StellarObject[], planets: AbstractBody[]) { - this.starFields.push(new StarfieldPostProcess(this.scene, stellarObjects, planets)); + public addStarField(stellarObjects: StellarObject[], planets: AbstractBody[], starfieldRotation: Quaternion) { + this.starFields.push(new StarfieldPostProcess(this.scene, stellarObjects, planets, starfieldRotation)); } /** diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index 00c86d1f3..0b76ea9fb 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -26,12 +26,15 @@ import { Mandelbulb } from "../view/bodies/planemos/mandelbulb"; import { getMoonSeed } from "../model/planemos/common"; import { NeutronStarModel } from "../model/stellarObjects/neutronStarModel"; import { ShipController } from "../spaceship/shipController"; +import { Quaternion } from "@babylonjs/core/Maths/math"; export class StarSystem { private readonly scene: UberScene; readonly postProcessManager: PostProcessManager; + private readonly starfieldRotation: Quaternion = Quaternion.Identity(); + private readonly orbitalObjects: AbstractObject[] = []; private readonly spaceStations: SpaceStation[] = []; @@ -365,7 +368,7 @@ export class StarSystem { * @private */ private initPostProcesses() { - this.postProcessManager.addStarField(this.stellarObjects, this.celestialBodies); + this.postProcessManager.addStarField(this.stellarObjects, this.celestialBodies, this.starfieldRotation); for (const object of this.orbitalObjects) this.postProcessManager.addObject(object, this.stellarObjects); this.postProcessManager.setBody(this.getNearestBody(this.scene.getActiveUberCamera().position)); } @@ -394,6 +397,9 @@ export class StarSystem { translate(object.getTransform(), nearestBodyDisplacement.negate()); rotateAround(object.getTransform(), nearestBody.getTransform().getAbsolutePosition(), nearestBody.getRotationAxis(), -dthetaNearest); } + + const starfieldAdditionalRotation = Quaternion.RotationAxis(nearestBody.getRotationAxis(), dthetaNearest); + this.starfieldRotation.copyFrom(starfieldAdditionalRotation.multiply(this.starfieldRotation)); for (const object of this.orbitalObjects) { if(object === nearestBody) continue; diff --git a/src/ts/view/postProcesses/starfieldPostProcess.ts b/src/ts/view/postProcesses/starfieldPostProcess.ts index b185350ee..cbbd5274b 100644 --- a/src/ts/view/postProcesses/starfieldPostProcess.ts +++ b/src/ts/view/postProcesses/starfieldPostProcess.ts @@ -13,26 +13,33 @@ import { Effect } from "@babylonjs/core/Materials/effect"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { PostProcessType } from "./postProcessTypes"; import { Axis } from "@babylonjs/core/Maths/math.axis"; -import { UniformEnumType, ShaderSamplers, ShaderUniforms, SamplerEnumType } from "../../controller/uberCore/postProcesses/types"; +import { + SamplerEnumType, + ShaderSamplers, + ShaderUniforms, + UniformEnumType +} from "../../controller/uberCore/postProcesses/types"; +import { Matrix, Quaternion } from "@babylonjs/core/Maths/math"; const shaderName = "starfield"; Effect.ShadersStore[`${shaderName}FragmentShader`] = starfieldFragment; -export interface StarfieldSettings { - foo: number; -} - export class StarfieldPostProcess extends UberPostProcess { - settings: StarfieldSettings; - - constructor(scene: UberScene, stellarObjects: StellarObject[], bodies: AbstractBody[]) { - const settings: StarfieldSettings = { - foo: 1 - }; + constructor(scene: UberScene, stellarObjects: StellarObject[], bodies: AbstractBody[], starfieldRotation: Quaternion) { const uniforms: ShaderUniforms = [ ...getActiveCameraUniforms(scene), ...getStellarObjectsUniforms(stellarObjects), + { + name: "starfieldRotation", + type: UniformEnumType.Matrix, + get: () => { + const rotationMatrix = new Matrix(); + starfieldRotation.toRotationMatrix(rotationMatrix); + console.log(starfieldRotation); + return rotationMatrix; + } + }, { name: "visibility", type: UniformEnumType.Float, @@ -82,7 +89,5 @@ export class StarfieldPostProcess extends UberPostProcess { ]; super("starfield", shaderName, uniforms, samplers, scene); - - this.settings = settings; } } From 20efa099a4aa8645da07973b53ab3c004d5b6a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:19:18 +0200 Subject: [PATCH 17/86] fixed starfield rotation for blackhole --- src/shaders/blackhole.glsl | 5 ++ src/ts/blackHoleDemo.ts | 4 +- src/ts/controller/postProcessManager.ts | 62 ++----------------- src/ts/controller/starSystem.ts | 54 +++++++++++++++- .../postProcesses/blackHolePostProcess.ts | 13 +++- 5 files changed, 74 insertions(+), 64 deletions(-) diff --git a/src/shaders/blackhole.glsl b/src/shaders/blackhole.glsl index 3db7e2fa4..4fb647d8f 100644 --- a/src/shaders/blackhole.glsl +++ b/src/shaders/blackhole.glsl @@ -22,6 +22,8 @@ uniform sampler2D depthSampler; uniform sampler2D starfieldTexture; +uniform mat4 starfieldRotation; + #pragma glslify: camera = require(./utils/camera.glsl) #pragma glslify: remap = require(./utils/remap.glsl) @@ -198,6 +200,8 @@ void main() { } } + rayDir = vec3(starfieldRotation * vec4(rayDir, 1.0)); + //FIXME: when WebGPU supports texture2D inside if statements, move this to not compute it when occluded /*vec2 uv = uvFromWorld(positionBHS); vec4 bg = vec4(0.0); @@ -208,6 +212,7 @@ void main() { sign(rayDir.z) * acos(rayDir.x / length(vec2(rayDir.x, rayDir.z))) / 6.28318530718, acos(rayDir.y) / 3.14159265359 ); + vec4 bg = texture2D(starfieldTexture, starfieldUV); //} diff --git a/src/ts/blackHoleDemo.ts b/src/ts/blackHoleDemo.ts index 1be16cf26..0c7f1a2d1 100644 --- a/src/ts/blackHoleDemo.ts +++ b/src/ts/blackHoleDemo.ts @@ -64,10 +64,10 @@ const starSystem = new StarSystem(starSystemSeed, scene); engine.setStarSystem(starSystem, false); const BH = starSystem.makeBlackHole(0); -BH.model.orbit.radius = BH.getRadius() * 4; +BH.model.orbit.radius = 0; const planet = starSystem.makeTelluricPlanet(); -planet.model.orbit.radius = 10000e3; +planet.model.orbit.radius = 10 * planet.getRadius(); document.addEventListener("keydown", (e) => { if (e.key === "g") { diff --git a/src/ts/controller/postProcessManager.ts b/src/ts/controller/postProcessManager.ts index 994945b37..1cb1acdd4 100644 --- a/src/ts/controller/postProcessManager.ts +++ b/src/ts/controller/postProcessManager.ts @@ -47,7 +47,7 @@ const spaceRenderingOrder: PostProcessType[] = [ PostProcessType.ATMOSPHERE, PostProcessType.MANDELBULB, PostProcessType.RING, - PostProcessType.BLACK_HOLE, + PostProcessType.BLACK_HOLE ]; /** @@ -61,7 +61,7 @@ const surfaceRenderingOrder: PostProcessType[] = [ PostProcessType.RING, PostProcessType.OCEAN, PostProcessType.CLOUDS, - PostProcessType.ATMOSPHERE, + PostProcessType.ATMOSPHERE ]; /** @@ -291,8 +291,8 @@ export class PostProcessManager { * Creates a new BlackHole postprocess for the given black hole and adds it to the manager. * @param blackHole A black hole */ - public addBlackHole(blackHole: BlackHole) { - const blackhole = new BlackHolePostProcess(blackHole, this.scene); + public addBlackHole(blackHole: BlackHole, starfieldRotation: Quaternion) { + const blackhole = new BlackHolePostProcess(blackHole, this.scene, starfieldRotation); this.blackHoles.push(blackhole); } @@ -316,60 +316,6 @@ export class PostProcessManager { this.lensFlares.push(new LensFlarePostProcess(stellarObject, this.scene)); } - /** - * Adds all post processes for the given body. - * @param body A body - * @param stellarObjects An array of stars or black holes lighting the body - */ - public addObject(body: AbstractObject, stellarObjects: StellarObject[]) { - for (const postProcess of body.postProcesses) { - switch (postProcess) { - case PostProcessType.RING: - if (!(body instanceof AbstractBody)) throw new Error("Rings post process can only be added to bodies. Source:" + body.name); - this.addRings(body, stellarObjects); - break; - case PostProcessType.OVERLAY: - this.addOverlay(body); - break; - case PostProcessType.ATMOSPHERE: - if (!(body instanceof GasPlanet) && !(body instanceof TelluricPlanemo)) - throw new Error("Atmosphere post process can only be added to gas or telluric planets. Source:" + body.name); - this.addAtmosphere(body as GasPlanet | TelluricPlanemo, stellarObjects); - break; - case PostProcessType.CLOUDS: - if (!(body instanceof TelluricPlanemo)) throw new Error("Clouds post process can only be added to telluric planets. Source:" + body.name); - this.addClouds(body as TelluricPlanemo, stellarObjects); - break; - case PostProcessType.OCEAN: - if (!(body instanceof TelluricPlanemo)) throw new Error("Ocean post process can only be added to telluric planets. Source:" + body.name); - this.addOcean(body as TelluricPlanemo, stellarObjects); - break; - case PostProcessType.VOLUMETRIC_LIGHT: - if (!(body instanceof Star)) throw new Error("Volumetric light post process can only be added to stars. Source:" + body.name); - this.addVolumetricLight(body as Star); - break; - case PostProcessType.MANDELBULB: - if (!(body instanceof Mandelbulb)) throw new Error("Mandelbulb post process can only be added to mandelbulbs. Source:" + body.name); - this.addMandelbulb(body as Mandelbulb, stellarObjects); - break; - case PostProcessType.BLACK_HOLE: - if (!(body instanceof BlackHole)) throw new Error("Black hole post process can only be added to black holes. Source:" + body.name); - this.addBlackHole(body as BlackHole); - break; - case PostProcessType.MATTER_JETS: - if (!(body instanceof NeutronStar)) throw new Error("Matter jets post process can only be added to neutron stars. Source:" + body.name); - this.addMatterJet(body as NeutronStar); - break; - case PostProcessType.SHADOW: - this.addShadowCaster(body as AbstractBody, stellarObjects); - break; - case PostProcessType.LENS_FLARE: - this.addLensFlare(body as StellarObject); - break; - } - } - } - public setBody(body: AbstractBody) { if (this.currentBody === body) return; this.currentBody = body; diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index 0b76ea9fb..e5af44e9e 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -27,6 +27,7 @@ import { getMoonSeed } from "../model/planemos/common"; import { NeutronStarModel } from "../model/stellarObjects/neutronStarModel"; import { ShipController } from "../spaceship/shipController"; import { Quaternion } from "@babylonjs/core/Maths/math"; +import { PostProcessType } from "../view/postProcesses/postProcessTypes"; export class StarSystem { private readonly scene: UberScene; @@ -369,7 +370,54 @@ export class StarSystem { */ private initPostProcesses() { this.postProcessManager.addStarField(this.stellarObjects, this.celestialBodies, this.starfieldRotation); - for (const object of this.orbitalObjects) this.postProcessManager.addObject(object, this.stellarObjects); + for (const object of this.orbitalObjects) { + for (const postProcess of object.postProcesses) { + switch (postProcess) { + case PostProcessType.RING: + if (!(object instanceof AbstractBody)) throw new Error("Rings post process can only be added to bodies. Source:" + object.name); + this.postProcessManager.addRings(object, this.stellarObjects); + break; + case PostProcessType.OVERLAY: + this.postProcessManager.addOverlay(object); + break; + case PostProcessType.ATMOSPHERE: + if (!(object instanceof GasPlanet) && !(object instanceof TelluricPlanemo)) + throw new Error("Atmosphere post process can only be added to gas or telluric planets. Source:" + object.name); + this.postProcessManager.addAtmosphere(object as GasPlanet | TelluricPlanemo, this.stellarObjects); + break; + case PostProcessType.CLOUDS: + if (!(object instanceof TelluricPlanemo)) throw new Error("Clouds post process can only be added to telluric planets. Source:" + object.name); + this.postProcessManager.addClouds(object as TelluricPlanemo, this.stellarObjects); + break; + case PostProcessType.OCEAN: + if (!(object instanceof TelluricPlanemo)) throw new Error("Ocean post process can only be added to telluric planets. Source:" + object.name); + this.postProcessManager.addOcean(object as TelluricPlanemo, this.stellarObjects); + break; + case PostProcessType.VOLUMETRIC_LIGHT: + if (!(object instanceof Star)) throw new Error("Volumetric light post process can only be added to stars. Source:" + object.name); + this.postProcessManager.addVolumetricLight(object as Star); + break; + case PostProcessType.MANDELBULB: + if (!(object instanceof Mandelbulb)) throw new Error("Mandelbulb post process can only be added to mandelbulbs. Source:" + object.name); + this.postProcessManager.addMandelbulb(object as Mandelbulb, this.stellarObjects); + break; + case PostProcessType.BLACK_HOLE: + if (!(object instanceof BlackHole)) throw new Error("Black hole post process can only be added to black holes. Source:" + object.name); + this.postProcessManager.addBlackHole(object as BlackHole, this.starfieldRotation); + break; + case PostProcessType.MATTER_JETS: + if (!(object instanceof NeutronStar)) throw new Error("Matter jets post process can only be added to neutron stars. Source:" + object.name); + this.postProcessManager.addMatterJet(object as NeutronStar); + break; + case PostProcessType.SHADOW: + this.postProcessManager.addShadowCaster(object as AbstractBody, this.stellarObjects); + break; + case PostProcessType.LENS_FLARE: + this.postProcessManager.addLensFlare(object as StellarObject); + break; + } + } + } this.postProcessManager.setBody(this.getNearestBody(this.scene.getActiveUberCamera().position)); } @@ -397,12 +445,12 @@ export class StarSystem { translate(object.getTransform(), nearestBodyDisplacement.negate()); rotateAround(object.getTransform(), nearestBody.getTransform().getAbsolutePosition(), nearestBody.getRotationAxis(), -dthetaNearest); } - + const starfieldAdditionalRotation = Quaternion.RotationAxis(nearestBody.getRotationAxis(), dthetaNearest); this.starfieldRotation.copyFrom(starfieldAdditionalRotation.multiply(this.starfieldRotation)); for (const object of this.orbitalObjects) { - if(object === nearestBody) continue; + if (object === nearestBody) continue; object.updateInternalClock(deltaTime); object.updateOrbitalPosition(deltaTime); diff --git a/src/ts/view/postProcesses/blackHolePostProcess.ts b/src/ts/view/postProcesses/blackHolePostProcess.ts index 87d3c6255..d2e09958d 100644 --- a/src/ts/view/postProcesses/blackHolePostProcess.ts +++ b/src/ts/view/postProcesses/blackHolePostProcess.ts @@ -8,6 +8,7 @@ import { Assets } from "../../controller/assets"; import { Effect } from "@babylonjs/core/Materials/effect"; import { getForwardDirection } from "../../controller/uberCore/transforms/basicTransform"; import { UniformEnumType, ShaderSamplers, ShaderUniforms, SamplerEnumType } from "../../controller/uberCore/postProcesses/types"; +import { Matrix, Quaternion } from "@babylonjs/core/Maths/math"; const shaderName = "blackhole"; Effect.ShadersStore[`${shaderName}FragmentShader`] = blackHoleFragment; @@ -21,7 +22,7 @@ export class BlackHolePostProcess extends UberPostProcess implements ObjectPostP readonly settings: BlackHoleSettings; readonly object: BlackHole; - constructor(blackHole: BlackHole, scene: UberScene) { + constructor(blackHole: BlackHole, scene: UberScene, starfieldRotation: Quaternion) { const settings: BlackHoleSettings = { accretionDiskRadius: blackHole.model.physicalProperties.accretionDiskRadius, rotationPeriod: 1.5 @@ -30,6 +31,16 @@ export class BlackHolePostProcess extends UberPostProcess implements ObjectPostP const uniforms: ShaderUniforms = [ ...getObjectUniforms(blackHole), ...getActiveCameraUniforms(scene), + { + name: "starfieldRotation", + type: UniformEnumType.Matrix, + get: () => { + const rotationMatrix = new Matrix(); + starfieldRotation.toRotationMatrix(rotationMatrix); + console.log(starfieldRotation); + return rotationMatrix; + } + }, { name: "time", type: UniformEnumType.Float, From 005119ca6f3b8e6b37df5e09767ded25583baa88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:35:42 +0200 Subject: [PATCH 18/86] rotation compensation disabled when far enough --- src/ts/controller/starSystem.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index e5af44e9e..1bebca0be 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -429,6 +429,9 @@ export class StarSystem { const controller = this.scene.getActiveController(); const nearestBody = this.getNearestBody(this.scene.getActiveUberCamera().position); + const shouldCompensateRotation = + Vector3.Distance(nearestBody.getTransform().getAbsolutePosition(), controller.getActiveCamera().getAbsolutePosition()) < nearestBody.getRadius() * 4; + nearestBody.updateInternalClock(deltaTime); const initialPosition = nearestBody.getTransform().getAbsolutePosition().clone(); nearestBody.updateOrbitalPosition(deltaTime); @@ -437,17 +440,19 @@ export class StarSystem { translate(nearestBody.getTransform(), nearestBodyDisplacement.negate()); const dthetaNearest = nearestBody.updateRotation(deltaTime); - nearestBody.updateRotation(-deltaTime); + if (shouldCompensateRotation) nearestBody.updateRotation(-deltaTime); // As the nearest object is kept in place, we need to transfer its movement to other bodies for (const object of this.orbitalObjects) { if (object === nearestBody) continue; translate(object.getTransform(), nearestBodyDisplacement.negate()); - rotateAround(object.getTransform(), nearestBody.getTransform().getAbsolutePosition(), nearestBody.getRotationAxis(), -dthetaNearest); + if (shouldCompensateRotation) rotateAround(object.getTransform(), nearestBody.getTransform().getAbsolutePosition(), nearestBody.getRotationAxis(), -dthetaNearest); } - const starfieldAdditionalRotation = Quaternion.RotationAxis(nearestBody.getRotationAxis(), dthetaNearest); - this.starfieldRotation.copyFrom(starfieldAdditionalRotation.multiply(this.starfieldRotation)); + if (shouldCompensateRotation) { + const starfieldAdditionalRotation = Quaternion.RotationAxis(nearestBody.getRotationAxis(), dthetaNearest); + this.starfieldRotation.copyFrom(starfieldAdditionalRotation.multiply(this.starfieldRotation)); + } for (const object of this.orbitalObjects) { if (object === nearestBody) continue; From ab99d5cc14f5710e89fa150dbfab4a437234651a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:53:29 +0200 Subject: [PATCH 19/86] small tweaks --- src/ts/view/materials/gasPlanetMaterial.ts | 4 ++-- src/ts/view/postProcesses/blackHolePostProcess.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ts/view/materials/gasPlanetMaterial.ts b/src/ts/view/materials/gasPlanetMaterial.ts index 8d0c9d8b0..e6173ee70 100644 --- a/src/ts/view/materials/gasPlanetMaterial.ts +++ b/src/ts/view/materials/gasPlanetMaterial.ts @@ -72,10 +72,10 @@ export class GasPlanetMaterial extends ShaderMaterial { colorSharpness: randRangeInt(40, 80, model.rng, 80) / 10 }; - /*this.onBindObservable.add(() => { + this.onBindObservable.add(() => { const effect = this.getEffect(); MaterialHelper.BindLogDepth(null, effect, scene); - });*/ + }); this.setFloat("seed", model.seed); diff --git a/src/ts/view/postProcesses/blackHolePostProcess.ts b/src/ts/view/postProcesses/blackHolePostProcess.ts index d2e09958d..7acbf8861 100644 --- a/src/ts/view/postProcesses/blackHolePostProcess.ts +++ b/src/ts/view/postProcesses/blackHolePostProcess.ts @@ -37,7 +37,6 @@ export class BlackHolePostProcess extends UberPostProcess implements ObjectPostP get: () => { const rotationMatrix = new Matrix(); starfieldRotation.toRotationMatrix(rotationMatrix); - console.log(starfieldRotation); return rotationMatrix; } }, From c8c9539ed242f258198c64b177d5c6c27cd35e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:53:53 +0200 Subject: [PATCH 20/86] mouse move won't be recorded outside of canvas --- src/ts/controller/inputs/mouse.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ts/controller/inputs/mouse.ts b/src/ts/controller/inputs/mouse.ts index 09b2153f7..4b312b450 100644 --- a/src/ts/controller/inputs/mouse.ts +++ b/src/ts/controller/inputs/mouse.ts @@ -26,7 +26,10 @@ export class Mouse implements Input { this.deadAreaRadius = deadAreaRadius; this.canvas = canvas; - document.addEventListener("pointermove", (e) => { + window.addEventListener("pointermove", (e) => { + const canvasRect = this.canvas.getBoundingClientRect(); + if (e.x < canvasRect.x || e.y < canvasRect.y || e.x > canvasRect.x + canvasRect.width || e.y > canvasRect.y + canvasRect.height) return; + this.dx = e.x - this.x; this.dy = e.y - this.y; From f54cee488816ebc90a9af4beb3e40bfa73f063e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:58:04 +0200 Subject: [PATCH 21/86] Update starfieldPostProcess.ts --- src/ts/view/postProcesses/starfieldPostProcess.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ts/view/postProcesses/starfieldPostProcess.ts b/src/ts/view/postProcesses/starfieldPostProcess.ts index cbbd5274b..c21f178c8 100644 --- a/src/ts/view/postProcesses/starfieldPostProcess.ts +++ b/src/ts/view/postProcesses/starfieldPostProcess.ts @@ -36,7 +36,6 @@ export class StarfieldPostProcess extends UberPostProcess { get: () => { const rotationMatrix = new Matrix(); starfieldRotation.toRotationMatrix(rotationMatrix); - console.log(starfieldRotation); return rotationMatrix; } }, From 762cd8af17340cc28dd1fe5d61ffcc1bcffee490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Wed, 25 Oct 2023 20:00:44 +0200 Subject: [PATCH 22/86] Update gasPlanetMaterial.ts --- src/ts/view/materials/gasPlanetMaterial.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/view/materials/gasPlanetMaterial.ts b/src/ts/view/materials/gasPlanetMaterial.ts index e6173ee70..4b088a75d 100644 --- a/src/ts/view/materials/gasPlanetMaterial.ts +++ b/src/ts/view/materials/gasPlanetMaterial.ts @@ -51,7 +51,7 @@ export class GasPlanetMaterial extends ShaderMaterial { "logarithmicDepthConstant" ], - //defines: ["#define LOGARITHMICDEPTH"] + defines: ["#define LOGARITHMICDEPTH"] }); this.planet = planet; From d4405bdee48305fd04f7de93d9e02f39b5bdc98b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Thu, 26 Oct 2023 18:05:03 +0200 Subject: [PATCH 23/86] fixed gas planet incorrect clouds rotation Local space coordinates were transformed, and it was not needed --- src/shaders/gasPlanetMaterial/vertex.glsl | 4 +--- src/ts/view/materials/gasPlanetMaterial.ts | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/shaders/gasPlanetMaterial/vertex.glsl b/src/shaders/gasPlanetMaterial/vertex.glsl index a631d1e5f..18f13dc5e 100644 --- a/src/shaders/gasPlanetMaterial/vertex.glsl +++ b/src/shaders/gasPlanetMaterial/vertex.glsl @@ -12,8 +12,6 @@ uniform mat4 world; uniform mat4 worldViewProjection; uniform mat4 normalMatrix; -uniform mat4 planetInverseRotationMatrix; - out vec3 vPositionW; out vec3 vNormalW; @@ -36,5 +34,5 @@ void main() { vPosition = position; - vUnitSamplePoint = mat3(planetInverseRotationMatrix) * normalize(vPosition); + vUnitSamplePoint = normalize(vPosition); } \ No newline at end of file diff --git a/src/ts/view/materials/gasPlanetMaterial.ts b/src/ts/view/materials/gasPlanetMaterial.ts index 4b088a75d..80ce08bd6 100644 --- a/src/ts/view/materials/gasPlanetMaterial.ts +++ b/src/ts/view/materials/gasPlanetMaterial.ts @@ -45,8 +45,6 @@ export class GasPlanetMaterial extends ShaderMaterial { "time", - "planetInverseRotationMatrix", - "playerPosition", "logarithmicDepthConstant" @@ -94,7 +92,6 @@ export class GasPlanetMaterial extends ShaderMaterial { this.clock += deltaTime; this.setMatrix("normalMatrix", this.planet.getWorldMatrix().clone().invert().transpose()); - this.setMatrix("planetInverseRotationMatrix", getInverseRotationMatrix(this.planet)); this.setVector3("playerPosition", player.getActiveCamera().getAbsolutePosition()); From d7a688bbffa5c4a11f28824e3827ba942afe6069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Thu, 26 Oct 2023 18:10:07 +0200 Subject: [PATCH 24/86] fixed orbits lagging behind camera movement --- src/ts/controller/spaceEngine.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ts/controller/spaceEngine.ts b/src/ts/controller/spaceEngine.ts index 510deba09..76505a97f 100644 --- a/src/ts/controller/spaceEngine.ts +++ b/src/ts/controller/spaceEngine.ts @@ -257,13 +257,13 @@ export class SpaceEngine { this.bodyEditor.update(nearestBody, starSystem.postProcessManager, starSystemScene); this.helmetOverlay.update(nearestBody); - this.orbitRenderer.update(); - //FIXME: should address stars orbits for (const star of starSystem.stellarObjects) star.model.orbit.period = 0; Assets.ChunkForge.update(); starSystem.update(deltaTime * Settings.TIME_MULTIPLIER); + + this.orbitRenderer.update(); }); window.addEventListener("resize", () => { From 347448edf38d8ed59a50c78e6e16a77d4005c9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 08:40:14 +0200 Subject: [PATCH 25/86] fixed orbit orientations --- .../uberCore/transforms/basicTransform.ts | 9 +++++++++ src/ts/model/orbit/orbit.ts | 18 +++++++++--------- src/ts/view/orbitRenderer.ts | 8 +++++++- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/ts/controller/uberCore/transforms/basicTransform.ts b/src/ts/controller/uberCore/transforms/basicTransform.ts index c452e10f1..fbf47c814 100644 --- a/src/ts/controller/uberCore/transforms/basicTransform.ts +++ b/src/ts/controller/uberCore/transforms/basicTransform.ts @@ -35,6 +35,15 @@ export function setRotationQuaternion(transformNode: TransformNode, newRotation: transformNode.computeWorldMatrix(true); } +export function setUpVector(transformNode: TransformNode, newUp: Vector3): void { + if(newUp.equalsWithEpsilon(transformNode.up, 1e-7)) return; + const currentUp = transformNode.up; + const rotationAxis = Vector3.Cross(newUp, currentUp); + const angle = -Math.acos(Vector3.Dot(newUp, currentUp)); + const rotation = Quaternion.RotationAxis(rotationAxis, angle); + setRotationQuaternion(transformNode, rotation.multiply(transformNode.rotationQuaternion ?? Quaternion.Identity())); +} + export function getRotationMatrix(transformNode: TransformNode): Matrix { const rotationMatrix = new Matrix(); getRotationQuaternion(transformNode).toRotationMatrix(rotationMatrix); diff --git a/src/ts/model/orbit/orbit.ts b/src/ts/model/orbit/orbit.ts index 8159f1193..cbd67b7e6 100644 --- a/src/ts/model/orbit/orbit.ts +++ b/src/ts/model/orbit/orbit.ts @@ -15,14 +15,7 @@ export function getPointOnOrbitLocal(settings: OrbitProperties, t: number): Vect const LpFactor = computeLpFactor(theta, settings.p); - const relativePosition = new Vector3(cosTheta, 0, sinTheta).scaleInPlace(settings.radius * LpFactor); - - // rotate orbital plane - const rotationAxis = Vector3.Cross(Vector3.Up(), settings.normalToPlane).normalize(); - const angle = Vector3.GetAngleBetweenVectors(Vector3.Up(), settings.normalToPlane, rotationAxis); - const rotationMatrix = Matrix.RotationAxis(rotationAxis, angle); - - return Vector3.TransformCoordinates(relativePosition, rotationMatrix); + return new Vector3(cosTheta, 0, sinTheta).scaleInPlace(settings.radius * LpFactor); } /** @@ -33,7 +26,14 @@ export function getPointOnOrbitLocal(settings: OrbitProperties, t: number): Vect * @returns */ export function getPointOnOrbit(centerOfMass: Vector3, settings: OrbitProperties, t: number): Vector3 { - return getPointOnOrbitLocal(settings, t).addInPlace(centerOfMass); + const localPosition = getPointOnOrbitLocal(settings, t); + + // rotate orbital plane + const rotationAxis = Vector3.Cross(Vector3.Up(), settings.normalToPlane).normalize(); + const angle = Vector3.GetAngleBetweenVectors(Vector3.Up(), settings.normalToPlane, rotationAxis); + const rotationMatrix = Matrix.RotationAxis(rotationAxis, angle); + + return Vector3.TransformCoordinates(localPosition, rotationMatrix).addInPlace(centerOfMass); } export function computeLpFactor(theta: number, p: number) { diff --git a/src/ts/view/orbitRenderer.ts b/src/ts/view/orbitRenderer.ts index e68a71602..6e422c628 100644 --- a/src/ts/view/orbitRenderer.ts +++ b/src/ts/view/orbitRenderer.ts @@ -1,8 +1,10 @@ import { LinesMesh, MeshBuilder } from "@babylonjs/core/Meshes"; import { OrbitalObject } from "./common"; import { getPointOnOrbitLocal } from "../model/orbit/orbit"; -import { Color3, Vector3 } from "@babylonjs/core/Maths/math"; +import { Color3, Quaternion, Vector3 } from "@babylonjs/core/Maths/math"; import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Matrix } from "ml-matrix"; +import { setRotationQuaternion, setUpVector } from "../controller/uberCore/transforms/basicTransform"; export class OrbitRenderer { private orbitMeshes: LinesMesh[] = []; @@ -59,6 +61,10 @@ export class OrbitRenderer { const orbitMesh = this.orbitMeshes[i]; orbitMesh.position = orbitalObject.parentObject?.getTransform().position ?? Vector3.Zero(); + orbitMesh.computeWorldMatrix(true); + + const normalToPlane = orbitalObject.model.orbit.normalToPlane; + setUpVector(orbitMesh, normalToPlane); } } From 19499db85f62e057e5ed43efc03012bfdc23b3f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 08:40:26 +0200 Subject: [PATCH 26/86] removed useless uniform in rings --- src/ts/view/postProcesses/ringsPostProcess.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/ts/view/postProcesses/ringsPostProcess.ts b/src/ts/view/postProcesses/ringsPostProcess.ts index 56c55b0a4..68b33effb 100644 --- a/src/ts/view/postProcesses/ringsPostProcess.ts +++ b/src/ts/view/postProcesses/ringsPostProcess.ts @@ -6,7 +6,7 @@ import { getActiveCameraUniforms, getObjectUniforms, getSamplers, getStellarObje import { ObjectPostProcess } from "./objectPostProcess"; import { StellarObject } from "../bodies/stellarObjects/stellarObject"; import { Effect } from "@babylonjs/core/Materials/effect"; -import { UniformEnumType, ShaderUniforms } from "../../controller/uberCore/postProcesses/types"; +import { ShaderUniforms } from "../../controller/uberCore/postProcesses/types"; import { RingsUniforms } from "../../model/ringsUniform"; const shaderName = "rings"; @@ -27,13 +27,6 @@ export class RingsPostProcess extends UberPostProcess implements ObjectPostProce ...getStellarObjectsUniforms(stellarObjects), ...getActiveCameraUniforms(scene), ...ringsUniforms.getShaderUniforms(), - { - name: "planetRotationAxis", - type: UniformEnumType.Vector3, - get: () => { - return body.getRotationAxis(); - } - } ]; super(body.name + "Rings", shaderName, uniforms, getSamplers(scene), scene); From 35f53dd4bb6ec40a9ae5c74529fa465596da2b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 08:41:08 +0200 Subject: [PATCH 27/86] better generalpanel axial tilt --- src/ts/ui/bodyEditor/panels/generalPanel.ts | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/ts/ui/bodyEditor/panels/generalPanel.ts b/src/ts/ui/bodyEditor/panels/generalPanel.ts index c05f0f5d2..02a8a0dbc 100644 --- a/src/ts/ui/bodyEditor/panels/generalPanel.ts +++ b/src/ts/ui/bodyEditor/panels/generalPanel.ts @@ -1,12 +1,12 @@ import { EditorPanel } from "../editorPanel"; import { stripAxisFromQuaternion } from "../../../utils/algebra"; -import { Axis } from "@babylonjs/core/Maths/math.axis"; +import { Axis, Space } from "@babylonjs/core/Maths/math.axis"; import { Slider } from "handle-sliderjs"; import { Settings } from "../../../settings"; import { UberScene } from "../../../controller/uberCore/uberScene"; import { isOrbiting } from "../../../utils/nearestBody"; import { ColorCorrection } from "../../../controller/uberCore/postProcesses/colorCorrection"; -import { getRotationQuaternion } from "../../../controller/uberCore/transforms/basicTransform"; +import { getRotationQuaternion, rotate } from "../../../controller/uberCore/transforms/basicTransform"; import { BoundingSphere, Transformable } from "../../../view/common"; export class GeneralPanel extends EditorPanel { @@ -22,27 +22,17 @@ export class GeneralPanel extends EditorPanel { let axialTiltX = stripAxisFromQuaternion(getRotationQuaternion(body.getTransform()), Axis.Y).toEulerAngles().x; let axialTiltZ = stripAxisFromQuaternion(getRotationQuaternion(body.getTransform()), Axis.Y).toEulerAngles().z; //TODO: do not hardcode here - const power = 1.4; + const power = 3; this.sliders = [ new Slider("axialTiltX", document.getElementById("axialTiltX") as HTMLElement, -180, 180, Math.round((180 * axialTiltX) / Math.PI), (val: number) => { const newAxialTilt = (val * Math.PI) / 180; - body.getTransform().rotate(Axis.X, newAxialTilt - axialTiltX); - if (isOrbiting(scene.getActiveController(), body)) - scene - .getActiveController() - .getTransform() - .rotateAround(body.getTransform().getAbsolutePosition(), Axis.X, newAxialTilt - axialTiltX); + rotate(body.getTransform(), Axis.X, newAxialTilt - axialTiltX); axialTiltX = newAxialTilt; }), new Slider("axialTiltZ", document.getElementById("axialTiltZ") as HTMLElement, -180, 180, Math.round((180 * axialTiltZ) / Math.PI), (val: number) => { const newAxialTilt = (val * Math.PI) / 180; - body.getTransform().rotate(Axis.Z, newAxialTilt - axialTiltZ); - if (isOrbiting(scene.getActiveController(), body)) - scene - .getActiveController() - .getTransform() - .rotateAround(body.getTransform().getAbsolutePosition(), Axis.Z, newAxialTilt - axialTiltZ); + rotate(body.getTransform(), Axis.Z, newAxialTilt - axialTiltZ); axialTiltZ = newAxialTilt; }), new Slider( From 6059a20570273ba9aaf29d340f3b460146299535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 08:41:21 +0200 Subject: [PATCH 28/86] linting --- src/ts/view/bodies/planemos/gasPlanet.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ts/view/bodies/planemos/gasPlanet.ts b/src/ts/view/bodies/planemos/gasPlanet.ts index e52f65447..40b535b0e 100644 --- a/src/ts/view/bodies/planemos/gasPlanet.ts +++ b/src/ts/view/bodies/planemos/gasPlanet.ts @@ -9,7 +9,6 @@ import { MeshBuilder } from "@babylonjs/core/Meshes/meshBuilder"; import { Axis } from "@babylonjs/core/Maths/math.axis"; import { Mesh } from "@babylonjs/core/Meshes/mesh"; import { PostProcessType } from "../../postProcesses/postProcessTypes"; -import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { isSizeOnScreenEnough } from "../../../utils/isObjectVisibleOnScreen"; import { Camera } from "@babylonjs/core/Cameras/camera"; From c716ac3a4384e1d76499ddecc50733624c06a87d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 09:04:09 +0200 Subject: [PATCH 29/86] better handling of rotation axis when compensating rotation --- src/ts/controller/starSystem.ts | 38 +++++++++++++++++-- src/ts/model/planemos/gasPlanetModel.ts | 6 +-- src/ts/model/planemos/telluricPlanemoModel.ts | 6 +-- src/ts/view/bodies/abstractObject.ts | 37 +++++++++--------- 4 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index 1bebca0be..6e043a0cc 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -20,7 +20,7 @@ import { TelluricPlanemoModel } from "../model/planemos/telluricPlanemoModel"; import { GasPlanetModel } from "../model/planemos/gasPlanetModel"; import { BlackHoleModel } from "../model/stellarObjects/blackHoleModel"; import { StarModel } from "../model/stellarObjects/starModel"; -import { rotateAround, translate } from "./uberCore/transforms/basicTransform"; +import { rotateAround, setUpVector, translate } from "./uberCore/transforms/basicTransform"; import { MandelbulbModel } from "../model/planemos/mandelbulbModel"; import { Mandelbulb } from "../view/bodies/planemos/mandelbulb"; import { getMoonSeed } from "../model/planemos/common"; @@ -360,6 +360,15 @@ export class StarSystem { */ public init(nbWarmUpUpdates = 100): void { this.initPostProcesses(); + + for (const object of this.orbitalObjects) { + const displacement = new Vector3(object.model.orbit.radius, 0, 0); + if (object.parentObject !== null) { + translate(object.getTransform(), object.parentObject.getTransform().getAbsolutePosition()); + } + translate(object.getTransform(), displacement); + } + this.update(Date.now() / 1000); for (let i = 0; i < nbWarmUpUpdates; i++) this.update(1); } @@ -439,14 +448,35 @@ export class StarSystem { const nearestBodyDisplacement = newPosition.subtract(initialPosition); translate(nearestBody.getTransform(), nearestBodyDisplacement.negate()); - const dthetaNearest = nearestBody.updateRotation(deltaTime); - if (shouldCompensateRotation) nearestBody.updateRotation(-deltaTime); + const dthetaNearest = nearestBody.getDeltaTheta(deltaTime); + + // if we don't compensate the rotation of the nearest body, we must rotate it accordingly + if (!shouldCompensateRotation) nearestBody.updateRotation(deltaTime); // As the nearest object is kept in place, we need to transfer its movement to other bodies for (const object of this.orbitalObjects) { + const oldNormal = object.model.orbit.normalToPlane.clone(); + if (shouldCompensateRotation) { + // the normal to the orbit planes must be rotated as well (even the one of the nearest body) + const rotation = Quaternion.RotationAxis(nearestBody.getRotationAxis(), -dthetaNearest); + object.model.orbit.normalToPlane.applyRotationQuaternionInPlace(rotation); + } if (object === nearestBody) continue; translate(object.getTransform(), nearestBodyDisplacement.negate()); - if (shouldCompensateRotation) rotateAround(object.getTransform(), nearestBody.getTransform().getAbsolutePosition(), nearestBody.getRotationAxis(), -dthetaNearest); + if (shouldCompensateRotation) { + // if the nearest body does not rotate, all other bodies must revolve around it for consistency + rotateAround(object.getTransform(), nearestBody.getTransform().getAbsolutePosition(), nearestBody.getRotationAxis(), -dthetaNearest); + + // we must as well rotate their rotation axis to keep consistency + const newNormal = object.model.orbit.normalToPlane.clone(); + const angle = Math.acos(Vector3.Dot(oldNormal, newNormal)); + if(angle > 0.02) { + const axis = Vector3.Cross(oldNormal, newNormal); + const quaternion = Quaternion.RotationAxis(axis, angle); + const newRotationAxis = object.getRotationAxis().applyRotationQuaternion(quaternion); + setUpVector(object.getTransform(), newRotationAxis); + } + } } if (shouldCompensateRotation) { diff --git a/src/ts/model/planemos/gasPlanetModel.ts b/src/ts/model/planemos/gasPlanetModel.ts index f33f866e7..3126961e6 100644 --- a/src/ts/model/planemos/gasPlanetModel.ts +++ b/src/ts/model/planemos/gasPlanetModel.ts @@ -44,16 +44,16 @@ export class GasPlanetModel implements PlanemoModel { this.orbit = { radius: orbitRadius, - p: orbitalP, + p: 2, //orbitalP, period: getOrbitalPeriod(orbitRadius, this.parentBody?.physicalProperties.mass ?? 0), normalToPlane: Vector3.Up(), isPlaneAlignedWithParent: true }; this.physicalProperties = { - // FIXME: choose physically accurates values + // FIXME: choose physically accurate values mass: 10, - axialTilt: normalRandom(0, 0.4, this.rng, GENERATION_STEPS.AXIAL_TILT), + axialTilt: normalRandom(0, 0.4, this.rng, GENERATION_STEPS.AXIAL_TILT), rotationPeriod: (24 * 60 * 60) / 10, minTemperature: -180, maxTemperature: 200, diff --git a/src/ts/model/planemos/telluricPlanemoModel.ts b/src/ts/model/planemos/telluricPlanemoModel.ts index dafbfd7d0..32432b2ea 100644 --- a/src/ts/model/planemos/telluricPlanemoModel.ts +++ b/src/ts/model/planemos/telluricPlanemoModel.ts @@ -62,15 +62,15 @@ export class TelluricPlanemoModel implements PlanemoModel { oceanLevel: 0 }; - const isOrbitalPlaneAlignedWithParent = this.isSatelliteOfGas && uniformRandBool(0.05, this.rng, GENERATION_STEPS.ORBITAL_PLANE_ALIGNEMENT); + const isOrbitalPlaneAlignedWithParent = true; //this.isSatelliteOfGas && uniformRandBool(0.05, this.rng, GENERATION_STEPS.ORBITAL_PLANE_ALIGNEMENT); const orbitalPlaneNormal = isOrbitalPlaneAlignedWithParent ? Vector3.Up() - : new Vector3(this.rng(GENERATION_STEPS.ORBIT + 20), this.rng(GENERATION_STEPS.ORBIT + 30), this.rng(GENERATION_STEPS.ORBIT + 40)).normalize(); + : new Vector3(this.rng(GENERATION_STEPS.ORBIT + 20), this.rng(GENERATION_STEPS.ORBIT + 30), this.rng(GENERATION_STEPS.ORBIT + 40)).normalize().scaleInPlace(0.1); // TODO: do not hardcode let orbitRadius = this.rng(GENERATION_STEPS.ORBIT) * 15e9; - const orbitalP = clamp(normalRandom(2.0, 0.3, this.rng, GENERATION_STEPS.ORBIT + 80), 0.7, 3.0); + const orbitalP = 2; //clamp(normalRandom(2.0, 0.3, this.rng, GENERATION_STEPS.ORBIT + 80), 0.7, 3.0); if (this.isSatelliteOfGas || this.isSatelliteOfTelluric) { const minRadius = this.parentBody?.radius ?? 0; diff --git a/src/ts/view/bodies/abstractObject.ts b/src/ts/view/bodies/abstractObject.ts index 4756a66cc..1a6688dfe 100644 --- a/src/ts/view/bodies/abstractObject.ts +++ b/src/ts/view/bodies/abstractObject.ts @@ -5,13 +5,11 @@ import { Scene } from "@babylonjs/core/scene"; import { getPointOnOrbit } from "../../model/orbit/orbit"; import { PostProcessType } from "../postProcesses/postProcessTypes"; import { Cullable } from "./cullable"; -import { TransformNode } from "@babylonjs/core/Meshes"; -import { - getRotationQuaternion, - setRotationQuaternion, - translate -} from "../../controller/uberCore/transforms/basicTransform"; +import { LinesMesh, TransformNode } from "@babylonjs/core/Meshes"; +import { getRotationQuaternion, rotateAround, setRotationQuaternion, translate } from "../../controller/uberCore/transforms/basicTransform"; import { Camera } from "@babylonjs/core/Cameras/camera"; +import { MeshBuilder } from "@babylonjs/core/Meshes/meshBuilder"; +import { Settings } from "../../settings"; export abstract class AbstractObject implements OrbitalObject, BaseObject, Cullable { private readonly transform: TransformNode; @@ -74,34 +72,33 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla if (this.model.orbit.period > 0 && this.parentObject !== null) { this.parentObject.getTransform().computeWorldMatrix(true); const barycenter = this.parentObject.getTransform().getAbsolutePosition(); - /*const orbitalPlaneNormal = this.parentObject?.transform.up ?? Vector3.Up(); -if (this.model.orbit.isPlaneAlignedWithParent) this.model.orbit.normalToPlane = orbitalPlaneNormal;*/ - const newPosition = getPointOnOrbit(barycenter, this.model.orbit, this.internalClock); - const oldPosition = getPointOnOrbit(barycenter, this.model.orbit, this.internalClock - deltaTime); - const translation = newPosition.subtract(oldPosition); - translate(this.transform, translation); + const dtheta = (2 * Math.PI * deltaTime) / this.model.orbit.period; + rotateAround(this.transform, barycenter, this.model.orbit.normalToPlane, dtheta); + const oldPosition = this.transform.getAbsolutePosition().subtract(barycenter); + const newPosition = oldPosition.normalizeToNew().scaleInPlace(this.model.orbit.radius); + translate(this.transform, newPosition.subtract(oldPosition)); } } + public getDeltaTheta(deltaTime: number) { + if (this.model.physicalProperties.rotationPeriod === 0) return 0; + return (2 * Math.PI * deltaTime) / this.model.physicalProperties.rotationPeriod; + } + /** * Updates the rotation of the body around its axis * @param deltaTime The time elapsed since the last update * @returns The elapsed angle of rotation around the axis */ - public updateRotation(deltaTime: number): number { - if (this.model.physicalProperties.rotationPeriod === 0) { - return 0; - } - - const dtheta = (2 * Math.PI * deltaTime) / this.model.physicalProperties.rotationPeriod; + public updateRotation(deltaTime: number) { + const dtheta = this.getDeltaTheta(deltaTime); + if (dtheta === 0) return; const elementaryRotationQuaternion = Quaternion.RotationAxis(this.getRotationAxis(), dtheta); const newQuaternion = elementaryRotationQuaternion.multiply(getRotationQuaternion(this.transform)); setRotationQuaternion(this.transform, newQuaternion); - - return dtheta; } public abstract computeCulling(camera: Camera): void; From 28ce9c09a81bea8e054b5f8dfa6e3930566153f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 09:17:06 +0200 Subject: [PATCH 30/86] added rotation axis renderer For debug purposes or it can be useful --- src/ts/controller/spaceEngine.ts | 8 ++++- src/ts/view/axisRenderer.ts | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/ts/view/axisRenderer.ts diff --git a/src/ts/controller/spaceEngine.ts b/src/ts/controller/spaceEngine.ts index 76505a97f..3ca79383a 100644 --- a/src/ts/controller/spaceEngine.ts +++ b/src/ts/controller/spaceEngine.ts @@ -31,6 +31,7 @@ import { Observable } from "@babylonjs/core/Misc/observable"; import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; import { OrbitRenderer } from "../view/orbitRenderer"; import { PauseMenu } from "../ui/pauseMenu"; +import { AxisRenderer } from "../view/axisRenderer"; enum EngineState { RUNNING, @@ -51,6 +52,7 @@ export class SpaceEngine { private starSystemScene: UberScene | null = null; private readonly orbitRenderer: OrbitRenderer = new OrbitRenderer(); + private readonly axisRenderer: AxisRenderer = new AxisRenderer(); private havokPlugin: HavokPlugin | null = null; @@ -104,7 +106,10 @@ export class SpaceEngine { //TODO: use the keyboard class document.addEventListener("keydown", (e) => { if (e.key === "o") OverlayPostProcess.ARE_ENABLED = !OverlayPostProcess.ARE_ENABLED; - if (e.key === "n") this.orbitRenderer.setVisibility(!this.orbitRenderer.isVisible()); + if (e.key === "n") { + this.orbitRenderer.setVisibility(!this.orbitRenderer.isVisible()); + this.axisRenderer.setVisibility(!this.axisRenderer.isVisible()); + } if (e.key === "p") this.takeScreenshot(); if (e.key === "v") { if (!VideoRecorder.IsSupported(this.getEngine())) console.warn("Your browser does not support video recording!"); @@ -215,6 +220,7 @@ export class SpaceEngine { if (firstBody === undefined) throw new Error("No bodies in star system"); this.orbitRenderer.setOrbitalObjects(this.getStarSystem().getBodies()); + this.axisRenderer.setObjects(this.getStarSystem().getBodies()); const activeController = this.getStarSystemScene().getActiveController(); positionNearObject(activeController, firstBody, this.getStarSystem(), firstBody instanceof BlackHole ? 7 : 5); diff --git a/src/ts/view/axisRenderer.ts b/src/ts/view/axisRenderer.ts new file mode 100644 index 000000000..a3f7c17e9 --- /dev/null +++ b/src/ts/view/axisRenderer.ts @@ -0,0 +1,57 @@ +import { LinesMesh, MeshBuilder } from "@babylonjs/core/Meshes"; +import { BoundingSphere, Transformable } from "./common"; +import { Color3, Vector3 } from "@babylonjs/core/Maths/math"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; + +export class AxisRenderer { + private axisMeshes: LinesMesh[] = []; + + private axisMaterial: StandardMaterial | null = null; + + private isVisibile = false; + + setObjects(objects: (Transformable & BoundingSphere)[]) { + this.reset(); + + for (const object of objects) { + this.createAxisMesh(object); + } + + this.setVisibility(this.isVisibile); + } + + private createAxisMesh(orbitalObject: Transformable & BoundingSphere) { + const rotationAxisHelper = MeshBuilder.CreateLines( + `RotationAxisHelper`, + { + points: [new Vector3(0, -orbitalObject.getBoundingRadius() * 2, 0), new Vector3(0, orbitalObject.getBoundingRadius() * 2, 0)] + }, + orbitalObject.getTransform().getScene() + ); + rotationAxisHelper.parent = orbitalObject.getTransform(); + if (this.axisMaterial === null) throw new Error("Orbit material is null"); + rotationAxisHelper.material = this.axisMaterial; + this.axisMeshes.push(rotationAxisHelper); + } + + setVisibility(visible: boolean) { + this.isVisibile = visible; + for (const axisMesh of this.axisMeshes) { + axisMesh.visibility = visible ? 1 : 0; + } + } + + isVisible(): boolean { + return this.isVisibile; + } + + private reset() { + this.axisMeshes.forEach((orbitMesh) => orbitMesh.dispose()); + this.axisMeshes = []; + + this.axisMaterial = new StandardMaterial("axisMaterial"); + this.axisMaterial.emissiveColor = Color3.White(); + this.axisMaterial.disableLighting = true; + this.axisMaterial.useLogarithmicDepth = true; + } +} From b83706b1485794d77541ee102eaa74e1b8248e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 09:18:48 +0200 Subject: [PATCH 31/86] Update abstractObject.ts --- src/ts/view/bodies/abstractObject.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/ts/view/bodies/abstractObject.ts b/src/ts/view/bodies/abstractObject.ts index 1a6688dfe..6b07a1ab5 100644 --- a/src/ts/view/bodies/abstractObject.ts +++ b/src/ts/view/bodies/abstractObject.ts @@ -1,15 +1,12 @@ -import { Vector3, Quaternion, Matrix } from "@babylonjs/core/Maths/math"; +import { Vector3, Quaternion } from "@babylonjs/core/Maths/math"; import { BaseObject, OrbitalObject } from "../common"; import { BaseModel } from "../../model/common"; import { Scene } from "@babylonjs/core/scene"; -import { getPointOnOrbit } from "../../model/orbit/orbit"; import { PostProcessType } from "../postProcesses/postProcessTypes"; import { Cullable } from "./cullable"; -import { LinesMesh, TransformNode } from "@babylonjs/core/Meshes"; +import { TransformNode } from "@babylonjs/core/Meshes"; import { getRotationQuaternion, rotateAround, setRotationQuaternion, translate } from "../../controller/uberCore/transforms/basicTransform"; import { Camera } from "@babylonjs/core/Cameras/camera"; -import { MeshBuilder } from "@babylonjs/core/Meshes/meshBuilder"; -import { Settings } from "../../settings"; export abstract class AbstractObject implements OrbitalObject, BaseObject, Cullable { private readonly transform: TransformNode; From bc4c48ce274dd5c048be6fea0521555dc820dc6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 09:36:08 +0200 Subject: [PATCH 32/86] 1:1 earth scale planets --- src/ts/model/planemos/telluricPlanemoModel.ts | 2 +- src/ts/settings.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ts/model/planemos/telluricPlanemoModel.ts b/src/ts/model/planemos/telluricPlanemoModel.ts index 32432b2ea..87429307b 100644 --- a/src/ts/model/planemos/telluricPlanemoModel.ts +++ b/src/ts/model/planemos/telluricPlanemoModel.ts @@ -104,7 +104,7 @@ export class TelluricPlanemoModel implements PlanemoModel { max_mountain_height: 10e3, continent_base_height: this.physicalProperties.oceanLevel * 1.9, - mountains_frequency: (20 * this.radius) / Settings.EARTH_RADIUS + mountains_frequency: (6 * (20 * this.radius)) / Settings.EARTH_RADIUS }; if (this.isSatelliteOfTelluric) { diff --git a/src/ts/settings.ts b/src/ts/settings.ts index 0b0a22306..041b9a82d 100644 --- a/src/ts/settings.ts +++ b/src/ts/settings.ts @@ -1,6 +1,6 @@ export const Settings = { UNIVERSE_SEED: Math.PI, - EARTH_RADIUS: 1000e3, // target is 6000e3 + EARTH_RADIUS: 6000e3, // target is 6000e3 AU: 150e9, // target is 150e9 VERTEX_RESOLUTION: 64, CLOUD_LAYER_HEIGHT: 15e3, From 9a6d0916c28eed380a4104f2a9e1f4f9445b5903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 10:04:35 +0200 Subject: [PATCH 33/86] fixed orbital inclination --- src/ts/controller/starSystem.ts | 5 +++++ src/ts/model/planemos/telluricPlanemoModel.ts | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index 6e043a0cc..461f6d184 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -363,6 +363,11 @@ export class StarSystem { for (const object of this.orbitalObjects) { const displacement = new Vector3(object.model.orbit.radius, 0, 0); + const targetNormal = object.model.orbit.normalToPlane; + const rotationAxis = Vector3.Cross(Vector3.Up(), targetNormal); + const angle = Math.acos(Vector3.Dot(Vector3.Up(), targetNormal)); + const quaternion = Quaternion.RotationAxis(rotationAxis, angle); + displacement.applyRotationQuaternionInPlace(quaternion); if (object.parentObject !== null) { translate(object.getTransform(), object.parentObject.getTransform().getAbsolutePosition()); } diff --git a/src/ts/model/planemos/telluricPlanemoModel.ts b/src/ts/model/planemos/telluricPlanemoModel.ts index 87429307b..483444c90 100644 --- a/src/ts/model/planemos/telluricPlanemoModel.ts +++ b/src/ts/model/planemos/telluricPlanemoModel.ts @@ -8,6 +8,8 @@ import { getOrbitalPeriod, getPeriapsis } from "../orbit/orbit"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { OrbitProperties } from "../orbit/orbitProperties"; import { RingsUniforms } from "../ringsUniform"; +import { Axis } from "@babylonjs/core/Maths/math.axis"; +import { Quaternion } from "@babylonjs/core/Maths/math"; export class TelluricPlanemoModel implements PlanemoModel { readonly bodyType = BODY_TYPE.TELLURIC; @@ -62,13 +64,13 @@ export class TelluricPlanemoModel implements PlanemoModel { oceanLevel: 0 }; - const isOrbitalPlaneAlignedWithParent = true; //this.isSatelliteOfGas && uniformRandBool(0.05, this.rng, GENERATION_STEPS.ORBITAL_PLANE_ALIGNEMENT); + const isOrbitalPlaneAlignedWithParent = this.isSatelliteOfGas && uniformRandBool(0.05, this.rng, GENERATION_STEPS.ORBITAL_PLANE_ALIGNEMENT); const orbitalPlaneNormal = isOrbitalPlaneAlignedWithParent ? Vector3.Up() - : new Vector3(this.rng(GENERATION_STEPS.ORBIT + 20), this.rng(GENERATION_STEPS.ORBIT + 30), this.rng(GENERATION_STEPS.ORBIT + 40)).normalize().scaleInPlace(0.1); + : Vector3.Up().applyRotationQuaternionInPlace(Quaternion.RotationAxis(Axis.X, (this.rng(GENERATION_STEPS.ORBIT + 20) - 0.5) * 0.2)); // TODO: do not hardcode - let orbitRadius = this.rng(GENERATION_STEPS.ORBIT) * 15e9; + let orbitRadius = 2e9 + this.rng(GENERATION_STEPS.ORBIT) * 15e9; const orbitalP = 2; //clamp(normalRandom(2.0, 0.3, this.rng, GENERATION_STEPS.ORBIT + 80), 0.7, 3.0); From 667d054b16d2e8a2aa2515d4654677e173dcb123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 10:09:30 +0200 Subject: [PATCH 34/86] gas planet have tilted orbits --- src/ts/model/planemos/gasPlanetModel.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ts/model/planemos/gasPlanetModel.ts b/src/ts/model/planemos/gasPlanetModel.ts index 3126961e6..e5b7d3aa2 100644 --- a/src/ts/model/planemos/gasPlanetModel.ts +++ b/src/ts/model/planemos/gasPlanetModel.ts @@ -7,6 +7,8 @@ import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { clamp } from "../../utils/math"; import { OrbitProperties } from "../orbit/orbitProperties"; import { RingsUniforms } from "../ringsUniform"; +import { Quaternion } from "@babylonjs/core/Maths/math"; +import { Axis } from "@babylonjs/core/Maths/math.axis"; export class GasPlanetModel implements PlanemoModel { readonly bodyType = BODY_TYPE.GAS; @@ -42,11 +44,13 @@ export class GasPlanetModel implements PlanemoModel { const orbitalP = clamp(0.7, 3.0, normalRandom(2.0, 0.3, this.rng, GENERATION_STEPS.ORBIT + 80)); orbitRadius += orbitRadius - getPeriapsis(orbitRadius, orbitalP); + const orbitalPlaneNormal = Vector3.Up().applyRotationQuaternionInPlace(Quaternion.RotationAxis(Axis.X, (this.rng(GENERATION_STEPS.ORBIT + 20) - 0.5) * 0.2)); + this.orbit = { radius: orbitRadius, p: 2, //orbitalP, period: getOrbitalPeriod(orbitRadius, this.parentBody?.physicalProperties.mass ?? 0), - normalToPlane: Vector3.Up(), + normalToPlane: orbitalPlaneNormal, isPlaneAlignedWithParent: true }; From 1ab1f0e0d22bbd859f15fc020599dac8ec69d486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 10:28:56 +0200 Subject: [PATCH 35/86] removed shadows on stars --- src/shaders/atmosphericScatteringFragment.glsl | 1 + src/shaders/flatCloudsFragment.glsl | 1 + src/shaders/mandelbulb.glsl | 1 + src/shaders/oceanFragment.glsl | 1 + src/shaders/ringsFragment.glsl | 1 + src/shaders/shadowFragment.glsl | 5 +++++ src/shaders/sierpinski.glsl | 1 + src/shaders/volumetricCloudsFragment.glsl | 1 + .../atmosphericScatteringPostProcess.ts | 3 ++- src/ts/view/postProcesses/oceanPostProcess.ts | 3 ++- src/ts/view/postProcesses/uniforms.ts | 18 +++++++++--------- 11 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/shaders/atmosphericScatteringFragment.glsl b/src/shaders/atmosphericScatteringFragment.glsl index 5b4fc35ab..3be626de9 100644 --- a/src/shaders/atmosphericScatteringFragment.glsl +++ b/src/shaders/atmosphericScatteringFragment.glsl @@ -16,6 +16,7 @@ uniform sampler2D atmosphereLUT; uniform int nbStars;// number of stars struct Star { vec3 position; + float radius; }; uniform Star stars[MAX_STARS]; diff --git a/src/shaders/flatCloudsFragment.glsl b/src/shaders/flatCloudsFragment.glsl index 4a701b251..74eef7906 100644 --- a/src/shaders/flatCloudsFragment.glsl +++ b/src/shaders/flatCloudsFragment.glsl @@ -10,6 +10,7 @@ uniform sampler2D depthSampler;// the depth map of the camera uniform int nbStars;// number of stars struct Star { vec3 position; + float radius; }; uniform Star stars[MAX_STARS]; diff --git a/src/shaders/mandelbulb.glsl b/src/shaders/mandelbulb.glsl index 8eb30525d..2ca3f30f5 100644 --- a/src/shaders/mandelbulb.glsl +++ b/src/shaders/mandelbulb.glsl @@ -13,6 +13,7 @@ uniform vec3 accentColor; uniform int nbStars;// number of stars struct Star { vec3 position; + float radius; }; uniform Star stars[MAX_STARS]; diff --git a/src/shaders/oceanFragment.glsl b/src/shaders/oceanFragment.glsl index ef7b674d1..e0353e973 100644 --- a/src/shaders/oceanFragment.glsl +++ b/src/shaders/oceanFragment.glsl @@ -13,6 +13,7 @@ uniform sampler2D normalMap2; uniform int nbStars;// number of stars struct Star { vec3 position; + float radius; }; uniform Star stars[MAX_STARS]; diff --git a/src/shaders/ringsFragment.glsl b/src/shaders/ringsFragment.glsl index 4e95d6e57..246832747 100644 --- a/src/shaders/ringsFragment.glsl +++ b/src/shaders/ringsFragment.glsl @@ -9,6 +9,7 @@ uniform sampler2D depthSampler;// the depth map of the camera uniform int nbStars;// number of stars struct Star { vec3 position; + float radius; }; uniform Star stars[MAX_STARS]; diff --git a/src/shaders/shadowFragment.glsl b/src/shaders/shadowFragment.glsl index 189de4c7f..84066aa73 100644 --- a/src/shaders/shadowFragment.glsl +++ b/src/shaders/shadowFragment.glsl @@ -9,6 +9,7 @@ uniform sampler2D depthSampler;// the depth map of the camera uniform int nbStars;// number of stars struct Star { vec3 position; + float radius; }; uniform Star stars[MAX_STARS]; @@ -36,6 +37,10 @@ uniform ShadowUniforms shadowUniforms; #pragma glslify: ringDensityAtPoint = require(./rings/ringsDensity.glsl, object=object, rings=rings) float sphereOccultation(vec3 rayDir, float maximumDistance) { + if(length(camera.position + rayDir * maximumDistance - stars[0].position) <= stars[0].radius + 1.0) { + // The point is on the surface of the star + return 1.0; + } vec3 towardLight = normalize(stars[0].position - (camera.position + rayDir * maximumDistance)); float t0, t1; if (lineIntersectSphere(camera.position + rayDir * maximumDistance, towardLight, object.position, object.radius, t0, t1)) { diff --git a/src/shaders/sierpinski.glsl b/src/shaders/sierpinski.glsl index ace1611f2..21c59244d 100644 --- a/src/shaders/sierpinski.glsl +++ b/src/shaders/sierpinski.glsl @@ -14,6 +14,7 @@ uniform vec3 accentColor; uniform int nbStars;// number of stars struct Star { vec3 position; + float radius; }; uniform Star stars[MAX_STARS]; diff --git a/src/shaders/volumetricCloudsFragment.glsl b/src/shaders/volumetricCloudsFragment.glsl index fae04ec0d..74bb8a19e 100644 --- a/src/shaders/volumetricCloudsFragment.glsl +++ b/src/shaders/volumetricCloudsFragment.glsl @@ -14,6 +14,7 @@ uniform sampler2D depthSampler;// the depth map of the camera uniform int nbStars;// number of stars struct Star { vec3 position; + float radius; }; uniform Star stars[MAX_STARS]; diff --git a/src/ts/view/postProcesses/atmosphericScatteringPostProcess.ts b/src/ts/view/postProcesses/atmosphericScatteringPostProcess.ts index 7eb49c0cc..9d7c35a34 100644 --- a/src/ts/view/postProcesses/atmosphericScatteringPostProcess.ts +++ b/src/ts/view/postProcesses/atmosphericScatteringPostProcess.ts @@ -11,6 +11,7 @@ import { GasPlanet } from "../bodies/planemos/gasPlanet"; import { ObjectPostProcess } from "./objectPostProcess"; import { OrbitalObject } from "../common"; import { UniformEnumType, ShaderSamplers, ShaderUniforms, SamplerEnumType } from "../../controller/uberCore/postProcesses/types"; +import { StellarObject } from "../bodies/stellarObjects/stellarObject"; const shaderName = "atmosphericScattering"; Effect.ShadersStore[`${shaderName}FragmentShader`] = atmosphericScatteringFragment; @@ -32,7 +33,7 @@ export class AtmosphericScatteringPostProcess extends UberPostProcess implements readonly atmosphereUniforms: AtmosphereUniforms; readonly object: TelluricPlanemo | GasPlanet; - constructor(name: string, planet: TelluricPlanemo | GasPlanet, atmosphereHeight: number, scene: UberScene, stellarObjects: OrbitalObject[]) { + constructor(name: string, planet: TelluricPlanemo | GasPlanet, atmosphereHeight: number, scene: UberScene, stellarObjects: StellarObject[]) { const atmosphereUniforms: AtmosphereUniforms = { atmosphereRadius: planet.getBoundingRadius() + atmosphereHeight, falloffFactor: 10, diff --git a/src/ts/view/postProcesses/oceanPostProcess.ts b/src/ts/view/postProcesses/oceanPostProcess.ts index e02a5e52e..922df263f 100644 --- a/src/ts/view/postProcesses/oceanPostProcess.ts +++ b/src/ts/view/postProcesses/oceanPostProcess.ts @@ -10,6 +10,7 @@ import { ObjectPostProcess } from "./objectPostProcess"; import { OrbitalObject } from "../common"; import { getInverseRotationQuaternion } from "../../controller/uberCore/transforms/basicTransform"; import { UniformEnumType, ShaderSamplers, ShaderUniforms, SamplerEnumType } from "../../controller/uberCore/postProcesses/types"; +import { StellarObject } from "../bodies/stellarObjects/stellarObject"; const shaderName = "ocean"; Effect.ShadersStore[`${shaderName}FragmentShader`] = oceanFragment; @@ -27,7 +28,7 @@ export class OceanPostProcess extends UberPostProcess implements ObjectPostProce readonly oceanUniforms: OceanUniforms; readonly object: TelluricPlanemo; - constructor(name: string, planet: TelluricPlanemo, scene: UberScene, stars: OrbitalObject[]) { + constructor(name: string, planet: TelluricPlanemo, scene: UberScene, stars: StellarObject[]) { const oceanUniforms: OceanUniforms = { oceanRadius: planet.getBoundingRadius(), depthModifier: 0.001, diff --git a/src/ts/view/postProcesses/uniforms.ts b/src/ts/view/postProcesses/uniforms.ts index 55a1434e1..8623f5443 100644 --- a/src/ts/view/postProcesses/uniforms.ts +++ b/src/ts/view/postProcesses/uniforms.ts @@ -1,6 +1,7 @@ import { UberScene } from "../../controller/uberCore/uberScene"; import { BaseObject, OrbitalObject } from "../common"; import { UniformEnumType, ShaderSamplers, ShaderUniforms, SamplerEnumType } from "../../controller/uberCore/postProcesses/types"; +import { StellarObject } from "../bodies/stellarObjects/stellarObject"; export function getActiveCameraUniforms(scene: UberScene): ShaderUniforms { return [ @@ -42,20 +43,19 @@ export function getActiveCameraUniforms(scene: UberScene): ShaderUniforms { ]; } -export function getStellarObjectsUniforms(stars: OrbitalObject[]): ShaderUniforms { +export function getStellarObjectsUniforms(stars: StellarObject[]): ShaderUniforms { return [ - ...stars.map((star, index) => { - return { + ...stars.flatMap((star, index) => { + return [{ name: `stars[${index}].position`, type: UniformEnumType.Vector3, get: () => star.getTransform().getAbsolutePosition() - }; + }, { + name: `stars[${index}].radius`, + type: UniformEnumType.Float, + get: () => star.getRadius() + }]; }), - { - name: "starPositions", - type: UniformEnumType.Vector3Array, - get: () => stars.map((star) => star.getTransform().getAbsolutePosition()) - }, { name: "nbStars", type: UniformEnumType.Int, From 18bf5d0ecf003d5ceb27cae696fa33f99db56938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 10:36:31 +0200 Subject: [PATCH 36/86] reused star struct in shaders --- .../atmosphericScatteringFragment.glsl | 7 +---- src/shaders/flatCloudsFragment.glsl | 7 +---- src/shaders/mandelbulb.glsl | 7 +---- src/shaders/oceanFragment.glsl | 7 +---- src/shaders/ringsFragment.glsl | 7 +---- src/shaders/shadowFragment.glsl | 8 ++---- src/shaders/sierpinski.glsl | 7 +---- src/shaders/utils/stars.glsl | 9 ++++++ src/shaders/volumetricCloudsFragment.glsl | 7 +---- src/ts/view/postProcesses/uniforms.ts | 28 +++++++++++++------ 10 files changed, 37 insertions(+), 57 deletions(-) create mode 100644 src/shaders/utils/stars.glsl diff --git a/src/shaders/atmosphericScatteringFragment.glsl b/src/shaders/atmosphericScatteringFragment.glsl index 3be626de9..033a6e5e9 100644 --- a/src/shaders/atmosphericScatteringFragment.glsl +++ b/src/shaders/atmosphericScatteringFragment.glsl @@ -12,13 +12,8 @@ uniform sampler2D depthSampler;// the depth map of the camera uniform sampler2D atmosphereLUT; -#define MAX_STARS 5 uniform int nbStars;// number of stars -struct Star { - vec3 position; - float radius; -}; -uniform Star stars[MAX_STARS]; +#pragma glslify: stars = require(./utils/stars.glsl) #pragma glslify: camera = require(./utils/camera.glsl) diff --git a/src/shaders/flatCloudsFragment.glsl b/src/shaders/flatCloudsFragment.glsl index 74eef7906..c93599713 100644 --- a/src/shaders/flatCloudsFragment.glsl +++ b/src/shaders/flatCloudsFragment.glsl @@ -6,13 +6,8 @@ in vec2 vUV;// screen coordinates uniform sampler2D textureSampler;// the original screen texture uniform sampler2D depthSampler;// the depth map of the camera -#define MAX_STARS 5 uniform int nbStars;// number of stars -struct Star { - vec3 position; - float radius; -}; -uniform Star stars[MAX_STARS]; +#pragma glslify: stars = require(./utils/stars.glsl) #pragma glslify: camera = require(./utils/camera.glsl) diff --git a/src/shaders/mandelbulb.glsl b/src/shaders/mandelbulb.glsl index 2ca3f30f5..70f8cafd2 100644 --- a/src/shaders/mandelbulb.glsl +++ b/src/shaders/mandelbulb.glsl @@ -9,13 +9,8 @@ uniform float time; uniform float power; uniform vec3 accentColor; -#define MAX_STARS 5 uniform int nbStars;// number of stars -struct Star { - vec3 position; - float radius; -}; -uniform Star stars[MAX_STARS]; +#pragma glslify: stars = require(./utils/stars.glsl) uniform sampler2D textureSampler; uniform sampler2D depthSampler; diff --git a/src/shaders/oceanFragment.glsl b/src/shaders/oceanFragment.glsl index e0353e973..19cf06445 100644 --- a/src/shaders/oceanFragment.glsl +++ b/src/shaders/oceanFragment.glsl @@ -9,13 +9,8 @@ uniform sampler2D normalMap2; #pragma glslify: camera = require(./utils/camera.glsl) -#define MAX_STARS 5 uniform int nbStars;// number of stars -struct Star { - vec3 position; - float radius; -}; -uniform Star stars[MAX_STARS]; +#pragma glslify: stars = require(./utils/stars.glsl) #pragma glslify: object = require(./utils/object.glsl) diff --git a/src/shaders/ringsFragment.glsl b/src/shaders/ringsFragment.glsl index 246832747..29467b46b 100644 --- a/src/shaders/ringsFragment.glsl +++ b/src/shaders/ringsFragment.glsl @@ -5,13 +5,8 @@ in vec2 vUV;// screen coordinates uniform sampler2D textureSampler;// the original screen texture uniform sampler2D depthSampler;// the depth map of the camera -#define MAX_STARS 5 uniform int nbStars;// number of stars -struct Star { - vec3 position; - float radius; -}; -uniform Star stars[MAX_STARS]; +#pragma glslify: stars = require(./utils/stars.glsl) #pragma glslify: camera = require(./utils/camera.glsl) diff --git a/src/shaders/shadowFragment.glsl b/src/shaders/shadowFragment.glsl index 84066aa73..0a8a6090a 100644 --- a/src/shaders/shadowFragment.glsl +++ b/src/shaders/shadowFragment.glsl @@ -5,13 +5,9 @@ in vec2 vUV;// screen coordinates uniform sampler2D textureSampler;// the original screen texture uniform sampler2D depthSampler;// the depth map of the camera -#define MAX_STARS 5 + uniform int nbStars;// number of stars -struct Star { - vec3 position; - float radius; -}; -uniform Star stars[MAX_STARS]; +#pragma glslify: stars = require(./utils/stars.glsl) #pragma glslify: camera = require(./utils/camera.glsl) diff --git a/src/shaders/sierpinski.glsl b/src/shaders/sierpinski.glsl index 21c59244d..f734ee0df 100644 --- a/src/shaders/sierpinski.glsl +++ b/src/shaders/sierpinski.glsl @@ -10,13 +10,8 @@ uniform float planetRadius; uniform float power; uniform vec3 accentColor; -#define MAX_STARS 5 uniform int nbStars;// number of stars -struct Star { - vec3 position; - float radius; -}; -uniform Star stars[MAX_STARS]; +#pragma glslify: stars = require(./utils/stars.glsl) uniform sampler2D textureSampler; uniform sampler2D depthSampler; diff --git a/src/shaders/utils/stars.glsl b/src/shaders/utils/stars.glsl new file mode 100644 index 000000000..f30593127 --- /dev/null +++ b/src/shaders/utils/stars.glsl @@ -0,0 +1,9 @@ +#define MAX_STARS 5 +struct Star { + vec3 position; + float radius; + vec3 color; +}; +uniform Star stars[MAX_STARS]; + +#pragma glslify: export(stars) \ No newline at end of file diff --git a/src/shaders/volumetricCloudsFragment.glsl b/src/shaders/volumetricCloudsFragment.glsl index 74bb8a19e..716881481 100644 --- a/src/shaders/volumetricCloudsFragment.glsl +++ b/src/shaders/volumetricCloudsFragment.glsl @@ -10,13 +10,8 @@ in vec2 vUV;// screen coordinates uniform sampler2D textureSampler;// the original screen texture uniform sampler2D depthSampler;// the depth map of the camera -#define MAX_STARS 5 uniform int nbStars;// number of stars -struct Star { - vec3 position; - float radius; -}; -uniform Star stars[MAX_STARS]; +#pragma glslify: stars = require(./utils/stars.glsl) #pragma glslify: camera = require(./utils/camera.glsl) diff --git a/src/ts/view/postProcesses/uniforms.ts b/src/ts/view/postProcesses/uniforms.ts index 8623f5443..305ba085e 100644 --- a/src/ts/view/postProcesses/uniforms.ts +++ b/src/ts/view/postProcesses/uniforms.ts @@ -2,6 +2,8 @@ import { UberScene } from "../../controller/uberCore/uberScene"; import { BaseObject, OrbitalObject } from "../common"; import { UniformEnumType, ShaderSamplers, ShaderUniforms, SamplerEnumType } from "../../controller/uberCore/postProcesses/types"; import { StellarObject } from "../bodies/stellarObjects/stellarObject"; +import { Star } from "../bodies/stellarObjects/star"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; export function getActiveCameraUniforms(scene: UberScene): ShaderUniforms { return [ @@ -46,15 +48,23 @@ export function getActiveCameraUniforms(scene: UberScene): ShaderUniforms { export function getStellarObjectsUniforms(stars: StellarObject[]): ShaderUniforms { return [ ...stars.flatMap((star, index) => { - return [{ - name: `stars[${index}].position`, - type: UniformEnumType.Vector3, - get: () => star.getTransform().getAbsolutePosition() - }, { - name: `stars[${index}].radius`, - type: UniformEnumType.Float, - get: () => star.getRadius() - }]; + return [ + { + name: `stars[${index}].position`, + type: UniformEnumType.Vector3, + get: () => star.getTransform().getAbsolutePosition() + }, + { + name: `stars[${index}].radius`, + type: UniformEnumType.Float, + get: () => star.getRadius() + }, + { + name: `stars[${index}].color`, + type: UniformEnumType.Vector3, + get: () => (star instanceof Star ? star.model.surfaceColor : Vector3.One()) + } + ]; }), { name: "nbStars", From 68a5d9de88a8df7c45767967f7aa9e0c06b5385c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 10:42:04 +0200 Subject: [PATCH 37/86] ocean takes color of star Still more work needs to be done to create a clean code --- src/shaders/oceanFragment.glsl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shaders/oceanFragment.glsl b/src/shaders/oceanFragment.glsl index 19cf06445..10e5d1c8a 100644 --- a/src/shaders/oceanFragment.glsl +++ b/src/shaders/oceanFragment.glsl @@ -81,7 +81,7 @@ vec4 oceanColor(vec4 originalColor, vec3 rayOrigin, vec3 rayDir, float maximumDi //normalWave = triplanarNormal(samplePointPlanetSpace + vec3(-time, -time, time) * 500.0, normalWave, normalMap2, 0.0000005, ocean.waveBlendingSharpness, 0.2); float ndl = 0.0; - float specularHighlight = 0.0; + vec3 specularHighlight = vec3(0.0); for (int i = 0; i < nbStars; i++) { vec3 sunDir = normalize(stars[i].position - samplePoint); @@ -93,12 +93,12 @@ vec4 oceanColor(vec4 originalColor, vec3 rayOrigin, vec3 rayDir, float maximumDi if (length(rayOrigin - object.position) > ocean.radius) { // if above cloud coverage then specular highlight - specularHighlight += computeSpecularHighlight(sunDir, rayDir, normalWave, ocean.smoothness, ocean.specularPower); + specularHighlight += computeSpecularHighlight(sunDir, rayDir, normalWave, ocean.smoothness, ocean.specularPower) * stars[i].color; } } ndl = saturate(ndl); - specularHighlight = saturate(specularHighlight); + specularHighlight = clamp(specularHighlight, vec3(0.0), vec3(1.0)); if (distanceThroughOcean > 0.0) { float opticalDepth01 = 1.0 - exp(-distanceThroughOcean * ocean.depthModifier); @@ -108,7 +108,7 @@ vec4 oceanColor(vec4 originalColor, vec3 rayOrigin, vec3 rayDir, float maximumDi vec3 deepColor = vec3(0.0, 22.0, 82.0)/255.0; vec3 shallowColor = vec3(32.0, 193.0, 180.0)/255.0; - vec3 oceanColor = mix(shallowColor, deepColor, opticalDepth01); + vec3 oceanColor = mix(shallowColor, deepColor, opticalDepth01) * stars[0].color; vec3 ambiant = mix(oceanColor, originalColor.rgb, alpha); From f4395c00097b5f1546e34fed4d788c4c909a1d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 27 Oct 2023 10:56:25 +0200 Subject: [PATCH 38/86] better gas planet satellites --- src/ts/model/planemos/telluricPlanemoModel.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ts/model/planemos/telluricPlanemoModel.ts b/src/ts/model/planemos/telluricPlanemoModel.ts index 483444c90..760065ade 100644 --- a/src/ts/model/planemos/telluricPlanemoModel.ts +++ b/src/ts/model/planemos/telluricPlanemoModel.ts @@ -113,6 +113,9 @@ export class TelluricPlanemoModel implements PlanemoModel { this.terrainSettings.continents_fragmentation = 0; this.terrainSettings.max_mountain_height = 2e3; } + if(this.isSatelliteOfGas && this.physicalProperties.pressure === 0) { + this.terrainSettings.continents_fragmentation = 0; + } if (uniformRandBool(0.6, this.rng, GENERATION_STEPS.RINGS) && !this.isSatelliteOfTelluric && !this.isSatelliteOfGas) { this.ringsUniforms = new RingsUniforms(this.rng); From 363f861913eb1ff7bb38ceeeb56cd9124f35d493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sat, 28 Oct 2023 13:28:03 +0200 Subject: [PATCH 39/86] surface temperature can now be changed for stars --- src/ts/model/stellarObjects/starModel.ts | 33 +++++++++++++++--------- src/ts/ui/bodyEditor/panels/starPanel.ts | 2 +- src/ts/view/materials/starMaterial.ts | 12 +++------ 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/ts/model/stellarObjects/starModel.ts b/src/ts/model/stellarObjects/starModel.ts index 2d6bff691..952df92ba 100644 --- a/src/ts/model/stellarObjects/starModel.ts +++ b/src/ts/model/stellarObjects/starModel.ts @@ -15,9 +15,8 @@ export class StarModel implements StellarObjectModel { readonly rng: (step: number) => number; readonly seed: number; - readonly surfaceTemperature: number; readonly surfaceColor: Vector3; - readonly stellarType: STELLAR_TYPE; + stellarType: STELLAR_TYPE; readonly radius: number; readonly mass = 1000; @@ -38,26 +37,20 @@ export class StarModel implements StellarObjectModel { this.seed = seed; this.rng = seededSquirrelNoise(this.seed); - this.surfaceTemperature = clamp(normalRandom(5778, 2000, this.rng, GENERATION_STEPS.TEMPERATURE), 3000, 10000); + const surfaceTemperature = clamp(normalRandom(5778, 2000, this.rng, GENERATION_STEPS.TEMPERATURE), 3000, 10000); this.parentBody = parentBody ?? null; this.physicalProperties = { mass: this.mass, rotationPeriod: this.rotationPeriod, - temperature: this.surfaceTemperature, + temperature: surfaceTemperature, axialTilt: 0 }; - this.surfaceColor = getRgbFromTemperature(this.surfaceTemperature); + this.surfaceColor = getRgbFromTemperature(surfaceTemperature); - if (this.surfaceTemperature < 3500) this.stellarType = STELLAR_TYPE.M; - else if (this.surfaceTemperature < 5000) this.stellarType = STELLAR_TYPE.K; - else if (this.surfaceTemperature < 6000) this.stellarType = STELLAR_TYPE.G; - else if (this.surfaceTemperature < 7500) this.stellarType = STELLAR_TYPE.F; - else if (this.surfaceTemperature < 10000) this.stellarType = STELLAR_TYPE.A; - else if (this.surfaceTemperature < 30000) this.stellarType = STELLAR_TYPE.B; - else this.stellarType = STELLAR_TYPE.O; + this.stellarType = StarModel.getStellarTypeFromTemperature(surfaceTemperature); //TODO: make it dependent on star type this.radius = randRange(50, 200, this.rng, GENERATION_STEPS.RADIUS) * Settings.EARTH_RADIUS; @@ -79,4 +72,20 @@ export class StarModel implements StellarObjectModel { this.ringsUniforms = null; } } + + public setSurfaceTemperature(temperature: number) { + this.physicalProperties.temperature = temperature; + this.stellarType = StarModel.getStellarTypeFromTemperature(temperature); + this.surfaceColor.copyFrom(getRgbFromTemperature(temperature)); + } + + static getStellarTypeFromTemperature(temperature: number) { + if (temperature < 3500) return STELLAR_TYPE.M; + else if (temperature < 5000) return STELLAR_TYPE.K; + else if (temperature < 6000) return STELLAR_TYPE.G; + else if (temperature < 7500) return STELLAR_TYPE.F; + else if (temperature < 10000) return STELLAR_TYPE.A; + else if (temperature < 30000) return STELLAR_TYPE.B; + else return STELLAR_TYPE.O; + } } diff --git a/src/ts/ui/bodyEditor/panels/starPanel.ts b/src/ts/ui/bodyEditor/panels/starPanel.ts index 29d83b13b..9fbe8668e 100644 --- a/src/ts/ui/bodyEditor/panels/starPanel.ts +++ b/src/ts/ui/bodyEditor/panels/starPanel.ts @@ -12,7 +12,7 @@ export class StarPanel extends EditorPanel { this.sliders = [ new Slider("temperature", document.getElementById("temperature") as HTMLElement, 3000, 15000, star.model.physicalProperties.temperature, (val: number) => { - star.model.physicalProperties.temperature = val; + star.model.setSurfaceTemperature(val); }), new Slider("starExposure", document.getElementById("starExposure") as HTMLElement, 0, 200, volumetricLight.exposure * 100, (val: number) => { volumetricLight.exposure = val / 100; diff --git a/src/ts/view/materials/starMaterial.ts b/src/ts/view/materials/starMaterial.ts index 6214f629f..87b1205d9 100644 --- a/src/ts/view/materials/starMaterial.ts +++ b/src/ts/view/materials/starMaterial.ts @@ -1,15 +1,11 @@ -import { getRgbFromTemperature } from "../../utils/specrend"; - import starMaterialFragment from "../../../shaders/starMaterial/fragment.glsl"; import starMaterialVertex from "../../../shaders/starMaterial/vertex.glsl"; -import { StarPhysicalProperties } from "../../model/common"; import { StarModel } from "../../model/stellarObjects/starModel"; import { Effect } from "@babylonjs/core/Materials/effect"; import { ShaderMaterial } from "@babylonjs/core/Materials/shaderMaterial"; import { Scene } from "@babylonjs/core/scene"; import { TransformNode } from "@babylonjs/core/Meshes"; import { getInverseRotationQuaternion } from "../../controller/uberCore/transforms/basicTransform"; -import { MaterialHelper } from "@babylonjs/core/Materials/materialHelper"; const shaderName = "starMaterial"; Effect.ShadersStore[`${shaderName}FragmentShader`] = starMaterialFragment; @@ -17,7 +13,7 @@ Effect.ShadersStore[`${shaderName}VertexShader`] = starMaterialVertex; export class StarMaterial extends ShaderMaterial { star: TransformNode; - physicalProperties: StarPhysicalProperties; + starModel: StarModel; starSeed: number; constructor(star: TransformNode, model: StarModel, scene: Scene) { @@ -27,7 +23,7 @@ export class StarMaterial extends ShaderMaterial { //defines: ["#define LOGARITHMICDEPTH"] }); this.star = star; - this.physicalProperties = model.physicalProperties; + this.starModel = model; this.starSeed = model.seed; /*this.onBindObservable.add(() => { @@ -37,8 +33,8 @@ export class StarMaterial extends ShaderMaterial { } public update(internalTime: number) { - this.setFloat("time", internalTime % 100000); //FIXME: does this work?? - this.setVector3("starColor", getRgbFromTemperature(this.physicalProperties.temperature)); + this.setFloat("time", internalTime % 100000); + this.setVector3("starColor", this.starModel.surfaceColor); this.setQuaternion("starInverseRotationQuaternion", getInverseRotationQuaternion(this.star)); this.setFloat("seed", this.starSeed); this.setVector3("starPosition", this.star.getAbsolutePosition()); From fb21e60f41c966d4a5a50cfb6d34c7897fbe3fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sat, 28 Oct 2023 13:46:02 +0200 Subject: [PATCH 40/86] enforced orbital plane on objects --- src/ts/view/bodies/abstractObject.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/ts/view/bodies/abstractObject.ts b/src/ts/view/bodies/abstractObject.ts index 6b07a1ab5..3ec5b784c 100644 --- a/src/ts/view/bodies/abstractObject.ts +++ b/src/ts/view/bodies/abstractObject.ts @@ -70,11 +70,22 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla this.parentObject.getTransform().computeWorldMatrix(true); const barycenter = this.parentObject.getTransform().getAbsolutePosition(); + // rotate the object around the barycenter of the orbit, around the normal to the orbital plane const dtheta = (2 * Math.PI * deltaTime) / this.model.orbit.period; rotateAround(this.transform, barycenter, this.model.orbit.normalToPlane, dtheta); + + // enforce distance to orbit center const oldPosition = this.transform.getAbsolutePosition().subtract(barycenter); const newPosition = oldPosition.normalizeToNew().scaleInPlace(this.model.orbit.radius); + + // enforce orbital plane + const correctionAxis = Vector3.Cross(this.model.orbit.normalToPlane, newPosition.normalizeToNew()); + const correctionAngle = 0.5 * Math.PI - Vector3.GetAngleBetweenVectors(this.model.orbit.normalToPlane, newPosition.normalizeToNew(), correctionAxis); + newPosition.applyRotationQuaternionInPlace(Quaternion.RotationAxis(correctionAxis, correctionAngle)); + + // apply corrections translate(this.transform, newPosition.subtract(oldPosition)); + } } From a18bfaa0506384ebf1f3f6d7021ed6df11ce9bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sat, 28 Oct 2023 14:03:07 +0200 Subject: [PATCH 41/86] added translation compensation threshold + comments on the floating origin --- src/ts/controller/starSystem.ts | 35 +++++++++++++++------ src/ts/ui/bodyEditor/panels/generalPanel.ts | 2 +- src/ts/view/bodies/abstractObject.ts | 1 - 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index 461f6d184..3f4be1202 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -443,15 +443,16 @@ export class StarSystem { const controller = this.scene.getActiveController(); const nearestBody = this.getNearestBody(this.scene.getActiveUberCamera().position); - const shouldCompensateRotation = - Vector3.Distance(nearestBody.getTransform().getAbsolutePosition(), controller.getActiveCamera().getAbsolutePosition()) < nearestBody.getRadius() * 4; + const distanceOfNearestToCamera = Vector3.Distance(nearestBody.getTransform().getAbsolutePosition(), controller.getActiveCamera().getAbsolutePosition()); + const shouldCompensateTranslation = distanceOfNearestToCamera < nearestBody.getRadius() * 10; + const shouldCompensateRotation = distanceOfNearestToCamera < nearestBody.getRadius() * 4; nearestBody.updateInternalClock(deltaTime); const initialPosition = nearestBody.getTransform().getAbsolutePosition().clone(); nearestBody.updateOrbitalPosition(deltaTime); const newPosition = nearestBody.getTransform().getAbsolutePosition().clone(); const nearestBodyDisplacement = newPosition.subtract(initialPosition); - translate(nearestBody.getTransform(), nearestBodyDisplacement.negate()); + if (shouldCompensateTranslation) translate(nearestBody.getTransform(), nearestBodyDisplacement.negate()); const dthetaNearest = nearestBody.getDeltaTheta(deltaTime); @@ -460,23 +461,29 @@ export class StarSystem { // As the nearest object is kept in place, we need to transfer its movement to other bodies for (const object of this.orbitalObjects) { - const oldNormal = object.model.orbit.normalToPlane.clone(); + const oldOrbitNormal = object.model.orbit.normalToPlane.clone(); if (shouldCompensateRotation) { // the normal to the orbit planes must be rotated as well (even the one of the nearest body) const rotation = Quaternion.RotationAxis(nearestBody.getRotationAxis(), -dthetaNearest); object.model.orbit.normalToPlane.applyRotationQuaternionInPlace(rotation); } if (object === nearestBody) continue; - translate(object.getTransform(), nearestBodyDisplacement.negate()); + + if (shouldCompensateTranslation) { + // the body is translated so that the nearest body can stay in place + translate(object.getTransform(), nearestBodyDisplacement.negate()); + } + if (shouldCompensateRotation) { // if the nearest body does not rotate, all other bodies must revolve around it for consistency rotateAround(object.getTransform(), nearestBody.getTransform().getAbsolutePosition(), nearestBody.getRotationAxis(), -dthetaNearest); // we must as well rotate their rotation axis to keep consistency const newNormal = object.model.orbit.normalToPlane.clone(); - const angle = Math.acos(Vector3.Dot(oldNormal, newNormal)); - if(angle > 0.02) { - const axis = Vector3.Cross(oldNormal, newNormal); + const angle = Math.acos(Vector3.Dot(oldOrbitNormal, newNormal)); + if (angle > 0.02) { + // FIXME: when time goes very fast, this will get wrongfully executed + const axis = Vector3.Cross(oldOrbitNormal, newNormal); const quaternion = Quaternion.RotationAxis(axis, angle); const newRotationAxis = object.getRotationAxis().applyRotationQuaternion(quaternion); setUpVector(object.getTransform(), newRotationAxis); @@ -485,10 +492,12 @@ export class StarSystem { } if (shouldCompensateRotation) { + // the starfield is rotated to give the impression the nearest body is rotating, which is not the case const starfieldAdditionalRotation = Quaternion.RotationAxis(nearestBody.getRotationAxis(), dthetaNearest); this.starfieldRotation.copyFrom(starfieldAdditionalRotation.multiply(this.starfieldRotation)); } + // finally, all other objects are updated normally for (const object of this.orbitalObjects) { if (object === nearestBody) continue; @@ -499,9 +508,15 @@ export class StarSystem { controller.update(deltaTime); - for (const body of this.telluricPlanets.concat(this.satellites)) body.updateLOD(controller.getTransform().getAbsolutePosition()); + for (const body of this.telluricPlanets.concat(this.satellites)) { + // Meshes with LOD are updated (surface quadtrees) + body.updateLOD(controller.getTransform().getAbsolutePosition()); + } - for (const object of this.orbitalObjects) object.computeCulling(controller.getActiveCamera()); + for (const object of this.orbitalObjects) { + // We disable objects that are too small on the screen + object.computeCulling(controller.getActiveCamera()); + } // floating origin if (controller.getActiveCamera().getAbsolutePosition().length() > 0) { diff --git a/src/ts/ui/bodyEditor/panels/generalPanel.ts b/src/ts/ui/bodyEditor/panels/generalPanel.ts index 02a8a0dbc..a7043314a 100644 --- a/src/ts/ui/bodyEditor/panels/generalPanel.ts +++ b/src/ts/ui/bodyEditor/panels/generalPanel.ts @@ -22,7 +22,7 @@ export class GeneralPanel extends EditorPanel { let axialTiltX = stripAxisFromQuaternion(getRotationQuaternion(body.getTransform()), Axis.Y).toEulerAngles().x; let axialTiltZ = stripAxisFromQuaternion(getRotationQuaternion(body.getTransform()), Axis.Y).toEulerAngles().z; //TODO: do not hardcode here - const power = 3; + const power = 1.4; this.sliders = [ new Slider("axialTiltX", document.getElementById("axialTiltX") as HTMLElement, -180, 180, Math.round((180 * axialTiltX) / Math.PI), (val: number) => { diff --git a/src/ts/view/bodies/abstractObject.ts b/src/ts/view/bodies/abstractObject.ts index 3ec5b784c..c3642b375 100644 --- a/src/ts/view/bodies/abstractObject.ts +++ b/src/ts/view/bodies/abstractObject.ts @@ -67,7 +67,6 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla public updateOrbitalPosition(deltaTime: number) { if (this.model.orbit.period > 0 && this.parentObject !== null) { - this.parentObject.getTransform().computeWorldMatrix(true); const barycenter = this.parentObject.getTransform().getAbsolutePosition(); // rotate the object around the barycenter of the orbit, around the normal to the orbital plane From 9226c787511392bdbb30ef5674a88a9dc19c43fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sat, 28 Oct 2023 19:53:28 +0200 Subject: [PATCH 42/86] stars have names with letter --- src/ts/controller/starSystem.ts | 3 ++- src/ts/utils/parseToStrings.ts | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index 3f4be1202..16b692cc4 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -28,6 +28,7 @@ import { NeutronStarModel } from "../model/stellarObjects/neutronStarModel"; import { ShipController } from "../spaceship/shipController"; import { Quaternion } from "@babylonjs/core/Maths/math"; import { PostProcessType } from "../view/postProcesses/postProcessTypes"; +import { starName } from "../utils/parseToStrings"; export class StarSystem { private readonly scene: UberScene; @@ -189,7 +190,7 @@ export class StarSystem { } public makeStar(model: number | StarModel = this.model.getStarSeed(this.stellarObjects.length)): Star { - const name = `${this.model.getName()} ${this.stellarObjects.length + 1}`; + const name = starName(this.model.getName(), this.stellarObjects.length); const star = new Star(name, this.scene, model, this.stellarObjects[0]); this.addStellarObject(star); return star; diff --git a/src/ts/utils/parseToStrings.ts b/src/ts/utils/parseToStrings.ts index 6b75a424c..27de6d68d 100644 --- a/src/ts/utils/parseToStrings.ts +++ b/src/ts/utils/parseToStrings.ts @@ -21,3 +21,8 @@ export function parseSpeed(speed: number): string { export function parsePercentageFrom01(percentage01: number): string { return `${(percentage01 * 100).toFixed(0)}%`; } + +export const alphabet = "abcdefghijklmnopqrstuvwxyz" +export function starName(baseName: string, index: number): string { + return `${baseName} ${alphabet[index].toUpperCase()}` +} \ No newline at end of file From 68326db7683a1a9a263ac1682837b8bf9a209a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sat, 28 Oct 2023 19:54:21 +0200 Subject: [PATCH 43/86] added sphere containers to planets and stars --- src/ts/view/bodies/planemos/gasPlanet.ts | 23 ++++++++++++++++++- .../view/bodies/planemos/telluricPlanemo.ts | 4 ++++ src/ts/view/bodies/stellarObjects/star.ts | 20 ++++++++++++---- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/ts/view/bodies/planemos/gasPlanet.ts b/src/ts/view/bodies/planemos/gasPlanet.ts index 40b535b0e..917c44f69 100644 --- a/src/ts/view/bodies/planemos/gasPlanet.ts +++ b/src/ts/view/bodies/planemos/gasPlanet.ts @@ -11,11 +11,16 @@ import { Mesh } from "@babylonjs/core/Meshes/mesh"; import { PostProcessType } from "../../postProcesses/postProcessTypes"; import { isSizeOnScreenEnough } from "../../../utils/isObjectVisibleOnScreen"; import { Camera } from "@babylonjs/core/Cameras/camera"; +import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; +import { PhysicsShapeSphere, PhysicsShapeType } from "@babylonjs/core"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; export class GasPlanet extends AbstractBody implements Planemo, PlanemoMaterial { private readonly mesh: Mesh; readonly material: GasPlanetMaterial; + readonly aggregate: PhysicsAggregate; + readonly model: GasPlanetModel; /** @@ -34,12 +39,27 @@ export class GasPlanet extends AbstractBody implements Planemo, PlanemoMaterial `${name}Mesh`, { diameter: this.model.radius * 2, - segments: 64 + segments: 32 }, scene ); this.mesh.parent = this.getTransform(); + this.aggregate = new PhysicsAggregate( + this.getTransform(), + PhysicsShapeType.CONTAINER, + { + mass: 0, + restitution: 0.2 + }, + scene + ); + this.aggregate.body.setMassProperties({ inertia: Vector3.Zero(), mass: 0 }); + this.aggregate.body.disablePreStep = false; + + const physicsShape = new PhysicsShapeSphere(Vector3.Zero(), this.model.radius, scene); + this.aggregate.shape.addChildFromParent(this.getTransform(), physicsShape, this.mesh); + this.material = new GasPlanetMaterial(this.name, this.getTransform(), this.model, scene); this.mesh.material = this.material; @@ -58,6 +78,7 @@ export class GasPlanet extends AbstractBody implements Planemo, PlanemoMaterial } public override dispose(): void { + this.aggregate.dispose(); this.mesh.dispose(); this.material.dispose(); super.dispose(); diff --git a/src/ts/view/bodies/planemos/telluricPlanemo.ts b/src/ts/view/bodies/planemos/telluricPlanemo.ts index 1382e91d7..657e33d6e 100644 --- a/src/ts/view/bodies/planemos/telluricPlanemo.ts +++ b/src/ts/view/bodies/planemos/telluricPlanemo.ts @@ -16,6 +16,7 @@ import { PostProcessType } from "../../postProcesses/postProcessTypes"; import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; import { PhysicsShapeType } from "@babylonjs/core/Physics/v2/IPhysicsEnginePlugin"; import { Camera } from "@babylonjs/core/Cameras/camera"; +import { PhysicsShapeSphere } from "@babylonjs/core"; export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMaterial { readonly sides: ChunkTree[] = new Array(6); // stores the 6 sides of the sphere @@ -73,6 +74,9 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat this.aggregate.body.setMassProperties({ inertia: Vector3.Zero(), mass: 0 }); this.aggregate.body.disablePreStep = false; + const physicsShape = new PhysicsShapeSphere(Vector3.Zero(), this.model.radius, scene); + this.aggregate.shape.addChildFromParent(this.getTransform(), physicsShape, this.getTransform()); + this.sides = [ new ChunkTree(Direction.Up, this.name, this.model, this.aggregate, this.material, scene), new ChunkTree(Direction.Down, this.name, this.model, this.aggregate, this.material, scene), diff --git a/src/ts/view/bodies/stellarObjects/star.ts b/src/ts/view/bodies/stellarObjects/star.ts index 32f4ab8a1..155c88752 100644 --- a/src/ts/view/bodies/stellarObjects/star.ts +++ b/src/ts/view/bodies/stellarObjects/star.ts @@ -13,7 +13,7 @@ import { Mesh } from "@babylonjs/core/Meshes/mesh"; import { Assets } from "../../../controller/assets"; import { setRotationQuaternion } from "../../../controller/uberCore/transforms/basicTransform"; import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; -import { PhysicsShapeType } from "@babylonjs/core"; +import { PhysicsShapeSphere, PhysicsShapeType } from "@babylonjs/core"; import { Camera } from "@babylonjs/core/Cameras/camera"; export class Star extends AbstractBody { @@ -23,7 +23,7 @@ export class Star extends AbstractBody { readonly model: StarModel; - //readonly aggregate: PhysicsAggregate; + readonly aggregate: PhysicsAggregate; /** * New Star @@ -50,9 +50,20 @@ export class Star extends AbstractBody { : Assets.CreateBananaClone(this.model.radius * 2); this.mesh.parent = this.getTransform(); - /*this.aggregate = new PhysicsAggregate(this.mesh, PhysicsShapeType.SPHERE); + this.aggregate = new PhysicsAggregate( + this.getTransform(), + PhysicsShapeType.CONTAINER, + { + mass: 0, + restitution: 0.2 + }, + scene + ); this.aggregate.body.setMassProperties({ inertia: Vector3.Zero(), mass: 0 }); - this.aggregate.body.disablePreStep = false;*/ + this.aggregate.body.disablePreStep = false; + + const physicsShape = new PhysicsShapeSphere(Vector3.Zero(), this.model.radius, scene); + this.aggregate.shape.addChildFromParent(this.getTransform(), physicsShape, this.mesh); this.light = new PointLight(`${name}Light`, Vector3.Zero(), scene); this.light.diffuse.fromArray(getRgbFromTemperature(this.model.physicalProperties.temperature).asArray()); @@ -78,6 +89,7 @@ export class Star extends AbstractBody { } public override dispose(): void { + this.aggregate.dispose(); this.mesh.dispose(); this.light.dispose(); this.material.dispose(); From 189be5b24251f2e30084fbb41efb1d7dd3f61658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sat, 28 Oct 2023 19:55:06 +0200 Subject: [PATCH 44/86] lensflare with fadeout animation --- src/shaders/lensflare.glsl | 10 ++-- src/ts/utils/moveTowards.ts | 6 +++ .../postProcesses/lensFlarePostProcess.ts | 49 +++++++++---------- 3 files changed, 34 insertions(+), 31 deletions(-) create mode 100644 src/ts/utils/moveTowards.ts diff --git a/src/shaders/lensflare.glsl b/src/shaders/lensflare.glsl index cc825e4b3..a40be6b02 100644 --- a/src/shaders/lensflare.glsl +++ b/src/shaders/lensflare.glsl @@ -7,6 +7,8 @@ in vec2 vUV; uniform sampler2D textureSampler;// the original screen texture uniform sampler2D depthSampler;// the depth map of the camera +uniform float visibility; + #pragma glslify: camera = require(./utils/camera.glsl) #pragma glslify: object = require(./utils/object.glsl) @@ -119,11 +121,7 @@ void main() { vec2 objectScreenPos = uvFromWorld(object.position); - //TODO: resample depth, and test if the object is occluded by something else, then do not render the lens flare - float depth2 = texture2D(depthSampler, objectScreenPos).r; - vec3 pixelWorldPosition2 = worldFromUV(objectScreenPos); - float depthDistance = length((pixelWorldPosition2 - camera.position) * remap(depth2, 0.0, 1.0, camera.near, camera.far)); - if (depthDistance < objectDistance - object.radius) { + if (visibility == 0.0) { gl_FragColor = screenColor; return; } @@ -147,7 +145,7 @@ void main() { // no lensflare when looking away from the sun sun *= smoothstep(0.0, 0.1, dot(objectDirection, normalize(closestPoint))); - col += sun; + col += sun * visibility; // Output to screen gl_FragColor = vec4(col, screenColor.a); diff --git a/src/ts/utils/moveTowards.ts b/src/ts/utils/moveTowards.ts new file mode 100644 index 000000000..cefa1ec70 --- /dev/null +++ b/src/ts/utils/moveTowards.ts @@ -0,0 +1,6 @@ +export function moveTowards(x: number, target: number, rate: number): number { + if (x > target) { + return Math.max(target, x - rate); + } + return Math.min(target, x + rate); +} diff --git a/src/ts/view/postProcesses/lensFlarePostProcess.ts b/src/ts/view/postProcesses/lensFlarePostProcess.ts index f233aced2..46720cd09 100644 --- a/src/ts/view/postProcesses/lensFlarePostProcess.ts +++ b/src/ts/view/postProcesses/lensFlarePostProcess.ts @@ -8,14 +8,14 @@ import { ShaderSamplers, ShaderUniforms, UniformEnumType } from "../../controlle import { StellarObject } from "../bodies/stellarObjects/stellarObject"; import { Star } from "../bodies/stellarObjects/star"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; -import { PhysicsEngineV2, PhysicsRaycastResult, Ray, RayHelper } from "@babylonjs/core"; -import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { PhysicsEngineV2, PhysicsRaycastResult } from "@babylonjs/core"; +import { moveTowards } from "../../utils/moveTowards"; const shaderName = "lensflare"; Effect.ShadersStore[`${shaderName}FragmentShader`] = lensFlareFragment; export type LensFlareSettings = { - // empty for now + visibility: number }; export class LensFlarePostProcess extends UberPostProcess implements ObjectPostProcess { @@ -23,7 +23,9 @@ export class LensFlarePostProcess extends UberPostProcess implements ObjectPostP readonly object: StellarObject; constructor(object: StellarObject, scene: UberScene) { - const settings: LensFlareSettings = {}; + const settings: LensFlareSettings = { + visibility: 1 + }; const uniforms: ShaderUniforms = [ ...getObjectUniforms(object), @@ -36,29 +38,26 @@ export class LensFlarePostProcess extends UberPostProcess implements ObjectPostP else return new Vector3(1, 1, 1); } }, - /*{ - name: "occulted", - type: UniformEnumType.Bool, - get: () => { - // send raycast from camera to object and check early intersections - const raycastResult = new PhysicsRaycastResult(); - const start = scene.getActiveUberCamera().getAbsolutePosition(); - const end = object.transform.getAbsolutePosition(); - (scene.getPhysicsEngine() as PhysicsEngineV2).raycastToRef(start, end, raycastResult); - if (raycastResult.hasHit) { - //console.log(Vector3.Distance(raycastResult.body!.getObjectCenterWorld(), object.transform.getAbsolutePosition())); - //console.log(raycastResult.body?.transformNode.name); - - const ray1 = new Ray(start, end.subtract(start).normalize(), Vector3.Distance(start, end)); - const ray1Helper = new RayHelper(ray1); - ray1Helper.show(scene, new Color3(1, 1, 0)); + { + name: "visibility", + type: UniformEnumType.Float, + get: () => { + // send raycast from camera to object and check early intersections + const raycastResult = new PhysicsRaycastResult(); + const start = scene.getActiveUberCamera().getAbsolutePosition(); + const end = object.getTransform().getAbsolutePosition(); + (scene.getPhysicsEngine() as PhysicsEngineV2).raycastToRef(start, end, raycastResult); + const occulted = raycastResult.hasHit && raycastResult.body?.transformNode.name !== object.name; - return true; - } + if(occulted && settings.visibility > 0) { + settings.visibility = moveTowards(settings.visibility, 0, 0.5); + } else if(!occulted && settings.visibility < 1) { + settings.visibility = moveTowards(settings.visibility, 1, 0.5); + } - return false; - } - },*/ + return settings.visibility; + } + }, { name: "aspectRatio", type: UniformEnumType.Float, From 1be9b3ca5ddb725f4466728604d51a512ef8213f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 01:08:33 +0200 Subject: [PATCH 45/86] disable occlusion on chunks It is kinda bugged --- src/ts/controller/chunks/planetChunk.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ts/controller/chunks/planetChunk.ts b/src/ts/controller/chunks/planetChunk.ts index b01b4e070..d9c5a73f1 100644 --- a/src/ts/controller/chunks/planetChunk.ts +++ b/src/ts/controller/chunks/planetChunk.ts @@ -5,7 +5,6 @@ import { Mesh } from "@babylonjs/core/Meshes/mesh"; import { Material } from "@babylonjs/core/Materials/material"; import { Transformable } from "../../view/common"; import { Scene } from "@babylonjs/core/scene"; -import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; import "@babylonjs/core/Engines/Extensions/engine.query"; import { TransformNode, VertexData } from "@babylonjs/core/Meshes"; import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; @@ -47,8 +46,8 @@ export class PlanetChunk implements Transformable { this.transform.parent = parentAggregate.transformNode; this.mesh.parent = this.transform; - this.mesh.occlusionQueryAlgorithmType = AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE; - this.mesh.occlusionType = AbstractMesh.OCCLUSION_TYPE_STRICT; + //this.mesh.occlusionQueryAlgorithmType = AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE; + //this.mesh.occlusionType = AbstractMesh.OCCLUSION_TYPE_STRICT; this.parent = parentAggregate.transformNode; this.parentAggregate = parentAggregate; From c06a2011475ffdc5f1ee5ee4e833a04e794d1ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 01:08:38 +0200 Subject: [PATCH 46/86] Create quadTree.ts --- src/ts/controller/chunks/quadTree.ts | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/ts/controller/chunks/quadTree.ts diff --git a/src/ts/controller/chunks/quadTree.ts b/src/ts/controller/chunks/quadTree.ts new file mode 100644 index 000000000..5eea1be0a --- /dev/null +++ b/src/ts/controller/chunks/quadTree.ts @@ -0,0 +1,37 @@ +/** + * A quadTree is defined recursively + */ +type tree = tree[] | T; + +/** + * A ChunkTree is a structure designed to manage LOD using a quadtree + */ +export class QuadTree { + private tree: tree = []; + + /** + * Function used to execute code on every leaf of the quadtree + * @param tree the tree to explore + * @param f the function to apply on every leaf + */ + public executeOnEveryLeaf(f: (leaf: T) => void, tree: tree = this.tree): void { + if (tree instanceof Array) { + for (const child of tree) { + this.executeOnEveryLeaf(f, child); + } + } else { + f(tree); + } + } + + public getLeaves(): T[] { + const leaves: T[] = []; + this.executeOnEveryLeaf((leaf) => leaves.push(leaf)); + + return leaves; + } + + public reset(): void { + this.tree = []; + } +} From e9f6010007743a798f50cfcb3fd714fc0348f742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 01:16:06 +0200 Subject: [PATCH 47/86] working physicsshape with terrain LOD The solution is ugly but it works. Basically I must keep track of the havok index of each chunk myself, which means that any chunk deletion must check all other chunk index for update. What a time to be alive. The chunktree + chunkforge system needs a rewrite it is difficult to keep track of chunks between the 2 --- src/ts/controller/chunks/chunkTree.ts | 31 +++++++--- src/ts/controller/chunks/planetChunk.ts | 57 +++++++++++++++---- .../view/bodies/planemos/telluricPlanemo.ts | 8 +++ 3 files changed, 75 insertions(+), 21 deletions(-) diff --git a/src/ts/controller/chunks/chunkTree.ts b/src/ts/controller/chunks/chunkTree.ts index 77b4d8b3d..97b375b49 100644 --- a/src/ts/controller/chunks/chunkTree.ts +++ b/src/ts/controller/chunks/chunkTree.ts @@ -14,7 +14,8 @@ import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; import { TransformNode } from "@babylonjs/core/Meshes"; import { getRotationQuaternion } from "../uberCore/transforms/basicTransform"; import { Camera } from "@babylonjs/core/Cameras/camera"; -import { getAngularSize, isSizeOnScreenEnough } from "../../utils/isObjectVisibleOnScreen"; +import { isSizeOnScreenEnough } from "../../utils/isObjectVisibleOnScreen"; +import { Observable } from "@babylonjs/core/Misc/observable"; /** * A quadTree is defined recursively @@ -37,6 +38,8 @@ export class ChunkTree { private readonly chunkForge: ChunkForge; private readonly scene: UberScene; + private readonly trashCan: PlanetChunk[] = []; + readonly planetName: string; readonly planetSeed: number; readonly terrainSettings: TerrainSettings; @@ -44,6 +47,8 @@ export class ChunkTree { readonly parent: TransformNode; readonly parentAggregate: PhysicsAggregate; + readonly onChunkPhysicsShapeDeletedObservable = new Observable(); + readonly material: Material; /** @@ -51,7 +56,7 @@ export class ChunkTree { * @param direction * @param planetName * @param planetModel - * @param parent + * @param parentAggregate * @param material * @param scene */ @@ -103,6 +108,8 @@ export class ChunkTree { isFiner: isFiner }; this.chunkForge?.addTask(deleteTask); + + this.trashCan.push(chunk); }, tree); } @@ -180,6 +187,10 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ private createChunk(path: number[], isFiner: boolean): PlanetChunk { const chunk = new PlanetChunk(path, this.direction, this.parentAggregate, this.material, this.rootChunkLength, this.minDepth === path.length, this.scene); + chunk.onDestroyPhysicsShapeObservable.add((index) => { + if (chunk.physicsShapeIndex !== null) this.onChunkPhysicsShapeDeletedObservable.notifyObservers(index); + }); + const buildTask: BuildTask = { type: TaskType.Build, planetName: this.planetName, @@ -198,6 +209,15 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ return chunk; } + public registerPhysicsShapeDeletion(index: number): void { + this.executeOnEveryChunk((chunk) => { + chunk.registerPhysicsShapeDeletion(index); + }); + for(const trash of this.trashCan) { + trash.registerPhysicsShapeDeletion(index); + } + } + public computeCulling(camera: Camera): void { this.executeOnEveryChunk((chunk: PlanetChunk) => { if (!chunk.isReady()) return; @@ -209,13 +229,6 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ }); } - public getChunks(): PlanetChunk[] { - const chunks: PlanetChunk[] = []; - this.executeOnEveryChunk((chunk) => chunks.push(chunk)); - - return chunks; - } - /** * Regenerate planet chunks */ diff --git a/src/ts/controller/chunks/planetChunk.ts b/src/ts/controller/chunks/planetChunk.ts index d9c5a73f1..6925e9d5a 100644 --- a/src/ts/controller/chunks/planetChunk.ts +++ b/src/ts/controller/chunks/planetChunk.ts @@ -8,7 +8,8 @@ import { Scene } from "@babylonjs/core/scene"; import "@babylonjs/core/Engines/Extensions/engine.query"; import { TransformNode, VertexData } from "@babylonjs/core/Meshes"; import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; -import { PhysicsShapeMesh } from "@babylonjs/core/Physics/v2/physicsShape"; +import { PhysicsShape, PhysicsShapeMesh } from "@babylonjs/core/Physics/v2/physicsShape"; +import { Observable } from "@babylonjs/core/Misc/observable"; export class PlanetChunk implements Transformable { public readonly mesh: Mesh; @@ -23,7 +24,10 @@ export class PlanetChunk implements Transformable { private readonly parent: TransformNode; - private physicsShape: PhysicsShapeMesh | null = null; + readonly onDestroyPhysicsShapeObservable = new Observable(); + + private physicsShape: PhysicsShape | null = null; + physicsShapeIndex: number | null = null; private readonly parentAggregate: PhysicsAggregate; constructor(path: number[], direction: Direction, parentAggregate: PhysicsAggregate, material: Material, rootLength: number, isMinDepth: boolean, scene: Scene) { @@ -39,10 +43,12 @@ export class PlanetChunk implements Transformable { this.mesh = new Mesh(`Chunk${id}`, scene); this.mesh.setEnabled(false); + this.mesh.material = material; - /*this.mesh.material = Assets.DebugMaterial(id); //material; - (this.mesh.material as StandardMaterial).disableLighting = true; - this.mesh.material.wireframe = true;*/ + //this.mesh.material = Assets.DebugMaterial(id); //material; + //(this.mesh.material as StandardMaterial).disableLighting = true; + //this.mesh.material.wireframe = true; + this.transform.parent = parentAggregate.transformNode; this.mesh.parent = this.transform; @@ -64,6 +70,8 @@ export class PlanetChunk implements Transformable { position.normalize().scaleInPlace(rootLength / 2); this.transform.position = position; + + //console.log(this.mesh.name + " created") } public getTransform(): TransformNode { @@ -75,15 +83,38 @@ export class PlanetChunk implements Transformable { this.mesh.freezeNormals(); if (this.isMinDepth) this.setReady(true); - if (this.depth > 7) { - //this.aggregate = new PhysicsAggregate(this.mesh, PhysicsShapeType.MESH, { mass: 0 }, this.mesh.getScene()); - //this.aggregate.body.disablePreStep = false; - + //if (this.depth > 7) { this.physicsShape = new PhysicsShapeMesh(this.mesh, this.mesh.getScene()); - this.parentAggregate.shape.addChildFromParent(this.parent, this.physicsShape, this.mesh); - //this.aggregate.shape.addChildFromParent(this.parent.node, this.aggregate.shape, this.mesh); + this.physicsShapeIndex = this.parentAggregate.shape.getNumChildren(); + //console.log("Created with index: " + this.physicsShapeIndex); + //} + + //console.log(this.mesh.name + " physicsed", this.physicsShapeIndex); + } + + public destroyPhysicsShape() { + if (this.physicsShapeIndex === null) { + //console.error(this.mesh.name + " INDEX NULL"); + return; } + if(this.physicsShapeIndex > this.parentAggregate.shape.getNumChildren()) { + //console.error(this.mesh.name + " ERROR", this.physicsShapeIndex, this.parentAggregate.shape.getNumChildren()); + return; + } + + //console.log(this.physicsShapeIndex, this.parentAggregate.shape.getNumChildren()); + this.parentAggregate.shape.removeChild(this.physicsShapeIndex); + this.physicsShape?.dispose(); + + //console.log(this.mesh.name + " unphysicsed", this.physicsShapeIndex); + + this.onDestroyPhysicsShapeObservable.notifyObservers(this.physicsShapeIndex); + } + + public registerPhysicsShapeDeletion(shapeIndex: number) { + if (this.physicsShapeIndex === null) return; + if (this.physicsShapeIndex > shapeIndex) this.physicsShapeIndex--; } public getBoundingRadius(): number { @@ -108,7 +139,9 @@ export class PlanetChunk implements Transformable { } public dispose() { - this.transform.dispose(); + this.destroyPhysicsShape(); this.mesh.dispose(); + this.transform.dispose(); + //console.log(this.mesh.name + " disposed"); } } diff --git a/src/ts/view/bodies/planemos/telluricPlanemo.ts b/src/ts/view/bodies/planemos/telluricPlanemo.ts index 657e33d6e..bd337b145 100644 --- a/src/ts/view/bodies/planemos/telluricPlanemo.ts +++ b/src/ts/view/bodies/planemos/telluricPlanemo.ts @@ -85,6 +85,14 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat new ChunkTree(Direction.Right, this.name, this.model, this.aggregate, this.material, scene), new ChunkTree(Direction.Left, this.name, this.model, this.aggregate, this.material, scene) ]; + + for(const side of this.sides) { + side.onChunkPhysicsShapeDeletedObservable.add((index) => { + for(const side2 of this.sides) { + side2.registerPhysicsShapeDeletion(index); + } + }); + } } /** From 7b96aff89f8e81d76be8d070f36b8ccfa984373a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 11:24:57 +0100 Subject: [PATCH 48/86] fixed lensflare visual bug + simplified it quite a bit --- src/shaders/lensflare.glsl | 21 +++++++-------------- src/ts/view/postProcesses/uniforms.ts | 2 +- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/shaders/lensflare.glsl b/src/shaders/lensflare.glsl index a40be6b02..02a5037da 100644 --- a/src/shaders/lensflare.glsl +++ b/src/shaders/lensflare.glsl @@ -18,7 +18,7 @@ uniform float visibility; #pragma glslify: remap = require(./utils/remap.glsl) -uniform vec3 flareColor;// = vec3(0.643, 0.494, 0.867); +uniform vec3 flareColor; uniform float aspectRatio; float getSun(vec2 uv){ @@ -107,25 +107,18 @@ vec3 anflares(vec2 uv, float intensity, float stretch, float brightness) void main() { vec4 screenColor = texture(textureSampler, vUV); - float depth = texture2D(depthSampler, vUV).r;// the depth corresponding to the pixel in the depth map + if (visibility == 0.0) { + gl_FragColor = screenColor; + return; + } vec3 pixelWorldPosition = worldFromUV(vUV);// the pixel position in world space (near plane) - // actual depth of the scene - float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); vec3 rayDir = normalize(pixelWorldPosition - camera.position); - // closest physical point from the camera in the direction of the pixel (occlusion) - vec3 closestPoint = camera.position + rayDir * maximumDistance; - float objectDistance = length(object.position - camera.position); - vec3 objectDirection = (object.position - camera.position) / objectDistance; + vec3 objectDirection = normalize(object.position - camera.position); vec2 objectScreenPos = uvFromWorld(object.position); - if (visibility == 0.0) { - gl_FragColor = screenColor; - return; - } - // Normalized pixel coordinates (from 0 to 1) vec2 uv = vUV - 0.5; vec2 mouse = objectScreenPos - 0.5; @@ -143,7 +136,7 @@ void main() { sun += getSun(uv-mouse) + (flare + anflare)*flareColor*2.0; // no lensflare when looking away from the sun - sun *= smoothstep(0.0, 0.1, dot(objectDirection, normalize(closestPoint))); + sun *= smoothstep(0.0, 0.1, dot(objectDirection, rayDir)); col += sun * visibility; diff --git a/src/ts/view/postProcesses/uniforms.ts b/src/ts/view/postProcesses/uniforms.ts index 305ba085e..6a8c3b798 100644 --- a/src/ts/view/postProcesses/uniforms.ts +++ b/src/ts/view/postProcesses/uniforms.ts @@ -1,5 +1,5 @@ import { UberScene } from "../../controller/uberCore/uberScene"; -import { BaseObject, OrbitalObject } from "../common"; +import { BaseObject } from "../common"; import { UniformEnumType, ShaderSamplers, ShaderUniforms, SamplerEnumType } from "../../controller/uberCore/postProcesses/types"; import { StellarObject } from "../bodies/stellarObjects/stellarObject"; import { Star } from "../bodies/stellarObjects/star"; From fff6892284e6eafc7ea33c63200cb12a814a6057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 11:57:28 +0100 Subject: [PATCH 49/86] introduced mutexes for chunk deletion this lead to really interesting simplifications --- src/ts/controller/chunks/chunkForge.ts | 46 ++---------------- src/ts/controller/chunks/chunkTree.ts | 64 ++++++++++++++----------- src/ts/controller/chunks/deleteMutex.ts | 24 ++++++++++ src/ts/controller/chunks/planetChunk.ts | 3 ++ src/ts/controller/chunks/taskTypes.ts | 7 --- src/ts/controller/chunks/workerPool.ts | 10 ++-- 6 files changed, 72 insertions(+), 82 deletions(-) create mode 100644 src/ts/controller/chunks/deleteMutex.ts diff --git a/src/ts/controller/chunks/chunkForge.ts b/src/ts/controller/chunks/chunkForge.ts index 72120a91a..1feec406e 100644 --- a/src/ts/controller/chunks/chunkForge.ts +++ b/src/ts/controller/chunks/chunkForge.ts @@ -1,5 +1,5 @@ import { TransferBuildData } from "./workerDataTypes"; -import { ApplyTask, BuildTask, DeleteTask, ReturnedChunkData, TaskType } from "./taskTypes"; +import { ApplyTask, BuildTask, ReturnedChunkData, TaskType } from "./taskTypes"; import { WorkerPool } from "./workerPool"; import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData"; @@ -19,18 +19,13 @@ export class ChunkForge { */ applyTasks: ApplyTask[] = []; - /** - * Contains deletion task grouped together in sublist - */ - deleteTasks: DeleteTask[][] = []; - constructor(nbVerticesPerSide: number) { this.nbVerticesPerSide = nbVerticesPerSide; const nbMaxWorkers = navigator.hardwareConcurrency - 1; // -1 because the main thread is also used this.workerPool = new WorkerPool(nbMaxWorkers); } - public addTask(task: BuildTask | DeleteTask) { + public addTask(task: BuildTask) { this.workerPool.submitTask(task); } @@ -44,12 +39,6 @@ export class ChunkForge { } private executeBuildTask(task: BuildTask, worker: Worker): void { - // delete tasks always follow build task, they are stored to be executed as callbacks of the build task - const callbackTasks: DeleteTask[] = []; - while (this.workerPool.taskQueue.length > 0 && this.workerPool.taskQueue[0].type === TaskType.Deletion) { - callbackTasks.push(this.workerPool.nextTask() as DeleteTask); - } - const buildData: TransferBuildData = { taskType: TaskType.Build, planetName: task.planetName, @@ -83,9 +72,7 @@ export class ChunkForge { const applyTask: ApplyTask = { type: TaskType.Apply, vertexData: vertexData, - chunk: task.chunk, - callbackTasks: callbackTasks, - isFiner: task.isFiner + chunk: task.chunk }; this.applyTasks.push(applyTask); @@ -94,38 +81,17 @@ export class ChunkForge { }; } - private dispatchTask(task: DeleteTask | BuildTask, worker: Worker) { + private dispatchTask(task: BuildTask, worker: Worker) { switch (task.type) { case TaskType.Build: this.executeBuildTask(task as BuildTask, worker); break; - case TaskType.Deletion: - console.error("Solitary Delete Task received, this cannot happen !"); - this.workerPool.finishedWorkers.push(worker); - break; default: console.error(`Illegal task received ! TaskType : ${task.type}`); this.workerPool.finishedWorkers.push(worker); } } - /** - * Removes all useless chunks - */ - private executeDeleteTasks() { - for (const deleteTask of this.deleteTasks) { - for (let i = 0; i < deleteTask.length; i++) { - const task = deleteTask[i]; - // disabling old chunk - task.chunk.setReady(false); - // if we are removing the last old chunk, enabling new chunks - if (i === deleteTask.length - 1) for (const chunk of task.newChunks) chunk.setReady(true); - task.chunk.dispose(); - } - } - this.deleteTasks = []; - } - /** * Apply generated vertexData to waiting chunks */ @@ -133,8 +99,7 @@ export class ChunkForge { const task = this.applyTasks.shift(); if (task) { task.chunk.init(task.vertexData); - this.deleteTasks.push(task.callbackTasks); - if (task.callbackTasks.length === 0) task.chunk.setReady(true); + task.chunk.setReady(true); } } @@ -147,7 +112,6 @@ export class ChunkForge { } this.workerPool.availableWorkers = this.workerPool.availableWorkers.concat(this.workerPool.finishedWorkers); this.workerPool.finishedWorkers = []; - this.executeDeleteTasks(); this.executeNextApplyTask(); } diff --git a/src/ts/controller/chunks/chunkTree.ts b/src/ts/controller/chunks/chunkTree.ts index 97b375b49..91c0640c9 100644 --- a/src/ts/controller/chunks/chunkTree.ts +++ b/src/ts/controller/chunks/chunkTree.ts @@ -1,7 +1,7 @@ import { PlanetChunk } from "./planetChunk"; import { Direction } from "../../utils/direction"; import { ChunkForge } from "./chunkForge"; -import { BuildTask, DeleteTask, TaskType } from "./taskTypes"; +import { BuildTask, TaskType } from "./taskTypes"; import { Settings } from "../../settings"; import { getChunkSphereSpacePositionFromPath } from "../../utils/chunkUtils"; import { TerrainSettings } from "../../model/terrain/terrainSettings"; @@ -16,6 +16,7 @@ import { getRotationQuaternion } from "../uberCore/transforms/basicTransform"; import { Camera } from "@babylonjs/core/Cameras/camera"; import { isSizeOnScreenEnough } from "../../utils/isObjectVisibleOnScreen"; import { Observable } from "@babylonjs/core/Misc/observable"; +import { DeleteMutex } from "./deleteMutex"; /** * A quadTree is defined recursively @@ -39,6 +40,7 @@ export class ChunkTree { private readonly scene: UberScene; private readonly trashCan: PlanetChunk[] = []; + private deleteMutexes: DeleteMutex[] = []; readonly planetName: string; readonly planetSeed: number; @@ -94,23 +96,22 @@ export class ChunkTree { } /** - * Send deletion request to chunkforge regarding the chunks of a branch + * Creates deletion mutexes for the tree (we will delete the chunks only when the new ones are ready) * @param tree The tree to delete * @param newChunks - * @param isFiner */ - private requestDeletion(tree: quadTree, newChunks: PlanetChunk[], isFiner: boolean): void { - this.executeOnEveryChunk((chunk: PlanetChunk) => { - const deleteTask: DeleteTask = { - type: TaskType.Deletion, - chunk: chunk, - newChunks: newChunks, - isFiner: isFiner - }; - this.chunkForge?.addTask(deleteTask); - - this.trashCan.push(chunk); - }, tree); + private requestDeletion(tree: quadTree, newChunks: PlanetChunk[]): void { + const chunksToDelete = this.getChunkList(tree); + const deleteMutex = new DeleteMutex(newChunks.length, chunksToDelete); + for (const chunk of newChunks) { + chunk.onRecieveVertexDataObservable.add(() => deleteMutex.countdown()); + } + } + + public getChunkList(tree: quadTree): PlanetChunk[] { + const result: PlanetChunk[] = []; + this.executeOnEveryChunk((chunk) => result.push(chunk), tree); + return result; } /** @@ -118,6 +119,13 @@ export class ChunkTree { * @param observerPosition The observer position */ public update(observerPosition: Vector3): void { + // remove delete mutexes that have been resolved + const deleteMutexes: DeleteMutex[] = []; + for (const deleteMutex of this.deleteMutexes) { + if (!deleteMutex.isResolved()) deleteMutexes.push(deleteMutex); + } + this.deleteMutexes = deleteMutexes; + this.tree = this.updateLODRecursively(observerPosition); } @@ -151,12 +159,12 @@ const [intersect, t0, t1] = rayIntersectSphere(observerPositionW, rayDir, this.p if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ const newTree = [ - this.createChunk(walked.concat([0]), true), - this.createChunk(walked.concat([1]), true), - this.createChunk(walked.concat([2]), true), - this.createChunk(walked.concat([3]), true) + this.createChunk(walked.concat([0])), + this.createChunk(walked.concat([1])), + this.createChunk(walked.concat([2])), + this.createChunk(walked.concat([3])) ]; - this.requestDeletion(tree, newTree, true); + this.requestDeletion(tree, newTree); return newTree; } return [ @@ -170,8 +178,8 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ if (tree instanceof PlanetChunk) return tree; if (walked.length >= this.minDepth) { - const newChunk = this.createChunk(walked, false); - this.requestDeletion(tree, [newChunk], false); + const newChunk = this.createChunk(walked); + this.requestDeletion(tree, [newChunk]); return newChunk; } return tree; @@ -181,10 +189,9 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ /** * Create new chunk of terrain at the specified location * @param path The path leading to the location where to add the new chunk - * @param isFiner * @returns The new Chunk */ - private createChunk(path: number[], isFiner: boolean): PlanetChunk { + private createChunk(path: number[]): PlanetChunk { const chunk = new PlanetChunk(path, this.direction, this.parentAggregate, this.material, this.rootChunkLength, this.minDepth === path.length, this.scene); chunk.onDestroyPhysicsShapeObservable.add((index) => { @@ -200,8 +207,7 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ position: chunk.cubePosition, depth: path.length, direction: this.direction, - chunk: chunk, - isFiner: isFiner + chunk: chunk }; this.chunkForge.addTask(buildTask); @@ -213,7 +219,7 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ this.executeOnEveryChunk((chunk) => { chunk.registerPhysicsShapeDeletion(index); }); - for(const trash of this.trashCan) { + for (const trash of this.trashCan) { trash.registerPhysicsShapeDeletion(index); } } @@ -233,8 +239,8 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ * Regenerate planet chunks */ public reset(): void { - const newTree = this.createChunk([], true); - this.requestDeletion(this.tree, [newTree], false); + const newTree = this.createChunk([]); + this.requestDeletion(this.tree, [newTree]); this.tree = newTree; } diff --git a/src/ts/controller/chunks/deleteMutex.ts b/src/ts/controller/chunks/deleteMutex.ts new file mode 100644 index 000000000..c67ea7ee8 --- /dev/null +++ b/src/ts/controller/chunks/deleteMutex.ts @@ -0,0 +1,24 @@ +import { PlanetChunk } from "./planetChunk"; + +export class DeleteMutex { + private flag: number; + private chunksToDelete: PlanetChunk[]; + + constructor(countdown: number, chunksToDelete: PlanetChunk[]) { + this.flag = countdown; + this.chunksToDelete = chunksToDelete; + } + + public countdown() { + this.flag--; + if (this.flag === 0) { + for (const chunk of this.chunksToDelete) { + chunk.dispose(); + } + } + } + + public isResolved() { + return this.flag === 0; + } +} diff --git a/src/ts/controller/chunks/planetChunk.ts b/src/ts/controller/chunks/planetChunk.ts index 6925e9d5a..854f7c755 100644 --- a/src/ts/controller/chunks/planetChunk.ts +++ b/src/ts/controller/chunks/planetChunk.ts @@ -26,6 +26,8 @@ export class PlanetChunk implements Transformable { readonly onDestroyPhysicsShapeObservable = new Observable(); + readonly onRecieveVertexDataObservable = new Observable(); + private physicsShape: PhysicsShape | null = null; physicsShapeIndex: number | null = null; private readonly parentAggregate: PhysicsAggregate; @@ -90,6 +92,7 @@ export class PlanetChunk implements Transformable { //console.log("Created with index: " + this.physicsShapeIndex); //} + this.onRecieveVertexDataObservable.notifyObservers(); //console.log(this.mesh.name + " physicsed", this.physicsShapeIndex); } diff --git a/src/ts/controller/chunks/taskTypes.ts b/src/ts/controller/chunks/taskTypes.ts index 756be9d98..b501486b7 100644 --- a/src/ts/controller/chunks/taskTypes.ts +++ b/src/ts/controller/chunks/taskTypes.ts @@ -5,7 +5,6 @@ import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData"; export enum TaskType { - Deletion, Build, Apply, Collision @@ -13,7 +12,6 @@ export enum TaskType { export type Task = { type: TaskType; - isFiner: boolean; chunk: PlanetChunk; }; @@ -29,11 +27,6 @@ export type BuildTask = Task & { export type ApplyTask = Task & { vertexData: VertexData; - callbackTasks: DeleteTask[]; -}; - -export type DeleteTask = Task & { - newChunks: PlanetChunk[]; }; export type ReturnedChunkData = { diff --git a/src/ts/controller/chunks/workerPool.ts b/src/ts/controller/chunks/workerPool.ts index e67253246..9a3179700 100644 --- a/src/ts/controller/chunks/workerPool.ts +++ b/src/ts/controller/chunks/workerPool.ts @@ -1,4 +1,4 @@ -import { BuildTask, DeleteTask } from "./taskTypes"; +import { BuildTask } from "./taskTypes"; /*export class BuildTaskQueue { array: ArrayBuffer @@ -10,7 +10,7 @@ import { BuildTask, DeleteTask } from "./taskTypes"; export class WorkerPool { availableWorkers: Worker[] = []; // liste des workers disponibles pour exécuter des tâches finishedWorkers: Worker[] = []; // liste des workers ayant terminé leur tâche (prêts à être réintégré dans la liste des workers disponibles) - taskQueue: (BuildTask | DeleteTask)[] = []; + taskQueue: BuildTask[] = []; //TODO: continuer à expérimenter avec le SharedArrayBuffer //sharedMemoryBuffer: SharedArrayBuffer; @@ -26,7 +26,7 @@ export class WorkerPool { } } - public submitTask(task: BuildTask | DeleteTask) { + public submitTask(task: BuildTask) { this.taskQueue.push(task); } @@ -34,8 +34,8 @@ export class WorkerPool { return this.taskQueue.length > 0; } - public nextTask(): DeleteTask | BuildTask { - if (this.hasTask()) return this.taskQueue.shift() as DeleteTask | BuildTask; + public nextTask(): BuildTask { + if (this.hasTask()) return this.taskQueue.shift() as BuildTask; throw new Error("The workerpool has no task to dispatch"); } } From 15ec848ffce5046de11d106496dc36668b3f7044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 12:16:39 +0100 Subject: [PATCH 50/86] better memory management and preventing chunk from getting built when they already have been disposed --- src/ts/controller/chunks/chunkForge.ts | 6 +++++- src/ts/controller/chunks/chunkTree.ts | 5 +++++ src/ts/controller/chunks/deleteMutex.ts | 2 +- src/ts/controller/chunks/planetChunk.ts | 11 ++++++++++- src/ts/view/bodies/planemos/telluricPlanemo.ts | 1 + 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/ts/controller/chunks/chunkForge.ts b/src/ts/controller/chunks/chunkForge.ts index 1feec406e..fa31c2d81 100644 --- a/src/ts/controller/chunks/chunkForge.ts +++ b/src/ts/controller/chunks/chunkForge.ts @@ -96,7 +96,11 @@ export class ChunkForge { * Apply generated vertexData to waiting chunks */ private executeNextApplyTask() { - const task = this.applyTasks.shift(); + let task = this.applyTasks.shift(); + while(task && task.chunk.hasBeenDisposed()) { + // if the chunk has been disposed, we skip it + task = this.applyTasks.shift(); + } if (task) { task.chunk.init(task.vertexData); task.chunk.setReady(true); diff --git a/src/ts/controller/chunks/chunkTree.ts b/src/ts/controller/chunks/chunkTree.ts index 91c0640c9..c4b22b865 100644 --- a/src/ts/controller/chunks/chunkTree.ts +++ b/src/ts/controller/chunks/chunkTree.ts @@ -248,5 +248,10 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ this.executeOnEveryChunk((chunk: PlanetChunk) => { chunk.dispose(); }); + for(const mutex of this.deleteMutexes) { + for(const chunk of mutex.chunksToDelete) { + chunk.dispose(); + } + } } } diff --git a/src/ts/controller/chunks/deleteMutex.ts b/src/ts/controller/chunks/deleteMutex.ts index c67ea7ee8..7082af774 100644 --- a/src/ts/controller/chunks/deleteMutex.ts +++ b/src/ts/controller/chunks/deleteMutex.ts @@ -2,7 +2,7 @@ import { PlanetChunk } from "./planetChunk"; export class DeleteMutex { private flag: number; - private chunksToDelete: PlanetChunk[]; + readonly chunksToDelete: PlanetChunk[]; constructor(countdown: number, chunksToDelete: PlanetChunk[]) { this.flag = countdown; diff --git a/src/ts/controller/chunks/planetChunk.ts b/src/ts/controller/chunks/planetChunk.ts index 854f7c755..08f4dfabb 100644 --- a/src/ts/controller/chunks/planetChunk.ts +++ b/src/ts/controller/chunks/planetChunk.ts @@ -30,7 +30,9 @@ export class PlanetChunk implements Transformable { private physicsShape: PhysicsShape | null = null; physicsShapeIndex: number | null = null; - private readonly parentAggregate: PhysicsAggregate; + readonly parentAggregate: PhysicsAggregate; + + private disposed = false; constructor(path: number[], direction: Direction, parentAggregate: PhysicsAggregate, material: Material, rootLength: number, isMinDepth: boolean, scene: Scene) { const id = `D${direction}P${path.join("")}`; @@ -81,6 +83,7 @@ export class PlanetChunk implements Transformable { } public init(vertexData: VertexData) { + if(this.disposed) return; vertexData.applyToMesh(this.mesh, false); this.mesh.freezeNormals(); if (this.isMinDepth) this.setReady(true); @@ -141,10 +144,16 @@ export class PlanetChunk implements Transformable { this.mesh.setEnabled(ready); } + public hasBeenDisposed() { + return this.disposed; + } + public dispose() { this.destroyPhysicsShape(); this.mesh.dispose(); this.transform.dispose(); + + this.disposed = true; //console.log(this.mesh.name + " disposed"); } } diff --git a/src/ts/view/bodies/planemos/telluricPlanemo.ts b/src/ts/view/bodies/planemos/telluricPlanemo.ts index bd337b145..025d8ce1e 100644 --- a/src/ts/view/bodies/planemos/telluricPlanemo.ts +++ b/src/ts/view/bodies/planemos/telluricPlanemo.ts @@ -125,6 +125,7 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat public override dispose(): void { this.material.dispose(); for (const side of this.sides) side.dispose(); + this.aggregate.dispose(); super.dispose(); } } From c98c66371a4bd1e284652387460f7c08da7fbad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 15:36:19 +0100 Subject: [PATCH 51/86] more robust mutex system --- src/ts/controller/chunks/chunkForge.ts | 16 ++----- src/ts/controller/chunks/chunkTree.ts | 16 +++---- src/ts/controller/chunks/planetChunk.ts | 56 +++++++++---------------- 3 files changed, 31 insertions(+), 57 deletions(-) diff --git a/src/ts/controller/chunks/chunkForge.ts b/src/ts/controller/chunks/chunkForge.ts index fa31c2d81..0a254fdb1 100644 --- a/src/ts/controller/chunks/chunkForge.ts +++ b/src/ts/controller/chunks/chunkForge.ts @@ -82,14 +82,7 @@ export class ChunkForge { } private dispatchTask(task: BuildTask, worker: Worker) { - switch (task.type) { - case TaskType.Build: - this.executeBuildTask(task as BuildTask, worker); - break; - default: - console.error(`Illegal task received ! TaskType : ${task.type}`); - this.workerPool.finishedWorkers.push(worker); - } + this.executeBuildTask(task, worker); } /** @@ -97,14 +90,11 @@ export class ChunkForge { */ private executeNextApplyTask() { let task = this.applyTasks.shift(); - while(task && task.chunk.hasBeenDisposed()) { + while (task && task.chunk.hasBeenDisposed()) { // if the chunk has been disposed, we skip it task = this.applyTasks.shift(); } - if (task) { - task.chunk.init(task.vertexData); - task.chunk.setReady(true); - } + if (task) task.chunk.init(task.vertexData); } /** diff --git a/src/ts/controller/chunks/chunkTree.ts b/src/ts/controller/chunks/chunkTree.ts index c4b22b865..dd6c0386f 100644 --- a/src/ts/controller/chunks/chunkTree.ts +++ b/src/ts/controller/chunks/chunkTree.ts @@ -39,7 +39,6 @@ export class ChunkTree { private readonly chunkForge: ChunkForge; private readonly scene: UberScene; - private readonly trashCan: PlanetChunk[] = []; private deleteMutexes: DeleteMutex[] = []; readonly planetName: string; @@ -106,6 +105,7 @@ export class ChunkTree { for (const chunk of newChunks) { chunk.onRecieveVertexDataObservable.add(() => deleteMutex.countdown()); } + this.deleteMutexes.push(deleteMutex); } public getChunkList(tree: quadTree): PlanetChunk[] { @@ -120,12 +120,12 @@ export class ChunkTree { */ public update(observerPosition: Vector3): void { // remove delete mutexes that have been resolved - const deleteMutexes: DeleteMutex[] = []; + /*const deleteMutexes: DeleteMutex[] = []; for (const deleteMutex of this.deleteMutexes) { if (!deleteMutex.isResolved()) deleteMutexes.push(deleteMutex); } this.deleteMutexes = deleteMutexes; - +*/ this.tree = this.updateLODRecursively(observerPosition); } @@ -192,10 +192,10 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ * @returns The new Chunk */ private createChunk(path: number[]): PlanetChunk { - const chunk = new PlanetChunk(path, this.direction, this.parentAggregate, this.material, this.rootChunkLength, this.minDepth === path.length, this.scene); + const chunk = new PlanetChunk(path, this.direction, this.parentAggregate, this.material, this.rootChunkLength, this.scene); chunk.onDestroyPhysicsShapeObservable.add((index) => { - if (chunk.physicsShapeIndex !== null) this.onChunkPhysicsShapeDeletedObservable.notifyObservers(index); + this.onChunkPhysicsShapeDeletedObservable.notifyObservers(index); }); const buildTask: BuildTask = { @@ -219,8 +219,10 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ this.executeOnEveryChunk((chunk) => { chunk.registerPhysicsShapeDeletion(index); }); - for (const trash of this.trashCan) { - trash.registerPhysicsShapeDeletion(index); + for(const mutex of this.deleteMutexes) { + for(const chunk of mutex.chunksToDelete) { + chunk.registerPhysicsShapeDeletion(index); + } } } diff --git a/src/ts/controller/chunks/planetChunk.ts b/src/ts/controller/chunks/planetChunk.ts index 08f4dfabb..ab9adbdb0 100644 --- a/src/ts/controller/chunks/planetChunk.ts +++ b/src/ts/controller/chunks/planetChunk.ts @@ -15,8 +15,6 @@ export class PlanetChunk implements Transformable { public readonly mesh: Mesh; private readonly depth: number; public readonly cubePosition: Vector3; - private ready = false; - readonly isMinDepth; private readonly transform: TransformNode; @@ -34,15 +32,13 @@ export class PlanetChunk implements Transformable { private disposed = false; - constructor(path: number[], direction: Direction, parentAggregate: PhysicsAggregate, material: Material, rootLength: number, isMinDepth: boolean, scene: Scene) { + constructor(path: number[], direction: Direction, parentAggregate: PhysicsAggregate, material: Material, rootLength: number, scene: Scene) { const id = `D${direction}P${path.join("")}`; this.depth = path.length; this.chunkSideLength = rootLength / 2 ** this.depth; - this.isMinDepth = isMinDepth; - this.transform = new TransformNode(`${id}Transform`, scene); this.mesh = new Mesh(`Chunk${id}`, scene); @@ -74,8 +70,6 @@ export class PlanetChunk implements Transformable { position.normalize().scaleInPlace(rootLength / 2); this.transform.position = position; - - //console.log(this.mesh.name + " created") } public getTransform(): TransformNode { @@ -83,44 +77,42 @@ export class PlanetChunk implements Transformable { } public init(vertexData: VertexData) { - if(this.disposed) return; + if (this.disposed) return; vertexData.applyToMesh(this.mesh, false); this.mesh.freezeNormals(); - if (this.isMinDepth) this.setReady(true); - //if (this.depth > 7) { - this.physicsShape = new PhysicsShapeMesh(this.mesh, this.mesh.getScene()); - this.parentAggregate.shape.addChildFromParent(this.parent, this.physicsShape, this.mesh); - this.physicsShapeIndex = this.parentAggregate.shape.getNumChildren(); - //console.log("Created with index: " + this.physicsShapeIndex); - //} + this.physicsShape = new PhysicsShapeMesh(this.mesh, this.mesh.getScene()); + this.parentAggregate.shape.addChildFromParent(this.parent, this.physicsShape, this.mesh); + this.physicsShapeIndex = this.parentAggregate.shape.getNumChildren(); + + this.mesh.setEnabled(true); this.onRecieveVertexDataObservable.notifyObservers(); - //console.log(this.mesh.name + " physicsed", this.physicsShapeIndex); } - public destroyPhysicsShape() { + private destroyPhysicsShape() { if (this.physicsShapeIndex === null) { - //console.error(this.mesh.name + " INDEX NULL"); - return; + throw new Error("index is null"); } - if(this.physicsShapeIndex > this.parentAggregate.shape.getNumChildren()) { - //console.error(this.mesh.name + " ERROR", this.physicsShapeIndex, this.parentAggregate.shape.getNumChildren()); - return; + if (this.physicsShapeIndex > this.parentAggregate.shape.getNumChildren() - 1) { + throw new Error( + `Tried to delete ${this.mesh.name} PhysicsShape. However its shape index was out of bound: ${ + this.physicsShapeIndex + } / range 0 : ${this.parentAggregate.shape.getNumChildren() - 1}` + ); } - //console.log(this.physicsShapeIndex, this.parentAggregate.shape.getNumChildren()); this.parentAggregate.shape.removeChild(this.physicsShapeIndex); this.physicsShape?.dispose(); - //console.log(this.mesh.name + " unphysicsed", this.physicsShapeIndex); - this.onDestroyPhysicsShapeObservable.notifyObservers(this.physicsShapeIndex); } public registerPhysicsShapeDeletion(shapeIndex: number) { if (this.physicsShapeIndex === null) return; - if (this.physicsShapeIndex > shapeIndex) this.physicsShapeIndex--; + if (this.physicsShapeIndex > shapeIndex) { + this.physicsShapeIndex--; + } } public getBoundingRadius(): number { @@ -132,16 +124,7 @@ export class PlanetChunk implements Transformable { * @returns true if the chunk is ready to be enabled (i.e if the chunk has recieved its vertex data) */ public isReady() { - return this.ready; - } - - /** - * Sets the chunk readiness. Call it with true when it recieves its vertex data and call it with false when it has to be deleted - * @param ready true if the chunk is ready to be enabled (i.e if the chunk has recieved its vertex data) - */ - public setReady(ready: boolean) { - this.ready = ready; - this.mesh.setEnabled(ready); + return this.mesh.isEnabled(); } public hasBeenDisposed() { @@ -154,6 +137,5 @@ export class PlanetChunk implements Transformable { this.transform.dispose(); this.disposed = true; - //console.log(this.mesh.name + " disposed"); } } From 08e4d72e592d9dcb8ad4dfa5005bdd033ed589e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 15:49:23 +0100 Subject: [PATCH 52/86] better delete mutex --- src/ts/controller/chunks/chunkTree.ts | 22 +++++++++------------- src/ts/controller/chunks/deleteMutex.ts | 14 +++++++++++--- src/ts/controller/chunks/planetChunk.ts | 8 ++++---- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/ts/controller/chunks/chunkTree.ts b/src/ts/controller/chunks/chunkTree.ts index dd6c0386f..1d8bd3617 100644 --- a/src/ts/controller/chunks/chunkTree.ts +++ b/src/ts/controller/chunks/chunkTree.ts @@ -101,11 +101,7 @@ export class ChunkTree { */ private requestDeletion(tree: quadTree, newChunks: PlanetChunk[]): void { const chunksToDelete = this.getChunkList(tree); - const deleteMutex = new DeleteMutex(newChunks.length, chunksToDelete); - for (const chunk of newChunks) { - chunk.onRecieveVertexDataObservable.add(() => deleteMutex.countdown()); - } - this.deleteMutexes.push(deleteMutex); + this.deleteMutexes.push(new DeleteMutex(newChunks, chunksToDelete)); } public getChunkList(tree: quadTree): PlanetChunk[] { @@ -121,10 +117,10 @@ export class ChunkTree { public update(observerPosition: Vector3): void { // remove delete mutexes that have been resolved /*const deleteMutexes: DeleteMutex[] = []; - for (const deleteMutex of this.deleteMutexes) { - if (!deleteMutex.isResolved()) deleteMutexes.push(deleteMutex); - } - this.deleteMutexes = deleteMutexes; + for (const deleteMutex of this.deleteMutexes) { + if (!deleteMutex.isResolved()) deleteMutexes.push(deleteMutex); + } + this.deleteMutexes = deleteMutexes; */ this.tree = this.updateLODRecursively(observerPosition); } @@ -219,8 +215,8 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ this.executeOnEveryChunk((chunk) => { chunk.registerPhysicsShapeDeletion(index); }); - for(const mutex of this.deleteMutexes) { - for(const chunk of mutex.chunksToDelete) { + for (const mutex of this.deleteMutexes) { + for (const chunk of mutex.chunksToDelete) { chunk.registerPhysicsShapeDeletion(index); } } @@ -250,8 +246,8 @@ if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/ this.executeOnEveryChunk((chunk: PlanetChunk) => { chunk.dispose(); }); - for(const mutex of this.deleteMutexes) { - for(const chunk of mutex.chunksToDelete) { + for (const mutex of this.deleteMutexes) { + for (const chunk of mutex.chunksToDelete) { chunk.dispose(); } } diff --git a/src/ts/controller/chunks/deleteMutex.ts b/src/ts/controller/chunks/deleteMutex.ts index 7082af774..bcb887768 100644 --- a/src/ts/controller/chunks/deleteMutex.ts +++ b/src/ts/controller/chunks/deleteMutex.ts @@ -1,15 +1,23 @@ import { PlanetChunk } from "./planetChunk"; +/** + * The DeleteMutex is responsible to delete chunk only when replacements are created to avoid holes in the surface of planets + * Each time a replacement chunk is set ready, we decrement the countdown. When it reaches 0 the old chunks can be deleted + */ export class DeleteMutex { private flag: number; readonly chunksToDelete: PlanetChunk[]; - constructor(countdown: number, chunksToDelete: PlanetChunk[]) { - this.flag = countdown; + constructor(newChunks: PlanetChunk[], chunksToDelete: PlanetChunk[]) { + this.flag = newChunks.length; this.chunksToDelete = chunksToDelete; + + for (const chunk of newChunks) { + chunk.onRecieveVertexDataObservable.add(() => this.countdown()); + } } - public countdown() { + private countdown() { this.flag--; if (this.flag === 0) { for (const chunk of this.chunksToDelete) { diff --git a/src/ts/controller/chunks/planetChunk.ts b/src/ts/controller/chunks/planetChunk.ts index ab9adbdb0..dc15e12d3 100644 --- a/src/ts/controller/chunks/planetChunk.ts +++ b/src/ts/controller/chunks/planetChunk.ts @@ -91,15 +91,15 @@ export class PlanetChunk implements Transformable { } private destroyPhysicsShape() { - if (this.physicsShapeIndex === null) { - throw new Error("index is null"); - } + if (this.physicsShapeIndex === null) return; if (this.physicsShapeIndex > this.parentAggregate.shape.getNumChildren() - 1) { - throw new Error( + console.error( `Tried to delete ${this.mesh.name} PhysicsShape. However its shape index was out of bound: ${ this.physicsShapeIndex } / range 0 : ${this.parentAggregate.shape.getNumChildren() - 1}` ); + this.physicsShape?.dispose(); + return; } this.parentAggregate.shape.removeChild(this.physicsShapeIndex); From 89ca2d1a619004b56dc46902bbe2d875e7d1be01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 16:22:23 +0100 Subject: [PATCH 53/86] fixed collision betweeen loading and cullling system --- src/ts/controller/chunks/planetChunk.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ts/controller/chunks/planetChunk.ts b/src/ts/controller/chunks/planetChunk.ts index dc15e12d3..954640eea 100644 --- a/src/ts/controller/chunks/planetChunk.ts +++ b/src/ts/controller/chunks/planetChunk.ts @@ -20,6 +20,8 @@ export class PlanetChunk implements Transformable { readonly chunkSideLength: number; + private loaded = false; + private readonly parent: TransformNode; readonly onDestroyPhysicsShapeObservable = new Observable(); @@ -86,6 +88,7 @@ export class PlanetChunk implements Transformable { this.physicsShapeIndex = this.parentAggregate.shape.getNumChildren(); this.mesh.setEnabled(true); + this.loaded = true; this.onRecieveVertexDataObservable.notifyObservers(); } @@ -124,7 +127,7 @@ export class PlanetChunk implements Transformable { * @returns true if the chunk is ready to be enabled (i.e if the chunk has recieved its vertex data) */ public isReady() { - return this.mesh.isEnabled(); + return this.loaded; } public hasBeenDisposed() { From e2fec1fec12dadf10bf11bbccaa73b5c2b7f5319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 16:24:57 +0100 Subject: [PATCH 54/86] space station no longer inside planet --- src/ts/model/spacestationModel.ts | 3 ++- src/ts/view/spaceStation.ts | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ts/model/spacestationModel.ts b/src/ts/model/spacestationModel.ts index f17dddc01..7618779b4 100644 --- a/src/ts/model/spacestationModel.ts +++ b/src/ts/model/spacestationModel.ts @@ -3,6 +3,7 @@ import { BaseModel, GENERATION_STEPS, PhysicalProperties } from "./common"; import { getOrbitalPeriod } from "./orbit/orbit"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { OrbitProperties } from "./orbit/orbitProperties"; +import { Settings } from "../settings"; export class SpaceStationModel implements BaseModel { readonly seed: number; @@ -20,7 +21,7 @@ export class SpaceStationModel implements BaseModel { this.childrenBodies = []; //TODO: do not hardcode - const orbitRadius = 3000e3; + const orbitRadius = 3 * Settings.EARTH_RADIUS; this.orbit = { radius: orbitRadius, diff --git a/src/ts/view/spaceStation.ts b/src/ts/view/spaceStation.ts index 28f1e7f46..882826771 100644 --- a/src/ts/view/spaceStation.ts +++ b/src/ts/view/spaceStation.ts @@ -5,7 +5,6 @@ import { SpaceStationModel } from "../model/spacestationModel"; import { AbstractObject } from "./bodies/abstractObject"; import { Axis } from "@babylonjs/core/Maths/math.axis"; import { PostProcessType } from "./postProcesses/postProcessTypes"; -import { Vector3 } from "@babylonjs/core/Maths/math"; import { isSizeOnScreenEnough } from "../utils/isObjectVisibleOnScreen"; import { Camera } from "@babylonjs/core/Cameras/camera"; From 87c3ef2e9cd3457cb2a04847cd94ffe68a0808d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 16:25:07 +0100 Subject: [PATCH 55/86] removed useless imports --- src/ts/index.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ts/index.ts b/src/ts/index.ts index c9bf0921e..6bf2bab4b 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -21,12 +21,9 @@ import { GasPlanetModel } from "./model/planemos/gasPlanetModel"; import { getRotationQuaternion, setRotationQuaternion } from "./controller/uberCore/transforms/basicTransform"; import { PhysicsViewer } from "@babylonjs/core/Debug/physicsViewer"; import { parsePercentageFrom01, parseSpeed } from "./utils/parseToStrings"; -import { MandelbulbModel } from "./model/planemos/mandelbulbModel"; import { getMoonSeed } from "./model/planemos/common"; -import { NeutronStarModel } from "./model/stellarObjects/neutronStarModel"; import { RingsUniforms } from "./model/ringsUniform"; import { StarModel } from "./model/stellarObjects/starModel"; -import { BlackHoleModel } from "./model/stellarObjects/blackHoleModel"; const engine = new SpaceEngine(); @@ -51,7 +48,7 @@ spaceshipController.addInput(keyboard); spaceshipController.addInput(gamepad); spaceshipController.addInput(mouse); -const physicsViewer = new PhysicsViewer(); +//const physicsViewer = new PhysicsViewer(); //physicsViewer.showBody(spaceshipController.aggregate.body); mouse.onMouseLeaveObservable.add(() => { From 795b17a763af5bb63aff6a8b2801d345b1c16964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 16:47:53 +0100 Subject: [PATCH 56/86] spacestation better integrated with systems --- src/ts/blackHoleDemo.ts | 4 +- src/ts/controller/postProcessManager.ts | 4 +- src/ts/controller/spaceEngine.ts | 7 ++- src/ts/controller/starSystem.ts | 47 +++++++++++++------- src/ts/index.ts | 2 +- src/ts/randomizer.ts | 4 +- src/ts/ui/helmetOverlay.ts | 3 +- src/ts/utils/extractRelevantPostProcesses.ts | 6 +-- 8 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/ts/blackHoleDemo.ts b/src/ts/blackHoleDemo.ts index 687239942..c95eef0b7 100644 --- a/src/ts/blackHoleDemo.ts +++ b/src/ts/blackHoleDemo.ts @@ -43,9 +43,9 @@ engine.registerStarSystemUpdateCallback(() => { if (scene.getActiveController() != spaceshipController) return; const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); - const nearestBody = engine.getStarSystem().getNearestBody(shipPosition); + const nearestBody = engine.getStarSystem().getNearestOrbitalObject(shipPosition); const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); - const radius = nearestBody.getRadius(); + const radius = nearestBody.getBoundingRadius(); spaceshipController.registerClosestObject(distance, radius); const warpDrive = spaceshipController.getWarpDrive(); diff --git a/src/ts/controller/postProcessManager.ts b/src/ts/controller/postProcessManager.ts index 1cb1acdd4..8a9b46917 100644 --- a/src/ts/controller/postProcessManager.ts +++ b/src/ts/controller/postProcessManager.ts @@ -79,7 +79,7 @@ export class PostProcessManager { private currentRenderingOrder: PostProcessType[] = spaceRenderingOrder; - private currentBody: AbstractBody | null = null; + private currentBody: AbstractObject | null = null; private readonly starFields: StarfieldPostProcess[] = []; private readonly volumetricLights: VolumetricLight[] = []; @@ -239,7 +239,7 @@ export class PostProcessManager { * Returns the rings post process for the given body. Throws an error if no rings are found. * @param body A body */ - public getRings(body: AbstractBody): RingsPostProcess | null { + public getRings(body: AbstractObject): RingsPostProcess | null { return this.rings.find((rings) => rings.object === body) ?? null; } diff --git a/src/ts/controller/spaceEngine.ts b/src/ts/controller/spaceEngine.ts index 3ca79383a..b14cf5f71 100644 --- a/src/ts/controller/spaceEngine.ts +++ b/src/ts/controller/spaceEngine.ts @@ -32,6 +32,7 @@ import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; import { OrbitRenderer } from "../view/orbitRenderer"; import { PauseMenu } from "../ui/pauseMenu"; import { AxisRenderer } from "../view/axisRenderer"; +import { AbstractBody } from "../view/bodies/abstractBody"; enum EngineState { RUNNING, @@ -258,9 +259,11 @@ export class SpaceEngine { const deltaTime = this.getEngine().getDeltaTime() / 1000; - const nearestBody = starSystem.getNearestBody(starSystemScene.getActiveUberCamera().position); + const nearestBody = starSystem.getNearestOrbitalObject(starSystemScene.getActiveUberCamera().position); - this.bodyEditor.update(nearestBody, starSystem.postProcessManager, starSystemScene); + if(nearestBody instanceof AbstractBody) { + this.bodyEditor.update(nearestBody, starSystem.postProcessManager, starSystemScene); + } this.helmetOverlay.update(nearestBody); //FIXME: should address stars orbits diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index 16b692cc4..eb76a7598 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -324,10 +324,10 @@ export class StarSystem { } /** - * Returns the nearest body to the origin + * Returns the nearest orbital object to the origin */ - public getNearestBody(position = Vector3.Zero()): AbstractBody { - if (this.celestialBodies.length === 0) throw new Error("There are no bodies in the solar system"); + public getNearestOrbitalObject(position = Vector3.Zero()): AbstractObject { + if (this.celestialBodies.length + this.spaceStations.length === 0) throw new Error("There are no bodies or spacestation in the solar system"); let nearest = null; let smallerDistance = -1; for (const body of this.celestialBodies) { @@ -337,22 +337,35 @@ export class StarSystem { smallerDistance = distance; } } + + smallerDistance = -1; + for (const spacestation of this.spaceStations) { + const distance = spacestation.getTransform().getAbsolutePosition().subtract(position).length() - spacestation.getBoundingRadius() * 50; + if (distance < smallerDistance && distance < 0) { + nearest = spacestation; + smallerDistance = distance; + } + } if (nearest === null) throw new Error("There are no bodies in the solar system"); return nearest; } - public getNearestObject(position = Vector3.Zero()): AbstractObject { - if (this.orbitalObjects.length === 0) throw new Error("There are no objects in the solar system"); + /** + * Returns the nearest body to the origin + */ + public getNearestCelestialBody(position = Vector3.Zero()): AbstractBody { + if (this.celestialBodies.length === 0) throw new Error("There are no bodies or spacestation in the solar system"); let nearest = null; - let smallerDistance2 = -1; - for (const object of this.orbitalObjects) { - const distance2 = object.getTransform().getAbsolutePosition().subtract(position).lengthSquared(); - if (nearest === null || distance2 < smallerDistance2) { - nearest = object; - smallerDistance2 = distance2; + let smallerDistance = -1; + for (const body of this.celestialBodies) { + const distance = body.getTransform().getAbsolutePosition().subtract(position).length() - body.model.radius; + if (nearest === null || distance < smallerDistance) { + nearest = body; + smallerDistance = distance; } } - if (nearest === null) throw new Error("There are no objects in the solar system"); + + if (nearest === null) throw new Error("There are no bodies in the solar system"); return nearest; } @@ -433,7 +446,7 @@ export class StarSystem { } } } - this.postProcessManager.setBody(this.getNearestBody(this.scene.getActiveUberCamera().position)); + this.postProcessManager.setBody(this.getNearestCelestialBody(this.scene.getActiveUberCamera().position)); } /** @@ -442,11 +455,11 @@ export class StarSystem { */ public update(deltaTime: number): void { const controller = this.scene.getActiveController(); - const nearestBody = this.getNearestBody(this.scene.getActiveUberCamera().position); + const nearestBody = this.getNearestOrbitalObject(this.scene.getActiveUberCamera().position); const distanceOfNearestToCamera = Vector3.Distance(nearestBody.getTransform().getAbsolutePosition(), controller.getActiveCamera().getAbsolutePosition()); - const shouldCompensateTranslation = distanceOfNearestToCamera < nearestBody.getRadius() * 10; - const shouldCompensateRotation = distanceOfNearestToCamera < nearestBody.getRadius() * 4; + const shouldCompensateTranslation = distanceOfNearestToCamera < nearestBody.getBoundingRadius() * 10; + const shouldCompensateRotation = distanceOfNearestToCamera < nearestBody.getBoundingRadius() * 4; nearestBody.updateInternalClock(deltaTime); const initialPosition = nearestBody.getTransform().getAbsolutePosition().clone(); @@ -531,7 +544,7 @@ export class StarSystem { public updateShaders(deltaTime: number) { const controller = this.scene.getActiveController(); - const nearestBody = this.getNearestBody(this.scene.getActiveUberCamera().position); + const nearestBody = this.getNearestCelestialBody(this.scene.getActiveUberCamera().position); for (const planet of this.planemosWithMaterial) { planet.updateMaterial(controller, this.stellarObjects, deltaTime); diff --git a/src/ts/index.ts b/src/ts/index.ts index 6bf2bab4b..b583c9e49 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -62,7 +62,7 @@ engine.registerStarSystemUpdateCallback(() => { if (scene.getActiveController() != spaceshipController) return; const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); - const nearestBody = engine.getStarSystem().getNearestObject(shipPosition); + const nearestBody = engine.getStarSystem().getNearestOrbitalObject(shipPosition); const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); const radius = nearestBody.getBoundingRadius(); spaceshipController.registerClosestObject(distance, radius); diff --git a/src/ts/randomizer.ts b/src/ts/randomizer.ts index 6b22ed29c..c83a99e0d 100644 --- a/src/ts/randomizer.ts +++ b/src/ts/randomizer.ts @@ -45,9 +45,9 @@ engine.registerStarSystemUpdateCallback(() => { if (scene.getActiveController() != spaceshipController) return; const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); - const nearestBody = engine.getStarSystem().getNearestBody(shipPosition); + const nearestBody = engine.getStarSystem().getNearestOrbitalObject(shipPosition); const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); - const radius = nearestBody.getRadius(); + const radius = nearestBody.getBoundingRadius(); spaceshipController.registerClosestObject(distance, radius); const warpDrive = spaceshipController.getWarpDrive(); diff --git a/src/ts/ui/helmetOverlay.ts b/src/ts/ui/helmetOverlay.ts index 5aa277ea1..07d4bb3ed 100644 --- a/src/ts/ui/helmetOverlay.ts +++ b/src/ts/ui/helmetOverlay.ts @@ -1,5 +1,6 @@ import overlayHTML from "../../html/helmetOverlay.html"; import { AbstractBody } from "../view/bodies/abstractBody"; +import { AbstractObject } from "../view/bodies/abstractObject"; export class HelmetOverlay { private readonly parentNode: HTMLElement; @@ -25,7 +26,7 @@ export class HelmetOverlay { return this.parentNode.style.visibility === "visible"; } - public update(currentBody: AbstractBody) { + public update(currentBody: AbstractObject) { this.bodyNamePlate.innerText = currentBody.name; this.bodySeedPlate.innerText = `Seed: ${currentBody.model.seed.toString()}`; } diff --git a/src/ts/utils/extractRelevantPostProcesses.ts b/src/ts/utils/extractRelevantPostProcesses.ts index 03877bd60..9cdd80b40 100644 --- a/src/ts/utils/extractRelevantPostProcesses.ts +++ b/src/ts/utils/extractRelevantPostProcesses.ts @@ -1,9 +1,9 @@ import { Engine } from "@babylonjs/core/Engines/engine"; -import { AbstractBody } from "../view/bodies/abstractBody"; import { ObjectPostProcess } from "../view/postProcesses/objectPostProcess"; import { PostProcessRenderEffect } from "@babylonjs/core/PostProcesses/RenderPipeline/postProcessRenderEffect"; +import { AbstractObject } from "../view/bodies/abstractObject"; -export function extractRelevantPostProcesses(postProcesses: ObjectPostProcess[], body: AbstractBody): [ObjectPostProcess[], ObjectPostProcess[]] { +export function extractRelevantPostProcesses(postProcesses: ObjectPostProcess[], body: AbstractObject): [ObjectPostProcess[], ObjectPostProcess[]] { const relevant = []; const notRelevant = []; for (const postProcess of postProcesses) { @@ -13,7 +13,7 @@ export function extractRelevantPostProcesses(postProcesses: ObjectPostProcess[], return [relevant, notRelevant]; } -export function makeSplitRenderEffects(name: string, body: AbstractBody, postProcesses: ObjectPostProcess[], engine: Engine): [PostProcessRenderEffect, PostProcessRenderEffect] { +export function makeSplitRenderEffects(name: string, body: AbstractObject, postProcesses: ObjectPostProcess[], engine: Engine): [PostProcessRenderEffect, PostProcessRenderEffect] { const [bodyRings, otherRings] = extractRelevantPostProcesses(postProcesses, body); const otherRingsRenderEffect = new PostProcessRenderEffect(engine, `other${name}RenderEffect`, () => { return otherRings; From 222f6ca3e937811afe4a05cf40cf01ef4ccc090f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 18:00:30 +0100 Subject: [PATCH 57/86] better blacks in starfield --- src/shaders/starfieldFragment.glsl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shaders/starfieldFragment.glsl b/src/shaders/starfieldFragment.glsl index b9aea534d..9d9724a64 100644 --- a/src/shaders/starfieldFragment.glsl +++ b/src/shaders/starfieldFragment.glsl @@ -36,6 +36,7 @@ void main() { acos(rayDir.y) / 3.14159265359 ); vec4 starfieldColor = texture2D(starfieldTexture, starfieldUV); + starfieldColor.rgb = pow(starfieldColor.rgb, vec3(2.0)); // deeper blacks finalColor = vec4(starfieldColor.rgb * visibility, starfieldColor.a); } From ea0f84e742fc5500bd2033c2d0096545d2b143a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 18:01:01 +0100 Subject: [PATCH 58/86] fixed gas planets spawning into stars --- src/ts/model/planemos/gasPlanetModel.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ts/model/planemos/gasPlanetModel.ts b/src/ts/model/planemos/gasPlanetModel.ts index e5b7d3aa2..b19fa06a4 100644 --- a/src/ts/model/planemos/gasPlanetModel.ts +++ b/src/ts/model/planemos/gasPlanetModel.ts @@ -43,6 +43,7 @@ export class GasPlanetModel implements PlanemoModel { const orbitalP = clamp(0.7, 3.0, normalRandom(2.0, 0.3, this.rng, GENERATION_STEPS.ORBIT + 80)); orbitRadius += orbitRadius - getPeriapsis(orbitRadius, orbitalP); + if(parentBody) orbitRadius += parentBody.radius * 1.5; const orbitalPlaneNormal = Vector3.Up().applyRotationQuaternionInPlace(Quaternion.RotationAxis(Axis.X, (this.rng(GENERATION_STEPS.ORBIT + 20) - 0.5) * 0.2)); From 50bf0753feb70bae5229054f33646759e4e31640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 29 Oct 2023 18:01:18 +0100 Subject: [PATCH 59/86] fixed telluric planet spawning into stars --- src/ts/model/planemos/telluricPlanemoModel.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ts/model/planemos/telluricPlanemoModel.ts b/src/ts/model/planemos/telluricPlanemoModel.ts index 760065ade..d3b6a5342 100644 --- a/src/ts/model/planemos/telluricPlanemoModel.ts +++ b/src/ts/model/planemos/telluricPlanemoModel.ts @@ -79,7 +79,7 @@ export class TelluricPlanemoModel implements PlanemoModel { orbitRadius = minRadius * clamp(normalRandom(2.0, 0.3, this.rng, GENERATION_STEPS.ORBIT), 1.2, 3.0); orbitRadius += this.radius * clamp(normalRandom(2, 1, this.rng, GENERATION_STEPS.ORBIT), 1, 20); orbitRadius += 2.0 * Math.max(0, minRadius - getPeriapsis(orbitRadius, orbitalP)); - } + } else if (parentBody) orbitRadius += parentBody.radius * 1.5; this.orbit = { radius: orbitRadius, @@ -113,7 +113,7 @@ export class TelluricPlanemoModel implements PlanemoModel { this.terrainSettings.continents_fragmentation = 0; this.terrainSettings.max_mountain_height = 2e3; } - if(this.isSatelliteOfGas && this.physicalProperties.pressure === 0) { + if (this.isSatelliteOfGas && this.physicalProperties.pressure === 0) { this.terrainSettings.continents_fragmentation = 0; } From daf7f457b6fd4240939e7aa13d3e59385cee9d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 30 Oct 2023 16:02:25 +0100 Subject: [PATCH 60/86] split starsystem class less cluter is always good --- src/ts/blackHoleDemo.ts | 5 +- src/ts/controller/spaceEngine.ts | 3 +- src/ts/controller/starSystem.ts | 176 +----------------- src/ts/controller/starSystemHelper.ts | 169 +++++++++++++++++ src/ts/index.ts | 11 +- .../view/bodies/planemos/telluricPlanemo.ts | 2 +- 6 files changed, 190 insertions(+), 176 deletions(-) create mode 100644 src/ts/controller/starSystemHelper.ts diff --git a/src/ts/blackHoleDemo.ts b/src/ts/blackHoleDemo.ts index c95eef0b7..9a02ff8da 100644 --- a/src/ts/blackHoleDemo.ts +++ b/src/ts/blackHoleDemo.ts @@ -12,6 +12,7 @@ import { SpaceEngine } from "./controller/spaceEngine"; import { ShipController } from "./spaceship/shipController"; import { getRotationQuaternion, setRotationQuaternion } from "./controller/uberCore/transforms/basicTransform"; import { parsePercentageFrom01, parseSpeed } from "./utils/parseToStrings"; +import { StarSystemHelper } from "./controller/starSystemHelper"; const engine = new SpaceEngine(); @@ -63,10 +64,10 @@ const starSystemSeed = randRange(-1, 1, (step: number) => Math.random(), 0); const starSystem = new StarSystem(starSystemSeed, scene); engine.setStarSystem(starSystem, false); -const BH = starSystem.makeBlackHole(0); +const BH = StarSystemHelper.makeBlackHole(starSystem, 0); BH.model.orbit.radius = 0; -const planet = starSystem.makeTelluricPlanet(); +const planet = StarSystemHelper.makeTelluricPlanet(starSystem); planet.model.orbit.radius = 45 * planet.getRadius(); document.addEventListener("keydown", (e) => { diff --git a/src/ts/controller/spaceEngine.ts b/src/ts/controller/spaceEngine.ts index b14cf5f71..3cec0ef90 100644 --- a/src/ts/controller/spaceEngine.ts +++ b/src/ts/controller/spaceEngine.ts @@ -33,6 +33,7 @@ import { OrbitRenderer } from "../view/orbitRenderer"; import { PauseMenu } from "../ui/pauseMenu"; import { AxisRenderer } from "../view/axisRenderer"; import { AbstractBody } from "../view/bodies/abstractBody"; +import { StarSystemHelper } from "./starSystemHelper"; enum EngineState { RUNNING, @@ -311,7 +312,7 @@ export class SpaceEngine { public setStarSystem(starSystem: StarSystem, needsGenerating: boolean): void { this.starSystem?.dispose(); this.starSystem = starSystem; - if (needsGenerating) this.starSystem.generate(); + if (needsGenerating) StarSystemHelper.generate(this.starSystem); } /** diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index eb76a7598..908bd7c48 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -11,31 +11,20 @@ import { PostProcessManager } from "./postProcessManager"; import { StarSystemModel } from "../model/starSystemModel"; import { isOrbiting } from "../utils/nearestBody"; import { NeutronStar } from "../view/bodies/stellarObjects/neutronStar"; -import { BODY_TYPE } from "../model/common"; import { StellarObject } from "../view/bodies/stellarObjects/stellarObject"; import { SpaceStation } from "../view/spaceStation"; import { AbstractObject } from "../view/bodies/abstractObject"; -import { romanNumeral } from "../utils/nameGenerator"; -import { TelluricPlanemoModel } from "../model/planemos/telluricPlanemoModel"; -import { GasPlanetModel } from "../model/planemos/gasPlanetModel"; -import { BlackHoleModel } from "../model/stellarObjects/blackHoleModel"; -import { StarModel } from "../model/stellarObjects/starModel"; import { rotateAround, setUpVector, translate } from "./uberCore/transforms/basicTransform"; -import { MandelbulbModel } from "../model/planemos/mandelbulbModel"; import { Mandelbulb } from "../view/bodies/planemos/mandelbulb"; -import { getMoonSeed } from "../model/planemos/common"; -import { NeutronStarModel } from "../model/stellarObjects/neutronStarModel"; -import { ShipController } from "../spaceship/shipController"; import { Quaternion } from "@babylonjs/core/Maths/math"; import { PostProcessType } from "../view/postProcesses/postProcessTypes"; -import { starName } from "../utils/parseToStrings"; export class StarSystem { - private readonly scene: UberScene; + readonly scene: UberScene; readonly postProcessManager: PostProcessManager; - private readonly starfieldRotation: Quaternion = Quaternion.Identity(); + private readonly universeRotation: Quaternion = Quaternion.Identity(); private readonly orbitalObjects: AbstractObject[] = []; @@ -51,7 +40,6 @@ export class StarSystem { /** * The list of all planemos in the system (planets and satellites) */ - readonly planemos: Planemo[] = []; readonly planemosWithMaterial: PlanemoMaterial[] = []; /** @@ -62,7 +50,7 @@ export class StarSystem { /** * The list of all telluric planets in the system */ - readonly telluricPlanets: TelluricPlanemo[] = []; + readonly telluricPlanemos: TelluricPlanemo[] = []; /** * The list of all gas planets in the system @@ -74,11 +62,6 @@ export class StarSystem { */ readonly mandelbulbs: Mandelbulb[] = []; - /** - * The list of all satellites in the system - */ - readonly satellites: TelluricPlanemo[] = []; - readonly model: StarSystemModel; constructor(model: StarSystemModel | number, scene: UberScene) { @@ -100,10 +83,9 @@ export class StarSystem { this.orbitalObjects.push(planet); this.celestialBodies.push(planet); - this.planemos.push(planet); this.planemosWithMaterial.push(planet); this.planets.push(planet); - this.telluricPlanets.push(planet); + this.telluricPlanemos.push(planet); return planet; } @@ -119,7 +101,6 @@ export class StarSystem { this.orbitalObjects.push(planet); this.celestialBodies.push(planet); - this.planemos.push(planet); this.planemosWithMaterial.push(planet); this.planets.push(planet); this.gasPlanets.push(planet); @@ -138,9 +119,8 @@ export class StarSystem { this.orbitalObjects.push(satellite); this.celestialBodies.push(satellite); - this.planemos.push(satellite); this.planemosWithMaterial.push(satellite); - this.satellites.push(satellite); + this.telluricPlanemos.push(satellite); return satellite; } @@ -152,7 +132,6 @@ export class StarSystem { this.orbitalObjects.push(mandelbulb); this.celestialBodies.push(mandelbulb); - this.planemos.push(mandelbulb); this.mandelbulbs.push(mandelbulb); return mandelbulb; } @@ -179,135 +158,6 @@ export class StarSystem { return spaceStation; } - /** - * Makes a star and adds it to the system. By default, it will use the next available seed planned by the system model - * @param seed The seed to use for the star generation (by default, the next available seed planned by the system model) - */ - public makeStellarObject(seed: number = this.model.getStarSeed(this.stellarObjects.length)): StellarObject { - const isStellarObjectBlackHole = this.model.getBodyTypeOfStar(this.stellarObjects.length) === BODY_TYPE.BLACK_HOLE; - if (isStellarObjectBlackHole) return this.makeBlackHole(seed); - else return this.makeStar(seed); - } - - public makeStar(model: number | StarModel = this.model.getStarSeed(this.stellarObjects.length)): Star { - const name = starName(this.model.getName(), this.stellarObjects.length); - const star = new Star(name, this.scene, model, this.stellarObjects[0]); - this.addStellarObject(star); - return star; - } - - public makeMandelbulb(model: number | MandelbulbModel = this.model.getPlanetSeed(this.mandelbulbs.length)): Mandelbulb { - if (this.planets.length >= this.model.getNbPlanets()) - console.warn(`You are adding a mandelbulb to the system. - The system generator had planned for ${this.model.getNbPlanets()} planets, but you are adding the ${this.planets.length + 1}th planet. - This might cause issues, or not who knows.`); - const mandelbulb = new Mandelbulb(`${this.model.getName()} ${romanNumeral(this.planets.length + 1)}`, this.scene, model, this.stellarObjects[0]); - this.addMandelbulb(mandelbulb); - return mandelbulb; - } - - /** - * Makes a black hole and adds it to the system. By default, it will use the next available model planned by the system - * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) - */ - public makeBlackHole(model: number | BlackHoleModel = this.model.getStarSeed(this.stellarObjects.length)): BlackHole { - const blackHole = new BlackHole(`${this.model.getName()} ${this.stellarObjects.length + 1}`, this.scene, model, this.stellarObjects[0]); - this.addStellarObject(blackHole); - return blackHole; - } - - public makeNeutronStar(model: number | NeutronStarModel = this.model.getStarSeed(this.stellarObjects.length)): NeutronStar { - if (this.stellarObjects.length >= this.model.getNbStars()) - console.warn(`You are adding a neutron star - to a system that already has ${this.stellarObjects.length} stars. - The capacity of the generator was supposed to be ${this.model.getNbStars()} This is not a problem, but it may be.`); - const neutronStar = new NeutronStar(`neutronStar${this.stellarObjects.length}`, this.scene, model, this.stellarObjects[0]); - - this.addStellarObject(neutronStar); - return neutronStar; - } - - /** - * Makes n stars and adds them to the system. By default, it will use the next available seeds planned by the system model - * @param n The number of stars to make (by default, the number of stars planned by the system model) - */ - public makeStellarObjects(n = this.model.getNbStars()): void { - if (n < 1) throw new Error("Cannot make less than 1 star"); - for (let i = 0; i < n; i++) this.makeStellarObject(); - } - - /** - * Makes a telluric planet and adds it to the system. By default, it will use the next available model planned by the system model - * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) - */ - public makeTelluricPlanet(model: number | TelluricPlanemoModel = this.model.getPlanetSeed(this.planets.length)): TelluricPlanemo { - const planet = new TelluricPlanemo(`${this.model.getName()} ${romanNumeral(this.planets.length + 1)}`, this.scene, model, this.stellarObjects[0]); - this.addTelluricPlanet(planet); - return planet; - } - - /** - * Makes a gas planet and adds it to the system. By default, it will use the next available model planned by the system model - * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) - */ - public makeGasPlanet(model: number | GasPlanetModel = this.model.getPlanetSeed(this.planets.length)): GasPlanet { - const planet = new GasPlanet(`${this.model.getName()} ${romanNumeral(this.planets.length + 1)}`, this.scene, model, this.stellarObjects[0]); - this.addGasPlanet(planet); - return planet; - } - - public makePlanets(n: number): void { - console.assert(n >= 0, `Cannot make a negative amount of planets : ${n}`); - - for (let i = 0; i < n; i++) { - switch (this.model.getBodyTypeOfPlanet(this.planets.length)) { - case BODY_TYPE.TELLURIC: - this.makeSatellites(this.makeTelluricPlanet()); - break; - case BODY_TYPE.GAS: - this.makeSatellites(this.makeGasPlanet()); - break; - case BODY_TYPE.MANDELBULB: - this.makeSatellites(this.makeMandelbulb()); - break; - default: - throw new Error(`Unknown body type ${this.model.getBodyTypeOfPlanet(this.planets.length)}`); - } - } - } - - public makeSatellite(planet: Planemo, model: TelluricPlanemoModel | number = getMoonSeed(planet.model, planet.model.childrenBodies.length)): TelluricPlanemo { - const satellite = new TelluricPlanemo(`${planet.name} ${romanNumeral(planet.model.childrenBodies.length + 1)}`, this.scene, model, planet); - - satellite.material.colorSettings.desertColor.copyFromFloats(92 / 255, 92 / 255, 92 / 255); - satellite.material.updateConstants(); - - planet.model.childrenBodies.push(satellite.model); - - this.addTelluricSatellite(satellite); - return satellite; - } - - /** - * Makes n more satellites for the given planet. By default, it will make as many as the planet has in the generation. - * You can make more, but it will generate warnings and might cause issues. - * @param planet The planet to make satellites for - * @param n The number of satellites to make - */ - public makeSatellites(planet: Planemo, n = planet.model.nbMoons): void { - if (n < 0) throw new Error(`Cannot make a negative amount of satellites : ${n}`); - if (planet.model.childrenBodies.length + n > planet.model.nbMoons) - console.warn( - `You are making more satellites than the planet had planned in its the generation: - You want ${n} more which will amount to a total ${planet.model.childrenBodies.length + n}. - The generator had planned ${planet.model.nbMoons}. - This might cause issues, or not who knows. - You can just leave this argument empty to make as many as the planet had planned.` - ); - - for (let i = 0; i < n; i++) this.makeSatellite(planet, getMoonSeed(planet.model, planet.model.childrenBodies.length)); - } - /** * Translates all celestial bodies and spacestations in the system by the given displacement * @param displacement The displacement applied to all bodies @@ -397,7 +247,7 @@ export class StarSystem { * @private */ private initPostProcesses() { - this.postProcessManager.addStarField(this.stellarObjects, this.celestialBodies, this.starfieldRotation); + this.postProcessManager.addStarField(this.stellarObjects, this.celestialBodies, this.universeRotation); for (const object of this.orbitalObjects) { for (const postProcess of object.postProcesses) { switch (postProcess) { @@ -431,7 +281,7 @@ export class StarSystem { break; case PostProcessType.BLACK_HOLE: if (!(object instanceof BlackHole)) throw new Error("Black hole post process can only be added to black holes. Source:" + object.name); - this.postProcessManager.addBlackHole(object as BlackHole, this.starfieldRotation); + this.postProcessManager.addBlackHole(object as BlackHole, this.universeRotation); break; case PostProcessType.MATTER_JETS: if (!(object instanceof NeutronStar)) throw new Error("Matter jets post process can only be added to neutron stars. Source:" + object.name); @@ -508,7 +358,7 @@ export class StarSystem { if (shouldCompensateRotation) { // the starfield is rotated to give the impression the nearest body is rotating, which is not the case const starfieldAdditionalRotation = Quaternion.RotationAxis(nearestBody.getRotationAxis(), dthetaNearest); - this.starfieldRotation.copyFrom(starfieldAdditionalRotation.multiply(this.starfieldRotation)); + this.universeRotation.copyFrom(starfieldAdditionalRotation.multiply(this.universeRotation)); } // finally, all other objects are updated normally @@ -522,7 +372,7 @@ export class StarSystem { controller.update(deltaTime); - for (const body of this.telluricPlanets.concat(this.satellites)) { + for (const body of this.telluricPlanemos) { // Meshes with LOD are updated (surface quadtrees) body.updateLOD(controller.getTransform().getAbsolutePosition()); } @@ -562,14 +412,6 @@ export class StarSystem { this.postProcessManager.update(deltaTime); } - /** - * Generates the system using the seed provided in the constructor - */ - public generate() { - this.makeStellarObjects(this.model.getNbStars()); - this.makePlanets(this.model.getNbPlanets()); - } - public dispose() { this.postProcessManager.dispose(); for (const spacestation of this.spaceStations) spacestation.dispose(); diff --git a/src/ts/controller/starSystemHelper.ts b/src/ts/controller/starSystemHelper.ts new file mode 100644 index 000000000..a58df85a9 --- /dev/null +++ b/src/ts/controller/starSystemHelper.ts @@ -0,0 +1,169 @@ +import { StarModel } from "../model/stellarObjects/starModel"; +import { Star } from "../view/bodies/stellarObjects/star"; +import { starName } from "../utils/parseToStrings"; +import { MandelbulbModel } from "../model/planemos/mandelbulbModel"; +import { Mandelbulb } from "../view/bodies/planemos/mandelbulb"; +import { romanNumeral } from "../utils/nameGenerator"; +import { BlackHoleModel } from "../model/stellarObjects/blackHoleModel"; +import { BlackHole } from "../view/bodies/stellarObjects/blackHole"; +import { NeutronStarModel } from "../model/stellarObjects/neutronStarModel"; +import { NeutronStar } from "../view/bodies/stellarObjects/neutronStar"; +import { TelluricPlanemoModel } from "../model/planemos/telluricPlanemoModel"; +import { TelluricPlanemo } from "../view/bodies/planemos/telluricPlanemo"; +import { GasPlanetModel } from "../model/planemos/gasPlanetModel"; +import { GasPlanet } from "../view/bodies/planemos/gasPlanet"; +import { BODY_TYPE } from "../model/common"; +import { Planemo } from "../view/bodies/planemos/planemo"; +import { getMoonSeed } from "../model/planemos/common"; +import { StarSystem } from "./starSystem"; +import { StellarObject } from "../view/bodies/stellarObjects/stellarObject"; + +export class StarSystemHelper { + public static makeStar(starsystem: StarSystem, model?: number | StarModel): Star { + if(model === undefined) { + model = starsystem.model.getStarSeed(starsystem.stellarObjects.length); + } + const name = starName(starsystem.model.getName(), starsystem.stellarObjects.length); + const star = new Star(name, starsystem.scene, model, starsystem.stellarObjects[0]); + starsystem.addStellarObject(star); + return star; + } + + public static makeMandelbulb(starsystem: StarSystem, model: number | MandelbulbModel = starsystem.model.getPlanetSeed(starsystem.mandelbulbs.length)): Mandelbulb { + if (starsystem.planets.length >= starsystem.model.getNbPlanets()) + console.warn(`You are adding a mandelbulb to the system. + The system generator had planned for ${starsystem.model.getNbPlanets()} planets, but you are adding the ${starsystem.planets.length + 1}th planet. + starsystem might cause issues, or not who knows.`); + const mandelbulb = new Mandelbulb(`${starsystem.model.getName()} ${romanNumeral(starsystem.planets.length + 1)}`, starsystem.scene, model, starsystem.stellarObjects[0]); + starsystem.addMandelbulb(mandelbulb); + return mandelbulb; + } + + /** + * Makes a black hole and adds it to the system. By default, it will use the next available model planned by the system + * @param starsystem + * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) + */ + public static makeBlackHole(starsystem: StarSystem, model: number | BlackHoleModel = starsystem.model.getStarSeed(starsystem.stellarObjects.length)): BlackHole { + const name = starName(starsystem.model.getName(), starsystem.stellarObjects.length); + const blackHole = new BlackHole(name, starsystem.scene, model, starsystem.stellarObjects[0]); + starsystem.addStellarObject(blackHole); + return blackHole; + } + + public static makeNeutronStar(starsystem: StarSystem, model: number | NeutronStarModel = starsystem.model.getStarSeed(starsystem.stellarObjects.length)): NeutronStar { + if (starsystem.stellarObjects.length >= starsystem.model.getNbStars()) + console.warn(`You are adding a neutron star + to a system that already has ${starsystem.stellarObjects.length} stars. + The capacity of the generator was supposed to be ${starsystem.model.getNbStars()} starsystem is not a problem, but it may be.`); + const name = starName(starsystem.model.getName(), starsystem.stellarObjects.length); + const neutronStar = new NeutronStar(name, starsystem.scene, model, starsystem.stellarObjects[0]); + + starsystem.addStellarObject(neutronStar); + return neutronStar; + } + + /** + * Makes a star and adds it to the system. By default, it will use the next available seed planned by the system model + * @param starsystem + * @param seed The seed to use for the star generation (by default, the next available seed planned by the system model) + */ + public static makeStellarObject(starsystem: StarSystem, seed: number = starsystem.model.getStarSeed(starsystem.stellarObjects.length)): StellarObject { + const isStellarObjectBlackHole = starsystem.model.getBodyTypeOfStar(starsystem.stellarObjects.length) === BODY_TYPE.BLACK_HOLE; + if (isStellarObjectBlackHole) return StarSystemHelper.makeBlackHole(starsystem, seed); + else return this.makeStar(starsystem, seed); + } + + /** + * Makes n stars and adds them to the system. By default, it will use the next available seeds planned by the system model + * @param starsystem + * @param n The number of stars to make (by default, the number of stars planned by the system model) + */ + public static makeStellarObjects(starsystem: StarSystem, n = starsystem.model.getNbStars()): void { + if (n < 1) throw new Error("Cannot make less than 1 star"); + for (let i = 0; i < n; i++) StarSystemHelper.makeStellarObject(starsystem); + } + + /** + * Makes a telluric planet and adds it to the system. By default, it will use the next available model planned by the system model + * @param starsystem + * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) + */ + public static makeTelluricPlanet(starsystem: StarSystem, model: number | TelluricPlanemoModel = starsystem.model.getPlanetSeed(starsystem.planets.length)): TelluricPlanemo { + const planet = new TelluricPlanemo(`${starsystem.model.getName()} ${romanNumeral(starsystem.planets.length + 1)}`, starsystem.scene, model, starsystem.stellarObjects[0]); + starsystem.addTelluricPlanet(planet); + return planet; + } + + /** + * Makes a gas planet and adds it to the system. By default, it will use the next available model planned by the system model + * @param starsystem + * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) + */ + public static makeGasPlanet(starsystem: StarSystem, model: number | GasPlanetModel = starsystem.model.getPlanetSeed(starsystem.planets.length)): GasPlanet { + const planet = new GasPlanet(`${starsystem.model.getName()} ${romanNumeral(starsystem.planets.length + 1)}`, starsystem.scene, model, starsystem.stellarObjects[0]); + starsystem.addGasPlanet(planet); + return planet; + } + + public static makePlanets(starsystem: StarSystem, n: number): void { + console.assert(n >= 0, `Cannot make a negative amount of planets : ${n}`); + + for (let i = 0; i < n; i++) { + switch (starsystem.model.getBodyTypeOfPlanet(starsystem.planets.length)) { + case BODY_TYPE.TELLURIC: + StarSystemHelper.makeSatellites(starsystem, StarSystemHelper.makeTelluricPlanet(starsystem)); + break; + case BODY_TYPE.GAS: + StarSystemHelper.makeSatellites(starsystem, StarSystemHelper.makeGasPlanet(starsystem)); + break; + case BODY_TYPE.MANDELBULB: + StarSystemHelper.makeSatellites(starsystem, StarSystemHelper.makeMandelbulb(starsystem)); + break; + default: + throw new Error(`Unknown body type ${starsystem.model.getBodyTypeOfPlanet(starsystem.planets.length)}`); + } + } + } + + public static makeSatellite(starsystem: StarSystem, planet: Planemo, model: TelluricPlanemoModel | number = getMoonSeed(planet.model, planet.model.childrenBodies.length)): TelluricPlanemo { + const satellite = new TelluricPlanemo(`${planet.name} ${romanNumeral(planet.model.childrenBodies.length + 1)}`, starsystem.scene, model, planet); + + satellite.material.colorSettings.desertColor.copyFromFloats(92 / 255, 92 / 255, 92 / 255); + satellite.material.updateConstants(); + + planet.model.childrenBodies.push(satellite.model); + + starsystem.addTelluricSatellite(satellite); + return satellite; + } + + /** + * Makes n more satellites for the given planet. By default, it will make as many as the planet has in the generation. + * You can make more, but it will generate warnings and might cause issues. + * @param starsystem + * @param planet The planet to make satellites for + * @param n The number of satellites to make + */ + public static makeSatellites(starsystem: StarSystem, planet: Planemo, n = planet.model.nbMoons): void { + if (n < 0) throw new Error(`Cannot make a negative amount of satellites : ${n}`); + if (planet.model.childrenBodies.length + n > planet.model.nbMoons) + console.warn( + `You are making more satellites than the planet had planned in its the generation: + You want ${n} more which will amount to a total ${planet.model.childrenBodies.length + n}. + The generator had planned ${planet.model.nbMoons}. + starsystem might cause issues, or not who knows. + You can just leave starsystem argument empty to make as many as the planet had planned.` + ); + + for (let i = 0; i < n; i++) StarSystemHelper.makeSatellite(starsystem, planet, getMoonSeed(planet.model, planet.model.childrenBodies.length)); + } + + /** + * Generates the system using the seed provided in the constructor + */ + public static generate(starsystem: StarSystem) { + StarSystemHelper.makeStellarObjects(starsystem, starsystem.model.getNbStars()); + StarSystemHelper.makePlanets(starsystem, starsystem.model.getNbPlanets()); + } +} \ No newline at end of file diff --git a/src/ts/index.ts b/src/ts/index.ts index b583c9e49..fcc32df40 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -24,6 +24,7 @@ import { parsePercentageFrom01, parseSpeed } from "./utils/parseToStrings"; import { getMoonSeed } from "./model/planemos/common"; import { RingsUniforms } from "./model/ringsUniform"; import { StarModel } from "./model/stellarObjects/starModel"; +import { StarSystemHelper } from "./controller/starSystemHelper"; const engine = new SpaceEngine(); @@ -94,7 +95,7 @@ starSystem.model.setName("Alpha Testis"); engine.setStarSystem(starSystem, false); const sunModel = new StarModel(0.51); -const sun = starSystem.makeStar(sunModel); +const sun = StarSystemHelper.makeStar(starSystem, sunModel); sun.model.orbit.period = 60 * 60 * 24; /*const secundaModel = new StarModel(-672446, sunModel); @@ -110,7 +111,7 @@ planetModel.orbit.period = 60 * 60 * 24 * 365.25; planetModel.orbit.radius = 4000 * planetModel.radius; planetModel.orbit.normalToPlane = Vector3.Up(); -const planet = starSystem.makeTelluricPlanet(planetModel); +const planet = StarSystemHelper.makeTelluricPlanet(starSystem, planetModel); planet.model.ringsUniforms = new RingsUniforms(planet.model.rng); planet.postProcesses.push(PostProcessType.RING); @@ -128,7 +129,7 @@ moonModel.orbit.period = moonModel.physicalProperties.rotationPeriod; moonModel.orbit.radius = 8 * planet.getRadius(); moonModel.orbit.normalToPlane = Vector3.Up(); -const moon = starSystem.makeSatellite(planet, moonModel); +const moon = StarSystemHelper.makeSatellite(starSystem, planet, moonModel); moon.material.colorSettings.plainColor.copyFromFloats(0.67, 0.67, 0.67); moon.material.colorSettings.desertColor.copyFrom(new Color3(116, 134, 121).scale(1 / 255)); @@ -155,7 +156,7 @@ aresModel.terrainSettings.continents_fragmentation = 0.0; aresModel.terrainSettings.continent_base_height = 10e3; aresModel.terrainSettings.max_mountain_height = 20e3; -const ares = starSystem.makeTelluricPlanet(aresModel); +const ares = StarSystemHelper.makeTelluricPlanet(starSystem, aresModel); ares.postProcesses.splice(ares.postProcesses.indexOf(PostProcessType.OCEAN), 1); ares.postProcesses.splice(ares.postProcesses.indexOf(PostProcessType.CLOUDS), 1); @@ -172,7 +173,7 @@ andromaqueModel.orbit.period = 60 * 60 * 24 * 365.25; andromaqueModel.orbit.radius = 4300 * ares.getRadius(); andromaqueModel.orbit.normalToPlane = Vector3.Up(); -const andromaque = starSystem.makeGasPlanet(andromaqueModel); +const andromaque = StarSystemHelper.makeGasPlanet(starSystem, andromaqueModel); /*const blackHoleModel = new BlackHoleModel(0.5, sunModel); blackHoleModel.orbit.period = 60 * 60 * 24 * 365.25; diff --git a/src/ts/view/bodies/planemos/telluricPlanemo.ts b/src/ts/view/bodies/planemos/telluricPlanemo.ts index 025d8ce1e..0e3315985 100644 --- a/src/ts/view/bodies/planemos/telluricPlanemo.ts +++ b/src/ts/view/bodies/planemos/telluricPlanemo.ts @@ -31,8 +31,8 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat * New Telluric Planet * @param name The name of the planet * @param scene - * @param parentBodies The bodies the planet is orbiting * @param model The model to build the planet or a seed for the planet in [-1, 1] + * @param parentBody */ constructor(name: string, scene: UberScene, model: TelluricPlanemoModel | number, parentBody?: AbstractBody) { super(name, scene, parentBody); From 1b3d70b03e48ccd6965b635b9a9af18d56493b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 30 Oct 2023 16:02:39 +0100 Subject: [PATCH 61/86] went back to 1:6 scale for now --- src/ts/model/planemos/telluricPlanemoModel.ts | 2 +- src/ts/settings.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ts/model/planemos/telluricPlanemoModel.ts b/src/ts/model/planemos/telluricPlanemoModel.ts index d3b6a5342..9b793bb64 100644 --- a/src/ts/model/planemos/telluricPlanemoModel.ts +++ b/src/ts/model/planemos/telluricPlanemoModel.ts @@ -106,7 +106,7 @@ export class TelluricPlanemoModel implements PlanemoModel { max_mountain_height: 10e3, continent_base_height: this.physicalProperties.oceanLevel * 1.9, - mountains_frequency: (6 * (20 * this.radius)) / Settings.EARTH_RADIUS + mountains_frequency: (20 * this.radius) / 1000e3 }; if (this.isSatelliteOfTelluric) { diff --git a/src/ts/settings.ts b/src/ts/settings.ts index 041b9a82d..0b0a22306 100644 --- a/src/ts/settings.ts +++ b/src/ts/settings.ts @@ -1,6 +1,6 @@ export const Settings = { UNIVERSE_SEED: Math.PI, - EARTH_RADIUS: 6000e3, // target is 6000e3 + EARTH_RADIUS: 1000e3, // target is 6000e3 AU: 150e9, // target is 150e9 VERTEX_RESOLUTION: 64, CLOUD_LAYER_HEIGHT: 15e3, From 25053104cd7c1231bf653270423b1a24815e0264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 30 Oct 2023 16:06:26 +0100 Subject: [PATCH 62/86] deeper black --- src/shaders/starfieldFragment.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shaders/starfieldFragment.glsl b/src/shaders/starfieldFragment.glsl index 9d9724a64..7a78e6302 100644 --- a/src/shaders/starfieldFragment.glsl +++ b/src/shaders/starfieldFragment.glsl @@ -36,7 +36,7 @@ void main() { acos(rayDir.y) / 3.14159265359 ); vec4 starfieldColor = texture2D(starfieldTexture, starfieldUV); - starfieldColor.rgb = pow(starfieldColor.rgb, vec3(2.0)); // deeper blacks + starfieldColor.rgb = pow(starfieldColor.rgb, vec3(2.2)); // deeper blacks finalColor = vec4(starfieldColor.rgb * visibility, starfieldColor.a); } From b6ebcf44c2c6159005748067f3c43055b06e2076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 31 Oct 2023 12:13:09 +0100 Subject: [PATCH 63/86] fixed black hole The deeper blacks were not accounted for in the blackhole + starmap does not need to showup on blackhole demo --- src/shaders/blackhole.glsl | 1 + src/ts/blackHoleDemo.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/shaders/blackhole.glsl b/src/shaders/blackhole.glsl index f268135f6..bd27b2322 100644 --- a/src/shaders/blackhole.glsl +++ b/src/shaders/blackhole.glsl @@ -251,6 +251,7 @@ void main() { acos(rayDir.y) / 3.14159265359 ); bg = texture2D(starfieldTexture, starfieldUV); + bg.rgb = pow(bg.rgb, vec3(2.2)); } vec4 finalColor = vec4(1.0, 0.0, 0.0, 1.0); diff --git a/src/ts/blackHoleDemo.ts b/src/ts/blackHoleDemo.ts index 9a02ff8da..36f28b204 100644 --- a/src/ts/blackHoleDemo.ts +++ b/src/ts/blackHoleDemo.ts @@ -91,3 +91,5 @@ document.addEventListener("keydown", (e) => { engine.init(); positionNearObject(scene.getActiveController(), BH, starSystem, 20); + +engine.toggleStarMap(); From 10c290057b5f8dc56790dd4d46272c2b776e0852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 31 Oct 2023 14:15:59 +0100 Subject: [PATCH 64/86] removed any mention of logdepth --- src/shaders/gasPlanetMaterial/fragment.glsl | 8 -------- src/shaders/gasPlanetMaterial/vertex.glsl | 9 --------- src/shaders/starMaterial/fragment.glsl | 8 -------- src/shaders/starMaterial/vertex.glsl | 9 --------- src/shaders/telluricPlanetMaterial/fragment.glsl | 8 -------- src/shaders/telluricPlanetMaterial/vertex.glsl | 9 --------- src/ts/controller/assets.ts | 9 --------- src/ts/controller/spaceEngine.ts | 1 + src/ts/spaceship/abstractThruster.ts | 1 - src/ts/utils/particleSystem.ts | 1 - src/ts/view/axisRenderer.ts | 1 - src/ts/view/materials/gasPlanetMaterial.ts | 10 +--------- src/ts/view/materials/starMaterial.ts | 8 +------- src/ts/view/materials/telluricPlanemoMaterial.ts | 8 -------- src/ts/view/orbitRenderer.ts | 1 - 15 files changed, 3 insertions(+), 88 deletions(-) diff --git a/src/shaders/gasPlanetMaterial/fragment.glsl b/src/shaders/gasPlanetMaterial/fragment.glsl index 990e59f37..3c61517ce 100644 --- a/src/shaders/gasPlanetMaterial/fragment.glsl +++ b/src/shaders/gasPlanetMaterial/fragment.glsl @@ -1,10 +1,5 @@ precision highp float; -#ifdef LOGARITHMICDEPTH -uniform float logarithmicDepthConstant; -in float vFragmentDepth; -#endif - #define MAX_STARS 5 uniform int nbStars;// number of stars struct Star { @@ -84,7 +79,4 @@ void main() { vec3 screenColor = color.rgb * (ndl + specComp * ndl); gl_FragColor = vec4(screenColor, 1.0);// apply color and lighting - #ifdef LOGARITHMICDEPTH - gl_FragDepthEXT = log2(vFragmentDepth) * logarithmicDepthConstant * 0.5; - #endif } diff --git a/src/shaders/gasPlanetMaterial/vertex.glsl b/src/shaders/gasPlanetMaterial/vertex.glsl index 18f13dc5e..eeb58709a 100644 --- a/src/shaders/gasPlanetMaterial/vertex.glsl +++ b/src/shaders/gasPlanetMaterial/vertex.glsl @@ -3,11 +3,6 @@ precision highp float; attribute vec3 position; attribute vec3 normal; -#ifdef LOGARITHMICDEPTH -uniform float logarithmicDepthConstant; -out float vFragmentDepth; -#endif - uniform mat4 world; uniform mat4 worldViewProjection; uniform mat4 normalMatrix; @@ -23,10 +18,6 @@ void main() { vec4 outPosition = worldViewProjection * vec4(position, 1.0); gl_Position = outPosition; - #ifdef LOGARITHMICDEPTH - vFragmentDepth = 1.0 + gl_Position.w; - gl_Position.z = log2(max(0.000001, vFragmentDepth)) * logarithmicDepthConstant; - #endif vPositionW = vec3(world * vec4(position, 1.0)); diff --git a/src/shaders/starMaterial/fragment.glsl b/src/shaders/starMaterial/fragment.glsl index 9eab0e903..92c85af40 100644 --- a/src/shaders/starMaterial/fragment.glsl +++ b/src/shaders/starMaterial/fragment.glsl @@ -3,11 +3,6 @@ precision highp float; in vec3 vPosition;// position of the vertex in sphere space in vec3 vUnitSamplePoint; -#ifdef LOGARITHMICDEPTH -uniform float logarithmicDepthConstant; -in float vFragmentDepth; -#endif - uniform vec3 starColor; uniform float time; @@ -28,7 +23,4 @@ void main() { finalColor -= vec3(pow(noiseValue, 4.0)); gl_FragColor = vec4(finalColor, 1.0);// apply color and lighting - #ifdef LOGARITHMICDEPTH - gl_FragDepthEXT = log2(vFragmentDepth) * logarithmicDepthConstant * 0.5; - #endif } \ No newline at end of file diff --git a/src/shaders/starMaterial/vertex.glsl b/src/shaders/starMaterial/vertex.glsl index e87bfeddd..efa8a3229 100644 --- a/src/shaders/starMaterial/vertex.glsl +++ b/src/shaders/starMaterial/vertex.glsl @@ -2,11 +2,6 @@ precision highp float; attribute vec3 position; -#ifdef LOGARITHMICDEPTH - uniform float logarithmicDepthConstant; - out float vFragmentDepth; -#endif - uniform mat4 world; uniform mat4 worldViewProjection; @@ -23,10 +18,6 @@ void main() { vec4 outPosition = worldViewProjection * vec4(position, 1.0); gl_Position = outPosition; - #ifdef LOGARITHMICDEPTH - vFragmentDepth = 1.0 + gl_Position.w; - gl_Position.z = log2(max(0.000001, vFragmentDepth)) * logarithmicDepthConstant; - #endif vPositionW = vec3(world * vec4(position, 1.0)); diff --git a/src/shaders/telluricPlanetMaterial/fragment.glsl b/src/shaders/telluricPlanetMaterial/fragment.glsl index 7dd0dee3f..202fa37cc 100644 --- a/src/shaders/telluricPlanetMaterial/fragment.glsl +++ b/src/shaders/telluricPlanetMaterial/fragment.glsl @@ -1,10 +1,5 @@ precision highp float; -#ifdef LOGARITHMICDEPTH -uniform float logarithmicDepthConstant; -in float vFragmentDepth; -#endif - in vec3 vPositionW; in vec3 vNormalW; in vec3 vUnitSamplePoint; @@ -283,7 +278,4 @@ void main() { gl_FragColor = vec4(screenColor, 1.0);// apply color and lighting - #ifdef LOGARITHMICDEPTH - gl_FragDepthEXT = log2(vFragmentDepth) * logarithmicDepthConstant * 0.5; - #endif } \ No newline at end of file diff --git a/src/shaders/telluricPlanetMaterial/vertex.glsl b/src/shaders/telluricPlanetMaterial/vertex.glsl index 2e41e3537..ddc74c8b6 100644 --- a/src/shaders/telluricPlanetMaterial/vertex.glsl +++ b/src/shaders/telluricPlanetMaterial/vertex.glsl @@ -3,11 +3,6 @@ precision highp float; attribute vec3 position; attribute vec3 normal; -#ifdef LOGARITHMICDEPTH - uniform float logarithmicDepthConstant; - out float vFragmentDepth; -#endif - uniform mat4 world; uniform mat4 worldViewProjection; uniform mat4 normalMatrix; @@ -33,10 +28,6 @@ void main() { vec4 outPosition = worldViewProjection * vec4(position, 1.0); gl_Position = outPosition; - #ifdef LOGARITHMICDEPTH - vFragmentDepth = 1.0 + gl_Position.w; - gl_Position.z = log2(max(0.000001, vFragmentDepth)) * logarithmicDepthConstant; - #endif vPositionW = vec3(world * vec4(position, 1.0)); vNormalW = normalize(mat3(normalMatrix) * normal); diff --git a/src/ts/controller/assets.ts b/src/ts/controller/assets.ts index a28568a42..5a688a168 100644 --- a/src/ts/controller/assets.ts +++ b/src/ts/controller/assets.ts @@ -109,8 +109,6 @@ export class Assets { for (const mesh of Assets.Spaceship.getChildMeshes()) { mesh.isVisible = false; - const pbr = mesh.material as PBRBaseMaterial; - pbr.useLogarithmicDepth = true; } console.log("Spaceship loaded"); @@ -122,8 +120,6 @@ export class Assets { for (const mesh of Assets.EndeavorSpaceship.getChildMeshes()) { mesh.isVisible = false; - const pbr = mesh.material as PBRBaseMaterial; - pbr.useLogarithmicDepth = true; } console.log("Endeavor Spaceship loaded"); @@ -135,8 +131,6 @@ export class Assets { for (const mesh of Assets.Spacestation.getChildMeshes()) { mesh.isVisible = false; - const pbr = mesh.material as PBRBaseMaterial; - pbr.useLogarithmicDepth = true; //pbr._reflectionTexture = new Texture(starfield, scene); //pbr._reflectionTexture.coordinatesMode = Texture.SPHERICAL_MODE; } @@ -151,8 +145,6 @@ export class Assets { for (const mesh of Assets.Banana.getChildMeshes()) { mesh.isVisible = false; - const pbr = mesh.material as PBRBaseMaterial; - pbr.useLogarithmicDepth = true; } console.log("Banana loaded"); @@ -222,7 +214,6 @@ export class Assets { if (!diffuse) mat.emissiveColor = Color3.Random(); else mat.diffuseColor = Color3.Random(); mat.wireframe = wireframe; - mat.useLogarithmicDepth = true; return mat; } } diff --git a/src/ts/controller/spaceEngine.ts b/src/ts/controller/spaceEngine.ts index 3cec0ef90..cc7309320 100644 --- a/src/ts/controller/spaceEngine.ts +++ b/src/ts/controller/spaceEngine.ts @@ -206,6 +206,7 @@ export class SpaceEngine { */ public async setup(): Promise { this.engine = new Engine(this.canvas); //await EngineFactory.CreateAsync(this.canvas, { enableAllFeatures: true }); + this.engine.useReverseDepthBuffer = true; this.engine.loadingScreen.displayLoadingUI(); diff --git a/src/ts/spaceship/abstractThruster.ts b/src/ts/spaceship/abstractThruster.ts index fcb4284d0..ebafcfeab 100644 --- a/src/ts/spaceship/abstractThruster.ts +++ b/src/ts/spaceship/abstractThruster.ts @@ -38,7 +38,6 @@ export abstract class AbstractThruster { const cubeMaterial = new StandardMaterial("cubeMat", mesh.getScene()); cubeMaterial.diffuseColor = Color3.White(); cubeMaterial.emissiveColor = Color3.White(); - cubeMaterial.useLogarithmicDepth = true; thrusterHelper.material = cubeMaterial; thrusterHelper.parent = mesh; diff --git a/src/ts/utils/particleSystem.ts b/src/ts/utils/particleSystem.ts index 216e62c93..410882bdf 100644 --- a/src/ts/utils/particleSystem.ts +++ b/src/ts/utils/particleSystem.ts @@ -32,7 +32,6 @@ export class DirectionnalParticleSystem extends ParticleSystem { this.emitter = mesh; this.minSize = 0.6; this.maxSize = 0.7; - this.useLogarithmicDepth = true; this.minLifeTime = 0.5; this.maxLifeTime = 0.6; this.minEmitPower = 0; diff --git a/src/ts/view/axisRenderer.ts b/src/ts/view/axisRenderer.ts index a3f7c17e9..9bb3b54f3 100644 --- a/src/ts/view/axisRenderer.ts +++ b/src/ts/view/axisRenderer.ts @@ -52,6 +52,5 @@ export class AxisRenderer { this.axisMaterial = new StandardMaterial("axisMaterial"); this.axisMaterial.emissiveColor = Color3.White(); this.axisMaterial.disableLighting = true; - this.axisMaterial.useLogarithmicDepth = true; } } diff --git a/src/ts/view/materials/gasPlanetMaterial.ts b/src/ts/view/materials/gasPlanetMaterial.ts index 80ce08bd6..29bff87bf 100644 --- a/src/ts/view/materials/gasPlanetMaterial.ts +++ b/src/ts/view/materials/gasPlanetMaterial.ts @@ -45,11 +45,8 @@ export class GasPlanetMaterial extends ShaderMaterial { "time", - "playerPosition", - - "logarithmicDepthConstant" + "playerPosition" ], - defines: ["#define LOGARITHMICDEPTH"] }); this.planet = planet; @@ -70,11 +67,6 @@ export class GasPlanetMaterial extends ShaderMaterial { colorSharpness: randRangeInt(40, 80, model.rng, 80) / 10 }; - this.onBindObservable.add(() => { - const effect = this.getEffect(); - MaterialHelper.BindLogDepth(null, effect, scene); - }); - this.setFloat("seed", model.seed); this.setColor3("color1", this.colorSettings.color1); diff --git a/src/ts/view/materials/starMaterial.ts b/src/ts/view/materials/starMaterial.ts index 87b1205d9..a808099e1 100644 --- a/src/ts/view/materials/starMaterial.ts +++ b/src/ts/view/materials/starMaterial.ts @@ -19,17 +19,11 @@ export class StarMaterial extends ShaderMaterial { constructor(star: TransformNode, model: StarModel, scene: Scene) { super("starColor", scene, shaderName, { attributes: ["position"], - uniforms: ["world", "worldViewProjection", "seed", "starColor", "starPosition", "starInverseRotationQuaternion", "time", "logarithmicDepthConstant"], - //defines: ["#define LOGARITHMICDEPTH"] + uniforms: ["world", "worldViewProjection", "seed", "starColor", "starPosition", "starInverseRotationQuaternion", "time"], }); this.star = star; this.starModel = model; this.starSeed = model.seed; - - /*this.onBindObservable.add(() => { - const effect = this.getEffect(); - MaterialHelper.BindLogDepth(null, effect, scene); - });*/ } public update(internalTime: number) { diff --git a/src/ts/view/materials/telluricPlanemoMaterial.ts b/src/ts/view/materials/telluricPlanemoMaterial.ts index 4f30c6b83..0987e328d 100644 --- a/src/ts/view/materials/telluricPlanemoMaterial.ts +++ b/src/ts/view/materials/telluricPlanemoMaterial.ts @@ -81,10 +81,7 @@ export class TelluricPlanemoMaterial extends ShaderMaterial { "pressure", "waterAmount", - - "logarithmicDepthConstant" ], - defines: ["#define LOGARITHMICDEPTH"] }); this.planet = planet; @@ -115,11 +112,6 @@ export class TelluricPlanemoMaterial extends ShaderMaterial { this.colorSettings.plainColor = this.colorSettings.desertColor.scale(0.7); } - this.onBindObservable.add(() => { - const effect = this.getEffect(); - MaterialHelper.BindLogDepth(null, effect, scene); - }); - this.setFloat("seed", model.seed); if (!Assets.IS_READY) throw new Error("You must initialize your assets using the AssetsManager"); diff --git a/src/ts/view/orbitRenderer.ts b/src/ts/view/orbitRenderer.ts index 6e422c628..82b355071 100644 --- a/src/ts/view/orbitRenderer.ts +++ b/src/ts/view/orbitRenderer.ts @@ -76,6 +76,5 @@ export class OrbitRenderer { this.orbitMaterial = new StandardMaterial("orbitMaterial"); this.orbitMaterial.emissiveColor = Color3.White(); this.orbitMaterial.disableLighting = true; - this.orbitMaterial.useLogarithmicDepth = true; } } From 79ac9dbe906881921d2258bb674be1954fbb50c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 31 Oct 2023 19:57:14 +0100 Subject: [PATCH 65/86] Fixed unprojection The reverse screen projection is now solved thanks to the awesome discussion at https://forum.babylonjs.com/t/reverse-depth-buffer-question/45318 --- src/shaders/utils/worldFromUV.glsl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shaders/utils/worldFromUV.glsl b/src/shaders/utils/worldFromUV.glsl index a778d1ada..7088f6840 100644 --- a/src/shaders/utils/worldFromUV.glsl +++ b/src/shaders/utils/worldFromUV.glsl @@ -1,7 +1,9 @@ // compute the world position of a pixel from its uv coordinates +// This is an evolution from the code found here // https://forum.babylonjs.com/t/pixel-position-in-world-space-from-fragment-postprocess-shader-issue/30232 +// This is a revised version that works with the reverse depth buffer vec3 worldFromUV(vec2 pos) { - vec4 ndc = vec4(pos.xy * 2.0 - 1.0, -1.0, 1.0); // get ndc position -1 because i want every point in the near camera plane + vec4 ndc = vec4(-pos.xy * 2.0 + 1.0, -1.0, -1.0); // get ndc position (z = -1 because the depth buffer is reversed) vec4 posVS = inverseProjection * ndc; // unproject the ndc coordinates : we are now in view space if i understand correctly vec4 posWS = inverseView * vec4((posVS.xyz / posVS.w), 1.0); // then we use inverse view to get to world space, division by w to get actual coordinates return posWS.xyz; // the coordinates in world space From 6f7a07b6048f872b265dd503f319112370564b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Thu, 2 Nov 2023 00:13:03 +0100 Subject: [PATCH 66/86] small tweaks --- src/ts/controller/chunks/planetChunk.ts | 9 +++++---- src/ts/controller/postProcessManager.ts | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ts/controller/chunks/planetChunk.ts b/src/ts/controller/chunks/planetChunk.ts index 954640eea..cac81d284 100644 --- a/src/ts/controller/chunks/planetChunk.ts +++ b/src/ts/controller/chunks/planetChunk.ts @@ -83,10 +83,11 @@ export class PlanetChunk implements Transformable { vertexData.applyToMesh(this.mesh, false); this.mesh.freezeNormals(); - this.physicsShape = new PhysicsShapeMesh(this.mesh, this.mesh.getScene()); - this.parentAggregate.shape.addChildFromParent(this.parent, this.physicsShape, this.mesh); - this.physicsShapeIndex = this.parentAggregate.shape.getNumChildren(); - + if(this.depth > 3) { + this.physicsShape = new PhysicsShapeMesh(this.mesh, this.mesh.getScene()); + this.parentAggregate.shape.addChildFromParent(this.parent, this.physicsShape, this.mesh); + this.physicsShapeIndex = this.parentAggregate.shape.getNumChildren(); + } this.mesh.setEnabled(true); this.loaded = true; diff --git a/src/ts/controller/postProcessManager.ts b/src/ts/controller/postProcessManager.ts index 8a9b46917..26e41ee48 100644 --- a/src/ts/controller/postProcessManager.ts +++ b/src/ts/controller/postProcessManager.ts @@ -132,8 +132,8 @@ export class PostProcessManager { this.colorCorrection = new ColorCorrection("colorCorrection", scene.getEngine()); this.colorCorrection.exposure = 1.1; - this.colorCorrection.gamma = 1.2; - this.colorCorrection.saturation = 0.9; + this.colorCorrection.gamma = 1.0; + this.colorCorrection.saturation = 1.0; this.fxaa = new FxaaPostProcess("fxaa", 1, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine()); From 95de817b5641db332dfe3a28ed40f987a6950476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:38:47 +0100 Subject: [PATCH 67/86] documentation + linting --- src/ts/controller/chunks/planetChunk.ts | 16 +- src/ts/controller/chunks/quadTree.ts | 44 +-- src/ts/controller/postProcessManager.ts | 14 + src/ts/controller/spaceEngine.ts | 2 +- src/ts/controller/starSystem.ts | 58 ++-- src/ts/controller/starSystemHelper.ts | 280 +++++++++--------- .../uberCore/transforms/basicTransform.ts | 2 +- src/ts/model/orbit/orbitProperties.ts | 4 +- src/ts/model/planemos/gasPlanetModel.ts | 4 +- .../model/stellarObjects/neutronStarModel.ts | 2 +- src/ts/model/stellarObjects/starModel.ts | 14 +- src/ts/playground.ts | 4 +- src/ts/spaceship/shipController.ts | 2 +- .../ui/bodyEditor/panels/atmospherePanel.ts | 13 +- src/ts/utils/nearestBody.ts | 2 +- src/ts/utils/parseToStrings.ts | 6 +- src/ts/utils/positionNearObject.ts | 12 +- src/ts/view/axisRenderer.ts | 78 ++--- src/ts/view/bodies/abstractObject.ts | 1 - src/ts/view/bodies/planemos/gasPlanet.ts | 14 +- .../view/bodies/planemos/telluricPlanemo.ts | 4 +- src/ts/view/bodies/stellarObjects/star.ts | 14 +- src/ts/view/materials/gasPlanetMaterial.ts | 20 +- src/ts/view/materials/starMaterial.ts | 2 +- .../view/materials/telluricPlanemoMaterial.ts | 72 +++-- .../postProcesses/flatCloudsPostProcess.ts | 10 +- .../postProcesses/lensFlarePostProcess.ts | 6 +- .../postProcesses/mandelbulbPostProcess.ts | 2 +- .../postProcesses/matterJetPostProcess.ts | 8 +- src/ts/view/postProcesses/oceanPostProcess.ts | 2 +- .../view/postProcesses/overlayPostProcess.ts | 2 +- src/ts/view/postProcesses/postProcessTypes.ts | 2 +- src/ts/view/postProcesses/ringsPostProcess.ts | 2 +- .../postProcesses/starfieldPostProcess.ts | 8 +- .../volumetricCloudsPostProcess.ts | 2 +- 35 files changed, 370 insertions(+), 358 deletions(-) diff --git a/src/ts/controller/chunks/planetChunk.ts b/src/ts/controller/chunks/planetChunk.ts index cac81d284..519a7b979 100644 --- a/src/ts/controller/chunks/planetChunk.ts +++ b/src/ts/controller/chunks/planetChunk.ts @@ -83,11 +83,11 @@ export class PlanetChunk implements Transformable { vertexData.applyToMesh(this.mesh, false); this.mesh.freezeNormals(); - if(this.depth > 3) { - this.physicsShape = new PhysicsShapeMesh(this.mesh, this.mesh.getScene()); - this.parentAggregate.shape.addChildFromParent(this.parent, this.physicsShape, this.mesh); - this.physicsShapeIndex = this.parentAggregate.shape.getNumChildren(); - } + if (this.depth > 3) { + this.physicsShape = new PhysicsShapeMesh(this.mesh, this.mesh.getScene()); + this.parentAggregate.shape.addChildFromParent(this.parent, this.physicsShape, this.mesh); + this.physicsShapeIndex = this.parentAggregate.shape.getNumChildren(); + } this.mesh.setEnabled(true); this.loaded = true; @@ -98,9 +98,9 @@ export class PlanetChunk implements Transformable { if (this.physicsShapeIndex === null) return; if (this.physicsShapeIndex > this.parentAggregate.shape.getNumChildren() - 1) { console.error( - `Tried to delete ${this.mesh.name} PhysicsShape. However its shape index was out of bound: ${ - this.physicsShapeIndex - } / range 0 : ${this.parentAggregate.shape.getNumChildren() - 1}` + `Tried to delete ${this.mesh.name} PhysicsShape. However its shape index was out of bound: ${this.physicsShapeIndex} / range 0 : ${ + this.parentAggregate.shape.getNumChildren() - 1 + }` ); this.physicsShape?.dispose(); return; diff --git a/src/ts/controller/chunks/quadTree.ts b/src/ts/controller/chunks/quadTree.ts index 5eea1be0a..d63125a95 100644 --- a/src/ts/controller/chunks/quadTree.ts +++ b/src/ts/controller/chunks/quadTree.ts @@ -7,31 +7,31 @@ type tree = tree[] | T; * A ChunkTree is a structure designed to manage LOD using a quadtree */ export class QuadTree { - private tree: tree = []; + private tree: tree = []; - /** - * Function used to execute code on every leaf of the quadtree - * @param tree the tree to explore - * @param f the function to apply on every leaf - */ - public executeOnEveryLeaf(f: (leaf: T) => void, tree: tree = this.tree): void { - if (tree instanceof Array) { - for (const child of tree) { - this.executeOnEveryLeaf(f, child); - } - } else { - f(tree); + /** + * Function used to execute code on every leaf of the quadtree + * @param tree the tree to explore + * @param f the function to apply on every leaf + */ + public executeOnEveryLeaf(f: (leaf: T) => void, tree: tree = this.tree): void { + if (tree instanceof Array) { + for (const child of tree) { + this.executeOnEveryLeaf(f, child); + } + } else { + f(tree); + } } - } - public getLeaves(): T[] { - const leaves: T[] = []; - this.executeOnEveryLeaf((leaf) => leaves.push(leaf)); + public getLeaves(): T[] { + const leaves: T[] = []; + this.executeOnEveryLeaf((leaf) => leaves.push(leaf)); - return leaves; - } + return leaves; + } - public reset(): void { - this.tree = []; - } + public reset(): void { + this.tree = []; + } } diff --git a/src/ts/controller/postProcessManager.ts b/src/ts/controller/postProcessManager.ts index 26e41ee48..43eeb32a7 100644 --- a/src/ts/controller/postProcessManager.ts +++ b/src/ts/controller/postProcessManager.ts @@ -35,6 +35,7 @@ import { NeutronStar } from "../view/bodies/stellarObjects/neutronStar"; import { ShadowPostProcess } from "../view/postProcesses/shadowPostProcess"; import { LensFlarePostProcess } from "../view/postProcesses/lensFlarePostProcess"; import { Quaternion } from "@babylonjs/core/Maths/math"; +import { isOrbiting } from "../utils/nearestBody"; /** * The order in which the post processes are rendered when away from a planet @@ -321,6 +322,12 @@ export class PostProcessManager { this.currentBody = body; this.currentRenderingPipeline.detachCamera(this.scene.getActiveUberCamera()); + + const rings = this.getRings(body); + const switchLimit = rings !== null ? rings.ringsUniforms.ringStart : 2; + if (isOrbiting(this.scene.getActiveController(), body, switchLimit)) this.setSurfaceOrder(); + else this.setSpaceOrder(); + this.init(); } @@ -464,10 +471,17 @@ export class PostProcessManager { this.currentRenderingPipeline.attachToCamera(this.scene.getActiveUberCamera()); } + /** + * Updates all updatable post processes with the given delta time. + * @param deltaTime The time in seconds since the last frame + */ public update(deltaTime: number) { for (const postProcess of this.updatablePostProcesses.flat()) postProcess.update(deltaTime); } + /** + * Disposes all post processes and rendering pipelines. + */ public dispose() { for (const objectPostProcess of this.objectPostProcesses.flat()) objectPostProcess.dispose(); diff --git a/src/ts/controller/spaceEngine.ts b/src/ts/controller/spaceEngine.ts index cc7309320..f2a11445c 100644 --- a/src/ts/controller/spaceEngine.ts +++ b/src/ts/controller/spaceEngine.ts @@ -263,7 +263,7 @@ export class SpaceEngine { const nearestBody = starSystem.getNearestOrbitalObject(starSystemScene.getActiveUberCamera().position); - if(nearestBody instanceof AbstractBody) { + if (nearestBody instanceof AbstractBody) { this.bodyEditor.update(nearestBody, starSystem.postProcessManager, starSystemScene); } this.helmetOverlay.update(nearestBody); diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index 908bd7c48..de40ba707 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -9,7 +9,6 @@ import { GasPlanet } from "../view/bodies/planemos/gasPlanet"; import { BlackHole } from "../view/bodies/stellarObjects/blackHole"; import { PostProcessManager } from "./postProcessManager"; import { StarSystemModel } from "../model/starSystemModel"; -import { isOrbiting } from "../utils/nearestBody"; import { NeutronStar } from "../view/bodies/stellarObjects/neutronStar"; import { StellarObject } from "../view/bodies/stellarObjects/stellarObject"; import { SpaceStation } from "../view/spaceStation"; @@ -62,6 +61,9 @@ export class StarSystem { */ readonly mandelbulbs: Mandelbulb[] = []; + /** + * The model of the star system that describes it and generates the randomness + */ readonly model: StarSystemModel; constructor(model: StarSystemModel | number, scene: UberScene) { @@ -76,11 +78,6 @@ export class StarSystem { * @param planet The planet to add to the system */ public addTelluricPlanet(planet: TelluricPlanemo): TelluricPlanemo { - if (this.planets.length >= this.model.getNbPlanets()) - console.warn(`You are adding a telluric planet to the system. - The system generator had planned for ${this.model.getNbPlanets()} planets, but you are adding the ${this.planets.length + 1}th planet. - This might cause issues, or not who knows.`); - this.orbitalObjects.push(planet); this.celestialBodies.push(planet); this.planemosWithMaterial.push(planet); @@ -94,11 +91,6 @@ export class StarSystem { * @param planet The planet to add to the system */ public addGasPlanet(planet: GasPlanet): GasPlanet { - if (this.planets.length >= this.model.getNbPlanets()) - console.warn(`You are adding a gas planet to the system. - The system generator had planned for ${this.model.getNbPlanets()} planets, but you are adding the ${this.planets.length + 1}th planet. - This might cause issues, or not who knows.`); - this.orbitalObjects.push(planet); this.celestialBodies.push(planet); this.planemosWithMaterial.push(planet); @@ -110,13 +102,9 @@ export class StarSystem { /** * Adds a satellite to the system and returns it * @param satellite The satellite to add to the system + * @returns The satellite added to the system */ public addTelluricSatellite(satellite: TelluricPlanemo): TelluricPlanemo { - if (this.planets.length >= this.model.getNbPlanets()) - console.warn(`You are adding a telluric planet to the system. - The system generator had planned for ${this.model.getNbPlanets()} planets, but you are adding the ${this.planets.length + 1}th planet. - This might cause issues, or not who knows.`); - this.orbitalObjects.push(satellite); this.celestialBodies.push(satellite); this.planemosWithMaterial.push(satellite); @@ -124,12 +112,12 @@ export class StarSystem { return satellite; } + /** + * Adds a Mandelbulb to the system and returns it + * @param mandelbulb The mandelbulb to add to the system + * @returns The mandelbulb added to the system + */ public addMandelbulb(mandelbulb: Mandelbulb): Mandelbulb { - if (this.planets.length >= this.model.getNbPlanets()) - console.warn(`You are adding a mandelbulb to the system. - The system generator had planned for ${this.model.getNbPlanets()} planets, but you are adding the ${this.planets.length + 1}th planet. - This might cause issues, or not who knows.`); - this.orbitalObjects.push(mandelbulb); this.celestialBodies.push(mandelbulb); this.mandelbulbs.push(mandelbulb); @@ -139,19 +127,20 @@ export class StarSystem { /** * Adds a star or a blackhole to the system and returns it * @param stellarObject The star added to the system + * @returns The star added to the system */ public addStellarObject(stellarObject: StellarObject): StellarObject { - if (this.stellarObjects.length >= this.model.getNbStars()) - console.warn(`You are adding a star - to a system that already has ${this.stellarObjects.length} stars. - The capacity of the generator was supposed to be ${this.model.getNbStars()} This is not a problem, but it may be.`); - this.orbitalObjects.push(stellarObject); this.celestialBodies.push(stellarObject); this.stellarObjects.push(stellarObject); return stellarObject; } + /** + * Adds a spacestation to the system and returns it + * @param spaceStation The spacestation added to the system + * @returns The spacestation added to the system + */ public addSpaceStation(spaceStation: SpaceStation): SpaceStation { this.orbitalObjects.push(spaceStation); this.spaceStations.push(spaceStation); @@ -176,7 +165,7 @@ export class StarSystem { /** * Returns the nearest orbital object to the origin */ - public getNearestOrbitalObject(position = Vector3.Zero()): AbstractObject { + public getNearestOrbitalObject(position: Vector3): AbstractObject { if (this.celestialBodies.length + this.spaceStations.length === 0) throw new Error("There are no bodies or spacestation in the solar system"); let nearest = null; let smallerDistance = -1; @@ -201,9 +190,9 @@ export class StarSystem { } /** - * Returns the nearest body to the origin + * Returns the nearest body to the the given position */ - public getNearestCelestialBody(position = Vector3.Zero()): AbstractBody { + public getNearestCelestialBody(position: Vector3): AbstractBody { if (this.celestialBodies.length === 0) throw new Error("There are no bodies or spacestation in the solar system"); let nearest = null; let smallerDistance = -1; @@ -392,6 +381,10 @@ export class StarSystem { this.updateShaders(deltaTime); } + /** + * Updates the shaders of all the bodies in the system with the given delta time + * @param deltaTime The time elapsed in seconds since the last update + */ public updateShaders(deltaTime: number) { const controller = this.scene.getActiveController(); const nearestBody = this.getNearestCelestialBody(this.scene.getActiveUberCamera().position); @@ -405,13 +398,12 @@ export class StarSystem { } this.postProcessManager.setBody(nearestBody); - const rings = this.postProcessManager.getRings(nearestBody); - const switchLimit = rings !== null ? rings.ringsUniforms.ringStart : 2; - if (isOrbiting(controller, nearestBody, switchLimit)) this.postProcessManager.setSurfaceOrder(); - else this.postProcessManager.setSpaceOrder(); this.postProcessManager.update(deltaTime); } + /** + * Disposes all the bodies in the system + */ public dispose() { this.postProcessManager.dispose(); for (const spacestation of this.spaceStations) spacestation.dispose(); diff --git a/src/ts/controller/starSystemHelper.ts b/src/ts/controller/starSystemHelper.ts index a58df85a9..08388d0a3 100644 --- a/src/ts/controller/starSystemHelper.ts +++ b/src/ts/controller/starSystemHelper.ts @@ -19,151 +19,155 @@ import { StarSystem } from "./starSystem"; import { StellarObject } from "../view/bodies/stellarObjects/stellarObject"; export class StarSystemHelper { - public static makeStar(starsystem: StarSystem, model?: number | StarModel): Star { - if(model === undefined) { - model = starsystem.model.getStarSeed(starsystem.stellarObjects.length); + public static makeStar(starsystem: StarSystem, model?: number | StarModel): Star { + if (model === undefined) { + model = starsystem.model.getStarSeed(starsystem.stellarObjects.length); + } + const name = starName(starsystem.model.getName(), starsystem.stellarObjects.length); + const star = new Star(name, starsystem.scene, model, starsystem.stellarObjects[0]); + starsystem.addStellarObject(star); + return star; } - const name = starName(starsystem.model.getName(), starsystem.stellarObjects.length); - const star = new Star(name, starsystem.scene, model, starsystem.stellarObjects[0]); - starsystem.addStellarObject(star); - return star; - } - - public static makeMandelbulb(starsystem: StarSystem, model: number | MandelbulbModel = starsystem.model.getPlanetSeed(starsystem.mandelbulbs.length)): Mandelbulb { - if (starsystem.planets.length >= starsystem.model.getNbPlanets()) - console.warn(`You are adding a mandelbulb to the system. + + public static makeMandelbulb(starsystem: StarSystem, model: number | MandelbulbModel = starsystem.model.getPlanetSeed(starsystem.mandelbulbs.length)): Mandelbulb { + if (starsystem.planets.length >= starsystem.model.getNbPlanets()) + console.warn(`You are adding a mandelbulb to the system. The system generator had planned for ${starsystem.model.getNbPlanets()} planets, but you are adding the ${starsystem.planets.length + 1}th planet. starsystem might cause issues, or not who knows.`); - const mandelbulb = new Mandelbulb(`${starsystem.model.getName()} ${romanNumeral(starsystem.planets.length + 1)}`, starsystem.scene, model, starsystem.stellarObjects[0]); - starsystem.addMandelbulb(mandelbulb); - return mandelbulb; - } - - /** - * Makes a black hole and adds it to the system. By default, it will use the next available model planned by the system - * @param starsystem - * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) - */ - public static makeBlackHole(starsystem: StarSystem, model: number | BlackHoleModel = starsystem.model.getStarSeed(starsystem.stellarObjects.length)): BlackHole { - const name = starName(starsystem.model.getName(), starsystem.stellarObjects.length); - const blackHole = new BlackHole(name, starsystem.scene, model, starsystem.stellarObjects[0]); - starsystem.addStellarObject(blackHole); - return blackHole; - } - - public static makeNeutronStar(starsystem: StarSystem, model: number | NeutronStarModel = starsystem.model.getStarSeed(starsystem.stellarObjects.length)): NeutronStar { - if (starsystem.stellarObjects.length >= starsystem.model.getNbStars()) - console.warn(`You are adding a neutron star + const mandelbulb = new Mandelbulb(`${starsystem.model.getName()} ${romanNumeral(starsystem.planets.length + 1)}`, starsystem.scene, model, starsystem.stellarObjects[0]); + starsystem.addMandelbulb(mandelbulb); + return mandelbulb; + } + + /** + * Makes a black hole and adds it to the system. By default, it will use the next available model planned by the system + * @param starsystem + * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) + */ + public static makeBlackHole(starsystem: StarSystem, model: number | BlackHoleModel = starsystem.model.getStarSeed(starsystem.stellarObjects.length)): BlackHole { + const name = starName(starsystem.model.getName(), starsystem.stellarObjects.length); + const blackHole = new BlackHole(name, starsystem.scene, model, starsystem.stellarObjects[0]); + starsystem.addStellarObject(blackHole); + return blackHole; + } + + public static makeNeutronStar(starsystem: StarSystem, model: number | NeutronStarModel = starsystem.model.getStarSeed(starsystem.stellarObjects.length)): NeutronStar { + if (starsystem.stellarObjects.length >= starsystem.model.getNbStars()) + console.warn(`You are adding a neutron star to a system that already has ${starsystem.stellarObjects.length} stars. The capacity of the generator was supposed to be ${starsystem.model.getNbStars()} starsystem is not a problem, but it may be.`); - const name = starName(starsystem.model.getName(), starsystem.stellarObjects.length); - const neutronStar = new NeutronStar(name, starsystem.scene, model, starsystem.stellarObjects[0]); - - starsystem.addStellarObject(neutronStar); - return neutronStar; - } - - /** - * Makes a star and adds it to the system. By default, it will use the next available seed planned by the system model - * @param starsystem - * @param seed The seed to use for the star generation (by default, the next available seed planned by the system model) - */ - public static makeStellarObject(starsystem: StarSystem, seed: number = starsystem.model.getStarSeed(starsystem.stellarObjects.length)): StellarObject { - const isStellarObjectBlackHole = starsystem.model.getBodyTypeOfStar(starsystem.stellarObjects.length) === BODY_TYPE.BLACK_HOLE; - if (isStellarObjectBlackHole) return StarSystemHelper.makeBlackHole(starsystem, seed); - else return this.makeStar(starsystem, seed); - } - - /** - * Makes n stars and adds them to the system. By default, it will use the next available seeds planned by the system model - * @param starsystem - * @param n The number of stars to make (by default, the number of stars planned by the system model) - */ - public static makeStellarObjects(starsystem: StarSystem, n = starsystem.model.getNbStars()): void { - if (n < 1) throw new Error("Cannot make less than 1 star"); - for (let i = 0; i < n; i++) StarSystemHelper.makeStellarObject(starsystem); - } - - /** - * Makes a telluric planet and adds it to the system. By default, it will use the next available model planned by the system model - * @param starsystem - * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) - */ - public static makeTelluricPlanet(starsystem: StarSystem, model: number | TelluricPlanemoModel = starsystem.model.getPlanetSeed(starsystem.planets.length)): TelluricPlanemo { - const planet = new TelluricPlanemo(`${starsystem.model.getName()} ${romanNumeral(starsystem.planets.length + 1)}`, starsystem.scene, model, starsystem.stellarObjects[0]); - starsystem.addTelluricPlanet(planet); - return planet; - } - - /** - * Makes a gas planet and adds it to the system. By default, it will use the next available model planned by the system model - * @param starsystem - * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) - */ - public static makeGasPlanet(starsystem: StarSystem, model: number | GasPlanetModel = starsystem.model.getPlanetSeed(starsystem.planets.length)): GasPlanet { - const planet = new GasPlanet(`${starsystem.model.getName()} ${romanNumeral(starsystem.planets.length + 1)}`, starsystem.scene, model, starsystem.stellarObjects[0]); - starsystem.addGasPlanet(planet); - return planet; - } - - public static makePlanets(starsystem: StarSystem, n: number): void { - console.assert(n >= 0, `Cannot make a negative amount of planets : ${n}`); - - for (let i = 0; i < n; i++) { - switch (starsystem.model.getBodyTypeOfPlanet(starsystem.planets.length)) { - case BODY_TYPE.TELLURIC: - StarSystemHelper.makeSatellites(starsystem, StarSystemHelper.makeTelluricPlanet(starsystem)); - break; - case BODY_TYPE.GAS: - StarSystemHelper.makeSatellites(starsystem, StarSystemHelper.makeGasPlanet(starsystem)); - break; - case BODY_TYPE.MANDELBULB: - StarSystemHelper.makeSatellites(starsystem, StarSystemHelper.makeMandelbulb(starsystem)); - break; - default: - throw new Error(`Unknown body type ${starsystem.model.getBodyTypeOfPlanet(starsystem.planets.length)}`); - } + const name = starName(starsystem.model.getName(), starsystem.stellarObjects.length); + const neutronStar = new NeutronStar(name, starsystem.scene, model, starsystem.stellarObjects[0]); + + starsystem.addStellarObject(neutronStar); + return neutronStar; + } + + /** + * Makes a star and adds it to the system. By default, it will use the next available seed planned by the system model + * @param starsystem + * @param seed The seed to use for the star generation (by default, the next available seed planned by the system model) + */ + public static makeStellarObject(starsystem: StarSystem, seed: number = starsystem.model.getStarSeed(starsystem.stellarObjects.length)): StellarObject { + const isStellarObjectBlackHole = starsystem.model.getBodyTypeOfStar(starsystem.stellarObjects.length) === BODY_TYPE.BLACK_HOLE; + if (isStellarObjectBlackHole) return StarSystemHelper.makeBlackHole(starsystem, seed); + else return this.makeStar(starsystem, seed); + } + + /** + * Makes n stars and adds them to the system. By default, it will use the next available seeds planned by the system model + * @param starsystem + * @param n The number of stars to make (by default, the number of stars planned by the system model) + */ + public static makeStellarObjects(starsystem: StarSystem, n = starsystem.model.getNbStars()): void { + if (n < 1) throw new Error("Cannot make less than 1 star"); + for (let i = 0; i < n; i++) StarSystemHelper.makeStellarObject(starsystem); + } + + /** + * Makes a telluric planet and adds it to the system. By default, it will use the next available model planned by the system model + * @param starsystem + * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) + */ + public static makeTelluricPlanet(starsystem: StarSystem, model: number | TelluricPlanemoModel = starsystem.model.getPlanetSeed(starsystem.planets.length)): TelluricPlanemo { + const planet = new TelluricPlanemo(`${starsystem.model.getName()} ${romanNumeral(starsystem.planets.length + 1)}`, starsystem.scene, model, starsystem.stellarObjects[0]); + starsystem.addTelluricPlanet(planet); + return planet; + } + + /** + * Makes a gas planet and adds it to the system. By default, it will use the next available model planned by the system model + * @param starsystem + * @param model The model or seed to use for the planet generation (by default, the next available seed planned by the system model) + */ + public static makeGasPlanet(starsystem: StarSystem, model: number | GasPlanetModel = starsystem.model.getPlanetSeed(starsystem.planets.length)): GasPlanet { + const planet = new GasPlanet(`${starsystem.model.getName()} ${romanNumeral(starsystem.planets.length + 1)}`, starsystem.scene, model, starsystem.stellarObjects[0]); + starsystem.addGasPlanet(planet); + return planet; + } + + public static makePlanets(starsystem: StarSystem, n: number): void { + console.assert(n >= 0, `Cannot make a negative amount of planets : ${n}`); + + for (let i = 0; i < n; i++) { + switch (starsystem.model.getBodyTypeOfPlanet(starsystem.planets.length)) { + case BODY_TYPE.TELLURIC: + StarSystemHelper.makeSatellites(starsystem, StarSystemHelper.makeTelluricPlanet(starsystem)); + break; + case BODY_TYPE.GAS: + StarSystemHelper.makeSatellites(starsystem, StarSystemHelper.makeGasPlanet(starsystem)); + break; + case BODY_TYPE.MANDELBULB: + StarSystemHelper.makeSatellites(starsystem, StarSystemHelper.makeMandelbulb(starsystem)); + break; + default: + throw new Error(`Unknown body type ${starsystem.model.getBodyTypeOfPlanet(starsystem.planets.length)}`); + } + } } - } - - public static makeSatellite(starsystem: StarSystem, planet: Planemo, model: TelluricPlanemoModel | number = getMoonSeed(planet.model, planet.model.childrenBodies.length)): TelluricPlanemo { - const satellite = new TelluricPlanemo(`${planet.name} ${romanNumeral(planet.model.childrenBodies.length + 1)}`, starsystem.scene, model, planet); - - satellite.material.colorSettings.desertColor.copyFromFloats(92 / 255, 92 / 255, 92 / 255); - satellite.material.updateConstants(); - - planet.model.childrenBodies.push(satellite.model); - - starsystem.addTelluricSatellite(satellite); - return satellite; - } - - /** - * Makes n more satellites for the given planet. By default, it will make as many as the planet has in the generation. - * You can make more, but it will generate warnings and might cause issues. - * @param starsystem - * @param planet The planet to make satellites for - * @param n The number of satellites to make - */ - public static makeSatellites(starsystem: StarSystem, planet: Planemo, n = planet.model.nbMoons): void { - if (n < 0) throw new Error(`Cannot make a negative amount of satellites : ${n}`); - if (planet.model.childrenBodies.length + n > planet.model.nbMoons) - console.warn( - `You are making more satellites than the planet had planned in its the generation: + + public static makeSatellite( + starsystem: StarSystem, + planet: Planemo, + model: TelluricPlanemoModel | number = getMoonSeed(planet.model, planet.model.childrenBodies.length) + ): TelluricPlanemo { + const satellite = new TelluricPlanemo(`${planet.name} ${romanNumeral(planet.model.childrenBodies.length + 1)}`, starsystem.scene, model, planet); + + satellite.material.colorSettings.desertColor.copyFromFloats(92 / 255, 92 / 255, 92 / 255); + satellite.material.updateConstants(); + + planet.model.childrenBodies.push(satellite.model); + + starsystem.addTelluricSatellite(satellite); + return satellite; + } + + /** + * Makes n more satellites for the given planet. By default, it will make as many as the planet has in the generation. + * You can make more, but it will generate warnings and might cause issues. + * @param starsystem + * @param planet The planet to make satellites for + * @param n The number of satellites to make + */ + public static makeSatellites(starsystem: StarSystem, planet: Planemo, n = planet.model.nbMoons): void { + if (n < 0) throw new Error(`Cannot make a negative amount of satellites : ${n}`); + if (planet.model.childrenBodies.length + n > planet.model.nbMoons) + console.warn( + `You are making more satellites than the planet had planned in its the generation: You want ${n} more which will amount to a total ${planet.model.childrenBodies.length + n}. The generator had planned ${planet.model.nbMoons}. starsystem might cause issues, or not who knows. You can just leave starsystem argument empty to make as many as the planet had planned.` - ); - - for (let i = 0; i < n; i++) StarSystemHelper.makeSatellite(starsystem, planet, getMoonSeed(planet.model, planet.model.childrenBodies.length)); - } - - /** - * Generates the system using the seed provided in the constructor - */ - public static generate(starsystem: StarSystem) { - StarSystemHelper.makeStellarObjects(starsystem, starsystem.model.getNbStars()); - StarSystemHelper.makePlanets(starsystem, starsystem.model.getNbPlanets()); - } -} \ No newline at end of file + ); + + for (let i = 0; i < n; i++) StarSystemHelper.makeSatellite(starsystem, planet, getMoonSeed(planet.model, planet.model.childrenBodies.length)); + } + + /** + * Generates the system using the seed provided in the constructor + */ + public static generate(starsystem: StarSystem) { + StarSystemHelper.makeStellarObjects(starsystem, starsystem.model.getNbStars()); + StarSystemHelper.makePlanets(starsystem, starsystem.model.getNbPlanets()); + } +} diff --git a/src/ts/controller/uberCore/transforms/basicTransform.ts b/src/ts/controller/uberCore/transforms/basicTransform.ts index fbf47c814..14119d72f 100644 --- a/src/ts/controller/uberCore/transforms/basicTransform.ts +++ b/src/ts/controller/uberCore/transforms/basicTransform.ts @@ -36,7 +36,7 @@ export function setRotationQuaternion(transformNode: TransformNode, newRotation: } export function setUpVector(transformNode: TransformNode, newUp: Vector3): void { - if(newUp.equalsWithEpsilon(transformNode.up, 1e-7)) return; + if (newUp.equalsWithEpsilon(transformNode.up, 1e-7)) return; const currentUp = transformNode.up; const rotationAxis = Vector3.Cross(newUp, currentUp); const angle = -Math.acos(Vector3.Dot(newUp, currentUp)); diff --git a/src/ts/model/orbit/orbitProperties.ts b/src/ts/model/orbit/orbitProperties.ts index 7a1de6c19..aac3f4b93 100644 --- a/src/ts/model/orbit/orbitProperties.ts +++ b/src/ts/model/orbit/orbitProperties.ts @@ -28,11 +28,11 @@ export class OrbitProperties { */ readonly isPlaneAlignedWithParent: boolean; - constructor({radius, p, period, normalToPlane, isPlaneAlignedWithParent}: OrbitProps) { + constructor({ radius, p, period, normalToPlane, isPlaneAlignedWithParent }: OrbitProps) { this.radius = radius; this.p = p; this.period = period; this.normalToPlane = normalToPlane; this.isPlaneAlignedWithParent = isPlaneAlignedWithParent; } -} \ No newline at end of file +} diff --git a/src/ts/model/planemos/gasPlanetModel.ts b/src/ts/model/planemos/gasPlanetModel.ts index b19fa06a4..d41513b8f 100644 --- a/src/ts/model/planemos/gasPlanetModel.ts +++ b/src/ts/model/planemos/gasPlanetModel.ts @@ -43,7 +43,7 @@ export class GasPlanetModel implements PlanemoModel { const orbitalP = clamp(0.7, 3.0, normalRandom(2.0, 0.3, this.rng, GENERATION_STEPS.ORBIT + 80)); orbitRadius += orbitRadius - getPeriapsis(orbitRadius, orbitalP); - if(parentBody) orbitRadius += parentBody.radius * 1.5; + if (parentBody) orbitRadius += parentBody.radius * 1.5; const orbitalPlaneNormal = Vector3.Up().applyRotationQuaternionInPlace(Quaternion.RotationAxis(Axis.X, (this.rng(GENERATION_STEPS.ORBIT + 20) - 0.5) * 0.2)); @@ -58,7 +58,7 @@ export class GasPlanetModel implements PlanemoModel { this.physicalProperties = { // FIXME: choose physically accurate values mass: 10, - axialTilt: normalRandom(0, 0.4, this.rng, GENERATION_STEPS.AXIAL_TILT), + axialTilt: normalRandom(0, 0.4, this.rng, GENERATION_STEPS.AXIAL_TILT), rotationPeriod: (24 * 60 * 60) / 10, minTemperature: -180, maxTemperature: 200, diff --git a/src/ts/model/stellarObjects/neutronStarModel.ts b/src/ts/model/stellarObjects/neutronStarModel.ts index a2af86b68..68c89c44b 100644 --- a/src/ts/model/stellarObjects/neutronStarModel.ts +++ b/src/ts/model/stellarObjects/neutronStarModel.ts @@ -5,4 +5,4 @@ export class NeutronStarModel extends StarModel { constructor(seed: number, parentBody?: BodyModel) { super(seed, parentBody); } -} \ No newline at end of file +} diff --git a/src/ts/model/stellarObjects/starModel.ts b/src/ts/model/stellarObjects/starModel.ts index 952df92ba..e80d68011 100644 --- a/src/ts/model/stellarObjects/starModel.ts +++ b/src/ts/model/stellarObjects/starModel.ts @@ -80,12 +80,12 @@ export class StarModel implements StellarObjectModel { } static getStellarTypeFromTemperature(temperature: number) { - if (temperature < 3500) return STELLAR_TYPE.M; - else if (temperature < 5000) return STELLAR_TYPE.K; - else if (temperature < 6000) return STELLAR_TYPE.G; - else if (temperature < 7500) return STELLAR_TYPE.F; - else if (temperature < 10000) return STELLAR_TYPE.A; - else if (temperature < 30000) return STELLAR_TYPE.B; - else return STELLAR_TYPE.O; + if (temperature < 3500) return STELLAR_TYPE.M; + else if (temperature < 5000) return STELLAR_TYPE.K; + else if (temperature < 6000) return STELLAR_TYPE.G; + else if (temperature < 7500) return STELLAR_TYPE.F; + else if (temperature < 10000) return STELLAR_TYPE.A; + else if (temperature < 30000) return STELLAR_TYPE.B; + else return STELLAR_TYPE.O; } } diff --git a/src/ts/playground.ts b/src/ts/playground.ts index 25c9c905d..77e89f7f7 100644 --- a/src/ts/playground.ts +++ b/src/ts/playground.ts @@ -137,9 +137,9 @@ function updateBeforeHavok() { aggregate.body.applyForce(gravityDirection.scaleInPlace(gravity * mass), aggregate.body.getObjectCenterWorld()); } - if(spaceship.getAggregate().transformNode.getAbsolutePosition().length() > 100) { + if (spaceship.getAggregate().transformNode.getAbsolutePosition().length() > 100) { const displacement = spaceship.getAggregate().transformNode.getAbsolutePosition().negate(); - for(const mesh of meshes) { + for (const mesh of meshes) { translate(mesh, displacement); } } diff --git a/src/ts/spaceship/shipController.ts b/src/ts/spaceship/shipController.ts index d1141caa5..dafc9ccad 100644 --- a/src/ts/spaceship/shipController.ts +++ b/src/ts/spaceship/shipController.ts @@ -57,7 +57,7 @@ export class ShipController extends AbstractController { this.firstPersonCamera.parent = this.instanceRoot; this.firstPersonCamera.position = new Vector3(0, 1, 0); - this.thirdPersonCamera = new UberOrbitCamera("thirdPersonCamera", Vector3.Zero(), scene, 30, 3.14, 3.14/2); + this.thirdPersonCamera = new UberOrbitCamera("thirdPersonCamera", Vector3.Zero(), scene, 30, 3.14, 3.14 / 2); this.thirdPersonCamera.parent = this.instanceRoot; this.aggregate = new PhysicsAggregate(this.instanceRoot, PhysicsShapeType.CONTAINER, { mass: 10, restitution: 0.2 }, scene); diff --git a/src/ts/ui/bodyEditor/panels/atmospherePanel.ts b/src/ts/ui/bodyEditor/panels/atmospherePanel.ts index d3bd333b9..467402a87 100644 --- a/src/ts/ui/bodyEditor/panels/atmospherePanel.ts +++ b/src/ts/ui/bodyEditor/panels/atmospherePanel.ts @@ -36,9 +36,16 @@ export class AtmospherePanel extends EditorPanel { atmosphere.atmosphereUniforms.atmosphereRadius = planet.getRadius() + val * 10000; } ), - new Slider("rayleighStrength", document.getElementById("rayleighStrength") as HTMLElement, 0, 40, atmosphere.atmosphereUniforms.rayleighStrength * 10, (val: number) => { - atmosphere.atmosphereUniforms.rayleighStrength = val / 10; - }), + new Slider( + "rayleighStrength", + document.getElementById("rayleighStrength") as HTMLElement, + 0, + 40, + atmosphere.atmosphereUniforms.rayleighStrength * 10, + (val: number) => { + atmosphere.atmosphereUniforms.rayleighStrength = val / 10; + } + ), new Slider("mieStrength", document.getElementById("mieStrength") as HTMLElement, 0, 40, atmosphere.atmosphereUniforms.mieStrength * 10, (val: number) => { atmosphere.atmosphereUniforms.mieStrength = val / 10; }), diff --git a/src/ts/utils/nearestBody.ts b/src/ts/utils/nearestBody.ts index 0a58e7fba..40dcdbc72 100644 --- a/src/ts/utils/nearestBody.ts +++ b/src/ts/utils/nearestBody.ts @@ -23,6 +23,6 @@ export function nearestBody(object: TransformNode, bodies: AbstractBody[]): Abst * @param body the body to check whereas the player is orbiting * @param orbitLimitFactor the boundary of the orbit detection (multiplied by planet radius) */ -export function isOrbiting(controller: AbstractController, body: Transformable & BoundingSphere, orbitLimitFactor = 2.5): boolean { +export function isOrbiting(controller: Transformable, body: Transformable & BoundingSphere, orbitLimitFactor = 2.5): boolean { return body.getTransform().getAbsolutePosition().subtract(controller.getTransform().getAbsolutePosition()).lengthSquared() < (orbitLimitFactor * body.getBoundingRadius()) ** 2; } diff --git a/src/ts/utils/parseToStrings.ts b/src/ts/utils/parseToStrings.ts index 27de6d68d..74422af60 100644 --- a/src/ts/utils/parseToStrings.ts +++ b/src/ts/utils/parseToStrings.ts @@ -22,7 +22,7 @@ export function parsePercentageFrom01(percentage01: number): string { return `${(percentage01 * 100).toFixed(0)}%`; } -export const alphabet = "abcdefghijklmnopqrstuvwxyz" +export const alphabet = "abcdefghijklmnopqrstuvwxyz"; export function starName(baseName: string, index: number): string { - return `${baseName} ${alphabet[index].toUpperCase()}` -} \ No newline at end of file + return `${baseName} ${alphabet[index].toUpperCase()}`; +} diff --git a/src/ts/utils/positionNearObject.ts b/src/ts/utils/positionNearObject.ts index 6995c8a12..a3ed56341 100644 --- a/src/ts/utils/positionNearObject.ts +++ b/src/ts/utils/positionNearObject.ts @@ -10,13 +10,21 @@ export function positionNearObject(controller: AbstractController, object: Trans if (nearestStar === object) { // the object is the nearest star - controller.getTransform().setAbsolutePosition(object.getTransform().getAbsolutePosition().add(new Vector3(0, 0.2, 1).scaleInPlace(object.getBoundingRadius() * nRadius))); + controller.getTransform().setAbsolutePosition( + object + .getTransform() + .getAbsolutePosition() + .add(new Vector3(0, 0.2, 1).scaleInPlace(object.getBoundingRadius() * nRadius)) + ); } else { const dirBodyToStar = object.getTransform().getAbsolutePosition().subtract(nearestStar.getTransform().getAbsolutePosition()); const distBodyToStar = dirBodyToStar.length(); dirBodyToStar.scaleInPlace(1 / distBodyToStar); - const displacement = nearestStar.getTransform().getAbsolutePosition().add(dirBodyToStar.scale(distBodyToStar - nRadius * object.getBoundingRadius())); + const displacement = nearestStar + .getTransform() + .getAbsolutePosition() + .add(dirBodyToStar.scale(distBodyToStar - nRadius * object.getBoundingRadius())); controller.getTransform().setAbsolutePosition(displacement); } diff --git a/src/ts/view/axisRenderer.ts b/src/ts/view/axisRenderer.ts index 9bb3b54f3..cd3e3763d 100644 --- a/src/ts/view/axisRenderer.ts +++ b/src/ts/view/axisRenderer.ts @@ -4,53 +4,53 @@ import { Color3, Vector3 } from "@babylonjs/core/Maths/math"; import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; export class AxisRenderer { - private axisMeshes: LinesMesh[] = []; + private axisMeshes: LinesMesh[] = []; - private axisMaterial: StandardMaterial | null = null; + private axisMaterial: StandardMaterial | null = null; - private isVisibile = false; + private isVisibile = false; - setObjects(objects: (Transformable & BoundingSphere)[]) { - this.reset(); + setObjects(objects: (Transformable & BoundingSphere)[]) { + this.reset(); - for (const object of objects) { - this.createAxisMesh(object); + for (const object of objects) { + this.createAxisMesh(object); + } + + this.setVisibility(this.isVisibile); } - this.setVisibility(this.isVisibile); - } - - private createAxisMesh(orbitalObject: Transformable & BoundingSphere) { - const rotationAxisHelper = MeshBuilder.CreateLines( - `RotationAxisHelper`, - { - points: [new Vector3(0, -orbitalObject.getBoundingRadius() * 2, 0), new Vector3(0, orbitalObject.getBoundingRadius() * 2, 0)] - }, - orbitalObject.getTransform().getScene() - ); - rotationAxisHelper.parent = orbitalObject.getTransform(); - if (this.axisMaterial === null) throw new Error("Orbit material is null"); - rotationAxisHelper.material = this.axisMaterial; - this.axisMeshes.push(rotationAxisHelper); - } - - setVisibility(visible: boolean) { - this.isVisibile = visible; - for (const axisMesh of this.axisMeshes) { - axisMesh.visibility = visible ? 1 : 0; + private createAxisMesh(orbitalObject: Transformable & BoundingSphere) { + const rotationAxisHelper = MeshBuilder.CreateLines( + `RotationAxisHelper`, + { + points: [new Vector3(0, -orbitalObject.getBoundingRadius() * 2, 0), new Vector3(0, orbitalObject.getBoundingRadius() * 2, 0)] + }, + orbitalObject.getTransform().getScene() + ); + rotationAxisHelper.parent = orbitalObject.getTransform(); + if (this.axisMaterial === null) throw new Error("Orbit material is null"); + rotationAxisHelper.material = this.axisMaterial; + this.axisMeshes.push(rotationAxisHelper); } - } - isVisible(): boolean { - return this.isVisibile; - } + setVisibility(visible: boolean) { + this.isVisibile = visible; + for (const axisMesh of this.axisMeshes) { + axisMesh.visibility = visible ? 1 : 0; + } + } - private reset() { - this.axisMeshes.forEach((orbitMesh) => orbitMesh.dispose()); - this.axisMeshes = []; + isVisible(): boolean { + return this.isVisibile; + } - this.axisMaterial = new StandardMaterial("axisMaterial"); - this.axisMaterial.emissiveColor = Color3.White(); - this.axisMaterial.disableLighting = true; - } + private reset() { + this.axisMeshes.forEach((orbitMesh) => orbitMesh.dispose()); + this.axisMeshes = []; + + this.axisMaterial = new StandardMaterial("axisMaterial"); + this.axisMaterial.emissiveColor = Color3.White(); + this.axisMaterial.disableLighting = true; + } } diff --git a/src/ts/view/bodies/abstractObject.ts b/src/ts/view/bodies/abstractObject.ts index c3642b375..a8f5ecdb8 100644 --- a/src/ts/view/bodies/abstractObject.ts +++ b/src/ts/view/bodies/abstractObject.ts @@ -84,7 +84,6 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla // apply corrections translate(this.transform, newPosition.subtract(oldPosition)); - } } diff --git a/src/ts/view/bodies/planemos/gasPlanet.ts b/src/ts/view/bodies/planemos/gasPlanet.ts index 917c44f69..411b8e25e 100644 --- a/src/ts/view/bodies/planemos/gasPlanet.ts +++ b/src/ts/view/bodies/planemos/gasPlanet.ts @@ -46,13 +46,13 @@ export class GasPlanet extends AbstractBody implements Planemo, PlanemoMaterial this.mesh.parent = this.getTransform(); this.aggregate = new PhysicsAggregate( - this.getTransform(), - PhysicsShapeType.CONTAINER, - { - mass: 0, - restitution: 0.2 - }, - scene + this.getTransform(), + PhysicsShapeType.CONTAINER, + { + mass: 0, + restitution: 0.2 + }, + scene ); this.aggregate.body.setMassProperties({ inertia: Vector3.Zero(), mass: 0 }); this.aggregate.body.disablePreStep = false; diff --git a/src/ts/view/bodies/planemos/telluricPlanemo.ts b/src/ts/view/bodies/planemos/telluricPlanemo.ts index 0e3315985..47ca37501 100644 --- a/src/ts/view/bodies/planemos/telluricPlanemo.ts +++ b/src/ts/view/bodies/planemos/telluricPlanemo.ts @@ -86,9 +86,9 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat new ChunkTree(Direction.Left, this.name, this.model, this.aggregate, this.material, scene) ]; - for(const side of this.sides) { + for (const side of this.sides) { side.onChunkPhysicsShapeDeletedObservable.add((index) => { - for(const side2 of this.sides) { + for (const side2 of this.sides) { side2.registerPhysicsShapeDeletion(index); } }); diff --git a/src/ts/view/bodies/stellarObjects/star.ts b/src/ts/view/bodies/stellarObjects/star.ts index 155c88752..1a664c5c8 100644 --- a/src/ts/view/bodies/stellarObjects/star.ts +++ b/src/ts/view/bodies/stellarObjects/star.ts @@ -51,13 +51,13 @@ export class Star extends AbstractBody { this.mesh.parent = this.getTransform(); this.aggregate = new PhysicsAggregate( - this.getTransform(), - PhysicsShapeType.CONTAINER, - { - mass: 0, - restitution: 0.2 - }, - scene + this.getTransform(), + PhysicsShapeType.CONTAINER, + { + mass: 0, + restitution: 0.2 + }, + scene ); this.aggregate.body.setMassProperties({ inertia: Vector3.Zero(), mass: 0 }); this.aggregate.body.disablePreStep = false; diff --git a/src/ts/view/materials/gasPlanetMaterial.ts b/src/ts/view/materials/gasPlanetMaterial.ts index 29bff87bf..ee819b341 100644 --- a/src/ts/view/materials/gasPlanetMaterial.ts +++ b/src/ts/view/materials/gasPlanetMaterial.ts @@ -28,25 +28,7 @@ export class GasPlanetMaterial extends ShaderMaterial { constructor(planetName: string, planet: TransformNode, model: GasPlanetModel, scene: Scene) { super(`${planetName}GasSurfaceColor`, scene, shaderName, { attributes: ["position", "normal"], - uniforms: [ - "world", - "worldViewProjection", - "normalMatrix", - - "seed", - - "stars", - "nbStars", - - "color1", - "color2", - "color3", - "colorSharpness", - - "time", - - "playerPosition" - ], + uniforms: ["world", "worldViewProjection", "normalMatrix", "seed", "stars", "nbStars", "color1", "color2", "color3", "colorSharpness", "time", "playerPosition"] }); this.planet = planet; diff --git a/src/ts/view/materials/starMaterial.ts b/src/ts/view/materials/starMaterial.ts index a808099e1..3a64eb127 100644 --- a/src/ts/view/materials/starMaterial.ts +++ b/src/ts/view/materials/starMaterial.ts @@ -19,7 +19,7 @@ export class StarMaterial extends ShaderMaterial { constructor(star: TransformNode, model: StarModel, scene: Scene) { super("starColor", scene, shaderName, { attributes: ["position"], - uniforms: ["world", "worldViewProjection", "seed", "starColor", "starPosition", "starInverseRotationQuaternion", "time"], + uniforms: ["world", "worldViewProjection", "seed", "starColor", "starPosition", "starInverseRotationQuaternion", "time"] }); this.star = star; this.starModel = model; diff --git a/src/ts/view/materials/telluricPlanemoMaterial.ts b/src/ts/view/materials/telluricPlanemoMaterial.ts index 0987e328d..29336c0c5 100644 --- a/src/ts/view/materials/telluricPlanemoMaterial.ts +++ b/src/ts/view/materials/telluricPlanemoMaterial.ts @@ -4,31 +4,45 @@ import surfaceMaterialFragment from "../../../shaders/telluricPlanetMaterial/fra import surfaceMaterialVertex from "../../../shaders/telluricPlanetMaterial/vertex.glsl"; import { Assets } from "../../controller/assets"; import { UberScene } from "../../controller/uberCore/uberScene"; -import { TerrainSettings } from "../../model/terrain/terrainSettings"; -import { SolidPhysicalProperties } from "../../model/common"; import { centeredRand } from "extended-random"; import { TelluricPlanemoModel } from "../../model/planemos/telluricPlanemoModel"; import { Effect } from "@babylonjs/core/Materials/effect"; import { ShaderMaterial } from "@babylonjs/core/Materials/shaderMaterial"; import { Color3 } from "@babylonjs/core/Maths/math.color"; -import { MaterialHelper } from "@babylonjs/core/Materials/materialHelper"; import { Vector3 } from "@babylonjs/core/Maths/math"; import { TransformNode } from "@babylonjs/core/Meshes"; import { getInverseRotationMatrix } from "../../controller/uberCore/transforms/basicTransform"; -import {Star} from "../bodies/stellarObjects/star"; -import {StellarObject} from "../bodies/stellarObjects/stellarObject"; +import { Star } from "../bodies/stellarObjects/star"; +import { StellarObject } from "../bodies/stellarObjects/stellarObject"; const shaderName = "surfaceMaterial"; Effect.ShadersStore[`${shaderName}FragmentShader`] = surfaceMaterialFragment; Effect.ShadersStore[`${shaderName}VertexShader`] = surfaceMaterialVertex; +/** + * The material for telluric planemos. + * It is responsible for the shading of the surface of the planet (biome blending, normal mapping and color) + */ export class TelluricPlanemoMaterial extends ShaderMaterial { - readonly planet: TransformNode; - colorSettings: ColorSettings; - terrainSettings: TerrainSettings; - physicalProperties: SolidPhysicalProperties; - planetRadius: number; - + /** + * The transform node of the planemo associated with this material + */ + private readonly planemoTransform: TransformNode; + + readonly colorSettings: ColorSettings; + + /** + * The model of the planemo associated with this material + */ + private readonly planemoModel: TelluricPlanemoModel; + + /** + * Creates a new telluric planemo material + * @param planetName The name of the planemo + * @param planet The transform node of the planemo + * @param model The model of the planemo associated with this material + * @param scene + */ constructor(planetName: string, planet: TransformNode, model: TelluricPlanemoModel, scene: UberScene) { super(`${planetName}SurfaceColor`, scene, shaderName, { attributes: ["position", "normal"], @@ -80,14 +94,13 @@ export class TelluricPlanemoMaterial extends ShaderMaterial { "maxTemperature", "pressure", - "waterAmount", - ], + "waterAmount" + ] }); - this.planet = planet; - this.planetRadius = model.radius; - this.terrainSettings = model.terrainSettings; - this.physicalProperties = model.physicalProperties; + this.planemoModel = model; + this.planemoTransform = planet; + this.colorSettings = { mode: ColorMode.DEFAULT, @@ -123,17 +136,17 @@ export class TelluricPlanemoMaterial extends ShaderMaterial { this.setColor3("desertColor", this.colorSettings.desertColor); this.setColor3("bottomColor", this.colorSettings.bottomColor); - this.setVector3("planetPosition", this.planet.getAbsolutePosition()); + this.setVector3("planetPosition", this.planemoTransform.getAbsolutePosition()); this.updateConstants(); } public updateConstants(): void { - this.setFloat("planetRadius", this.planetRadius); + this.setFloat("planetRadius", this.planemoModel.radius); this.setInt("colorMode", this.colorSettings.mode); - this.setFloat("waterLevel", this.physicalProperties.oceanLevel); + this.setFloat("waterLevel", this.planemoModel.physicalProperties.oceanLevel); this.setFloat("beachSize", this.colorSettings.beachSize); this.setFloat("steepSharpness", this.colorSettings.steepSharpness); @@ -146,17 +159,20 @@ export class TelluricPlanemoMaterial extends ShaderMaterial { this.setTexture("beachNormalMap", Assets.SandNormalMap1); this.setTexture("desertNormalMap", Assets.SandNormalMap2); - this.setFloat("minTemperature", this.physicalProperties.minTemperature); - this.setFloat("maxTemperature", this.physicalProperties.maxTemperature); - this.setFloat("pressure", this.physicalProperties.pressure); - this.setFloat("waterAmount", this.physicalProperties.waterAmount); + this.setFloat("minTemperature", this.planemoModel.physicalProperties.minTemperature); + this.setFloat("maxTemperature", this.planemoModel.physicalProperties.maxTemperature); + this.setFloat("pressure", this.planemoModel.physicalProperties.pressure); + this.setFloat("waterAmount", this.planemoModel.physicalProperties.waterAmount); - this.setFloat("maxElevation", this.terrainSettings.continent_base_height + this.terrainSettings.max_mountain_height + this.terrainSettings.max_bump_height); + this.setFloat( + "maxElevation", + this.planemoModel.terrainSettings.continent_base_height + this.planemoModel.terrainSettings.max_mountain_height + this.planemoModel.terrainSettings.max_bump_height + ); } public update(activeControllerPosition: Vector3, stellarObjects: StellarObject[]) { - this.setMatrix("normalMatrix", this.planet.getWorldMatrix().clone().invert().transpose()); - this.setMatrix("planetInverseRotationMatrix", getInverseRotationMatrix(this.planet)); + this.setMatrix("normalMatrix", this.planemoTransform.getWorldMatrix().clone().invert().transpose()); + this.setMatrix("planetInverseRotationMatrix", getInverseRotationMatrix(this.planemoTransform)); this.setVector3("playerPosition", activeControllerPosition); @@ -167,6 +183,6 @@ export class TelluricPlanemoMaterial extends ShaderMaterial { } this.setInt("nbStars", stellarObjects.length); - this.setVector3("planetPosition", this.planet.getAbsolutePosition()); + this.setVector3("planetPosition", this.planemoTransform.getAbsolutePosition()); } } diff --git a/src/ts/view/postProcesses/flatCloudsPostProcess.ts b/src/ts/view/postProcesses/flatCloudsPostProcess.ts index d54945fc7..9ac16a847 100644 --- a/src/ts/view/postProcesses/flatCloudsPostProcess.ts +++ b/src/ts/view/postProcesses/flatCloudsPostProcess.ts @@ -11,11 +11,7 @@ import { TelluricPlanemo } from "../bodies/planemos/telluricPlanemo"; import { ObjectPostProcess } from "./objectPostProcess"; import { StellarObject } from "../bodies/stellarObjects/stellarObject"; import { getInverseRotationQuaternion } from "../../controller/uberCore/transforms/basicTransform"; -import { - UniformEnumType, - ShaderSamplers, - ShaderUniforms, -} from "../../controller/uberCore/postProcesses/types"; +import { UniformEnumType, ShaderSamplers, ShaderUniforms } from "../../controller/uberCore/postProcesses/types"; const shaderName = "flatClouds"; Effect.ShadersStore[`${shaderName}FragmentShader`] = flatCloudsFragment; @@ -129,7 +125,9 @@ export class FlatCloudsPostProcess extends UberPostProcess implements ObjectPost name: "time", type: UniformEnumType.Float, get: () => { - return -this.internalTime % ((2 * Math.PI * gcd(this.cloudUniforms.worleySpeed * 10000, this.cloudUniforms.detailSpeed * 10000)) / this.cloudUniforms.worleySpeed); + return ( + -this.internalTime % ((2 * Math.PI * gcd(this.cloudUniforms.worleySpeed * 10000, this.cloudUniforms.detailSpeed * 10000)) / this.cloudUniforms.worleySpeed) + ); } } ]; diff --git a/src/ts/view/postProcesses/lensFlarePostProcess.ts b/src/ts/view/postProcesses/lensFlarePostProcess.ts index 46720cd09..2cef66a2c 100644 --- a/src/ts/view/postProcesses/lensFlarePostProcess.ts +++ b/src/ts/view/postProcesses/lensFlarePostProcess.ts @@ -15,7 +15,7 @@ const shaderName = "lensflare"; Effect.ShadersStore[`${shaderName}FragmentShader`] = lensFlareFragment; export type LensFlareSettings = { - visibility: number + visibility: number; }; export class LensFlarePostProcess extends UberPostProcess implements ObjectPostProcess { @@ -49,9 +49,9 @@ export class LensFlarePostProcess extends UberPostProcess implements ObjectPostP (scene.getPhysicsEngine() as PhysicsEngineV2).raycastToRef(start, end, raycastResult); const occulted = raycastResult.hasHit && raycastResult.body?.transformNode.name !== object.name; - if(occulted && settings.visibility > 0) { + if (occulted && settings.visibility > 0) { settings.visibility = moveTowards(settings.visibility, 0, 0.5); - } else if(!occulted && settings.visibility < 1) { + } else if (!occulted && settings.visibility < 1) { settings.visibility = moveTowards(settings.visibility, 1, 0.5); } diff --git a/src/ts/view/postProcesses/mandelbulbPostProcess.ts b/src/ts/view/postProcesses/mandelbulbPostProcess.ts index e85d25507..b4b40056f 100644 --- a/src/ts/view/postProcesses/mandelbulbPostProcess.ts +++ b/src/ts/view/postProcesses/mandelbulbPostProcess.ts @@ -6,7 +6,7 @@ import { ObjectPostProcess } from "./objectPostProcess"; import { Effect } from "@babylonjs/core/Materials/effect"; import { Mandelbulb } from "../bodies/planemos/mandelbulb"; import { StellarObject } from "../bodies/stellarObjects/stellarObject"; -import {UniformEnumType, ShaderSamplers, ShaderUniforms} from "../../controller/uberCore/postProcesses/types"; +import { UniformEnumType, ShaderSamplers, ShaderUniforms } from "../../controller/uberCore/postProcesses/types"; const shaderName = "mandelbulb"; Effect.ShadersStore[`${shaderName}FragmentShader`] = mandelbulbFragment; diff --git a/src/ts/view/postProcesses/matterJetPostProcess.ts b/src/ts/view/postProcesses/matterJetPostProcess.ts index bb2e3b21d..5cea89389 100644 --- a/src/ts/view/postProcesses/matterJetPostProcess.ts +++ b/src/ts/view/postProcesses/matterJetPostProcess.ts @@ -7,7 +7,7 @@ import { StellarObject } from "../bodies/stellarObjects/stellarObject"; import { ObjectPostProcess } from "./objectPostProcess"; import { BaseObject } from "../common"; import { getForwardDirection } from "../../controller/uberCore/transforms/basicTransform"; -import {UniformEnumType, ShaderSamplers, ShaderUniforms} from "../../controller/uberCore/postProcesses/types"; +import { UniformEnumType, ShaderSamplers, ShaderUniforms } from "../../controller/uberCore/postProcesses/types"; const shaderName = "matterjet"; Effect.ShadersStore[`${shaderName}FragmentShader`] = matterJetFragment; @@ -52,12 +52,10 @@ export class MatterJetPostProcess extends UberPostProcess implements ObjectPostP get: () => { return stellarObject.getRotationAxis(); } - }, + } ]; - const samplers: ShaderSamplers = [ - ...getSamplers(scene) - ]; + const samplers: ShaderSamplers = [...getSamplers(scene)]; super(name, shaderName, uniforms, samplers, scene); diff --git a/src/ts/view/postProcesses/oceanPostProcess.ts b/src/ts/view/postProcesses/oceanPostProcess.ts index 922df263f..56b5b0646 100644 --- a/src/ts/view/postProcesses/oceanPostProcess.ts +++ b/src/ts/view/postProcesses/oceanPostProcess.ts @@ -22,7 +22,7 @@ export type OceanUniforms = { depthModifier: number; alphaModifier: number; waveBlendingSharpness: number; -} +}; export class OceanPostProcess extends UberPostProcess implements ObjectPostProcess { readonly oceanUniforms: OceanUniforms; diff --git a/src/ts/view/postProcesses/overlayPostProcess.ts b/src/ts/view/postProcesses/overlayPostProcess.ts index e97f1cf05..9cec5a844 100644 --- a/src/ts/view/postProcesses/overlayPostProcess.ts +++ b/src/ts/view/postProcesses/overlayPostProcess.ts @@ -5,7 +5,7 @@ import { UberPostProcess } from "../../controller/uberCore/postProcesses/uberPos import { ObjectPostProcess } from "./objectPostProcess"; import { Effect } from "@babylonjs/core/Materials/effect"; import { BaseObject } from "../common"; -import {UniformEnumType, ShaderUniforms} from "../../controller/uberCore/postProcesses/types"; +import { UniformEnumType, ShaderUniforms } from "../../controller/uberCore/postProcesses/types"; const shaderName = "overlay"; Effect.ShadersStore[`${shaderName}FragmentShader`] = overlayFragment; diff --git a/src/ts/view/postProcesses/postProcessTypes.ts b/src/ts/view/postProcesses/postProcessTypes.ts index b9cbaae04..447536916 100644 --- a/src/ts/view/postProcesses/postProcessTypes.ts +++ b/src/ts/view/postProcesses/postProcessTypes.ts @@ -9,5 +9,5 @@ export enum PostProcessType { BLACK_HOLE, SHADOW, OVERLAY, - LENS_FLARE, + LENS_FLARE } diff --git a/src/ts/view/postProcesses/ringsPostProcess.ts b/src/ts/view/postProcesses/ringsPostProcess.ts index 68b33effb..2b94e01f9 100644 --- a/src/ts/view/postProcesses/ringsPostProcess.ts +++ b/src/ts/view/postProcesses/ringsPostProcess.ts @@ -26,7 +26,7 @@ export class RingsPostProcess extends UberPostProcess implements ObjectPostProce ...getObjectUniforms(body), ...getStellarObjectsUniforms(stellarObjects), ...getActiveCameraUniforms(scene), - ...ringsUniforms.getShaderUniforms(), + ...ringsUniforms.getShaderUniforms() ]; super(body.name + "Rings", shaderName, uniforms, getSamplers(scene), scene); diff --git a/src/ts/view/postProcesses/starfieldPostProcess.ts b/src/ts/view/postProcesses/starfieldPostProcess.ts index c21f178c8..4b1e9b335 100644 --- a/src/ts/view/postProcesses/starfieldPostProcess.ts +++ b/src/ts/view/postProcesses/starfieldPostProcess.ts @@ -13,12 +13,7 @@ import { Effect } from "@babylonjs/core/Materials/effect"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { PostProcessType } from "./postProcessTypes"; import { Axis } from "@babylonjs/core/Maths/math.axis"; -import { - SamplerEnumType, - ShaderSamplers, - ShaderUniforms, - UniformEnumType -} from "../../controller/uberCore/postProcesses/types"; +import { SamplerEnumType, ShaderSamplers, ShaderUniforms, UniformEnumType } from "../../controller/uberCore/postProcesses/types"; import { Matrix, Quaternion } from "@babylonjs/core/Maths/math"; const shaderName = "starfield"; @@ -26,7 +21,6 @@ Effect.ShadersStore[`${shaderName}FragmentShader`] = starfieldFragment; export class StarfieldPostProcess extends UberPostProcess { constructor(scene: UberScene, stellarObjects: StellarObject[], bodies: AbstractBody[], starfieldRotation: Quaternion) { - const uniforms: ShaderUniforms = [ ...getActiveCameraUniforms(scene), ...getStellarObjectsUniforms(stellarObjects), diff --git a/src/ts/view/postProcesses/volumetricCloudsPostProcess.ts b/src/ts/view/postProcesses/volumetricCloudsPostProcess.ts index 2485101a3..5a5765151 100644 --- a/src/ts/view/postProcesses/volumetricCloudsPostProcess.ts +++ b/src/ts/view/postProcesses/volumetricCloudsPostProcess.ts @@ -9,7 +9,7 @@ import { ObjectPostProcess } from "./objectPostProcess"; import { CloudUniforms, FlatCloudsPostProcess } from "./flatCloudsPostProcess"; import { Effect } from "@babylonjs/core/Materials/effect"; import { Color3 } from "@babylonjs/core/Maths/math.color"; -import {UniformEnumType, ShaderSamplers, ShaderUniforms} from "../../controller/uberCore/postProcesses/types"; +import { UniformEnumType, ShaderSamplers, ShaderUniforms } from "../../controller/uberCore/postProcesses/types"; const shaderName = "volumetricClouds"; Effect.ShadersStore[`${shaderName}FragmentShader`] = volumetricCloudsFragment; From 9ef6ee95fb4dac163df2f5aa0d8160e4ea65abb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 3 Nov 2023 13:46:53 +0100 Subject: [PATCH 68/86] fixed speed display bug when out of hyperspace + force of mainthrusters do not generate any rotation --- src/ts/blackHoleDemo.ts | 2 +- src/ts/index.ts | 2 +- src/ts/randomizer.ts | 2 +- src/ts/spaceship/mainThruster.ts | 6 +++--- src/ts/ui/helmetOverlay.ts | 1 - 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/ts/blackHoleDemo.ts b/src/ts/blackHoleDemo.ts index 36f28b204..b67f606b7 100644 --- a/src/ts/blackHoleDemo.ts +++ b/src/ts/blackHoleDemo.ts @@ -55,7 +55,7 @@ engine.registerStarSystemUpdateCallback(() => { const throttleString = warpDrive.isEnabled() ? `${parsePercentageFrom01(shipInternalThrottle)}/${parsePercentageFrom01(shipTargetThrottle)}` - : spaceshipController.getThrottle(); + : `${parsePercentageFrom01(spaceshipController.getThrottle())}/100%`; (document.querySelector("#speedometer") as HTMLElement).innerHTML = `${throttleString} | ${parseSpeed(spaceshipController.getSpeed())}`; }); diff --git a/src/ts/index.ts b/src/ts/index.ts index fcc32df40..f52d1da2c 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -74,7 +74,7 @@ engine.registerStarSystemUpdateCallback(() => { const throttleString = warpDrive.isEnabled() ? `${parsePercentageFrom01(shipInternalThrottle)}/${parsePercentageFrom01(shipTargetThrottle)}` - : spaceshipController.getThrottle(); + : `${parsePercentageFrom01(spaceshipController.getThrottle())}/100%`; (document.querySelector("#speedometer") as HTMLElement).innerHTML = `${throttleString} | ${parseSpeed(spaceshipController.getSpeed())}`; }); diff --git a/src/ts/randomizer.ts b/src/ts/randomizer.ts index c83a99e0d..158a29828 100644 --- a/src/ts/randomizer.ts +++ b/src/ts/randomizer.ts @@ -56,7 +56,7 @@ engine.registerStarSystemUpdateCallback(() => { const throttleString = warpDrive.isEnabled() ? `${parsePercentageFrom01(shipInternalThrottle)}/${parsePercentageFrom01(shipTargetThrottle)}` - : spaceshipController.getThrottle(); + : `${parsePercentageFrom01(spaceshipController.getThrottle())}/100%`; (document.querySelector("#speedometer") as HTMLElement).innerHTML = `${throttleString} | ${parseSpeed(spaceshipController.getSpeed())}`; }); diff --git a/src/ts/spaceship/mainThruster.ts b/src/ts/spaceship/mainThruster.ts index 689d52d61..4fb21a218 100644 --- a/src/ts/spaceship/mainThruster.ts +++ b/src/ts/spaceship/mainThruster.ts @@ -2,7 +2,7 @@ import { Vector3 } from "@babylonjs/core/Maths/math"; import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; import { AbstractThruster } from "./abstractThruster"; import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; -import { getDownwardDirection, getForwardDirection, getUpwardDirection } from "../controller/uberCore/transforms/basicTransform"; +import { getDownwardDirection } from "../controller/uberCore/transforms/basicTransform"; export class MainThruster extends AbstractThruster { protected readonly maxAuthority = 3e3; @@ -21,9 +21,9 @@ export class MainThruster extends AbstractThruster { public applyForce(): void { const thrustDirection = getDownwardDirection(this.mesh); - const force = thrustDirection.scale(200 * this.throttle); + const force = thrustDirection.scale(this.maxAuthority * this.throttle); // make the ship spin (apply force at the position of the thruster then apply the same force at the center of mass in the opposite direction) - this.parentAggregate.body.applyForce(force, this.mesh.getAbsolutePosition()); + this.parentAggregate.body.applyForce(force, this.parentAggregate.body.getObjectCenterWorld()); } } diff --git a/src/ts/ui/helmetOverlay.ts b/src/ts/ui/helmetOverlay.ts index 07d4bb3ed..910c38f20 100644 --- a/src/ts/ui/helmetOverlay.ts +++ b/src/ts/ui/helmetOverlay.ts @@ -1,5 +1,4 @@ import overlayHTML from "../../html/helmetOverlay.html"; -import { AbstractBody } from "../view/bodies/abstractBody"; import { AbstractObject } from "../view/bodies/abstractObject"; export class HelmetOverlay { From fcf583afc1b09cb7fc22f2d65cf522f4f9955e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Fri, 3 Nov 2023 14:51:02 +0100 Subject: [PATCH 69/86] more accurate ocean shader better handling of multiple stars --- src/shaders/oceanFragment.glsl | 60 +++++++++++++--------------------- src/ts/index.ts | 11 +++++-- 2 files changed, 30 insertions(+), 41 deletions(-) diff --git a/src/shaders/oceanFragment.glsl b/src/shaders/oceanFragment.glsl index 10e5d1c8a..48235c0b5 100644 --- a/src/shaders/oceanFragment.glsl +++ b/src/shaders/oceanFragment.glsl @@ -60,6 +60,8 @@ vec4 oceanColor(vec4 originalColor, vec3 rayOrigin, vec3 rayDir, float maximumDi float distanceThroughOcean = max(0.0, escapePoint - impactPoint);// probably doesn't need the max but for the sake of coherence the distance cannot be negative + if (distanceThroughOcean <= 0.0) return originalColor; + vec3 samplePoint = rayOrigin + impactPoint * rayDir - object.position; vec3 samplePointPlanetSpace = applyQuaternion(planetInverseRotationQuaternion, samplePoint); @@ -77,56 +79,38 @@ vec4 oceanColor(vec4 originalColor, vec3 rayOrigin, vec3 rayDir, float maximumDi normalWave = triplanarNormal(samplePointPlanetSpace + vec3(time, -time, -time) * 500.0, normalWave, normalMap2, 0.000010, ocean.waveBlendingSharpness, 0.5); normalWave = triplanarNormal(samplePointPlanetSpace + vec3(-time, -time, time) * 500.0, normalWave, normalMap1, 0.000005, ocean.waveBlendingSharpness, 0.5); - //normalWave = triplanarNormal(samplePointPlanetSpace + vec3(time, -time, -time) * 500.0, normalWave, normalMap1, 0.000001, ocean.waveBlendingSharpness, 0.2); - //normalWave = triplanarNormal(samplePointPlanetSpace + vec3(-time, -time, time) * 500.0, normalWave, normalMap2, 0.0000005, ocean.waveBlendingSharpness, 0.2); + float opticalDepth01 = 1.0 - exp(-distanceThroughOcean * ocean.depthModifier); + float alpha = exp(-distanceThroughOcean * ocean.alphaModifier); + + //vec3 oceanColor = lerp(vec3(10.0, 100.0, 249.0)/255.0, vec3(15.0,94.0,156.0)/255.0, opticalDepth01); + + vec3 deepColor = vec3(0.0, 22.0, 82.0)/255.0; + vec3 shallowColor = vec3(32.0, 193.0, 180.0)/255.0; + vec3 oceanColor = mix(shallowColor, deepColor, opticalDepth01) * stars[0].color; + + vec3 ambiant = mix(oceanColor, originalColor.rgb, alpha); - float ndl = 0.0; - vec3 specularHighlight = vec3(0.0); + float foamSize = 30.0; + float foamFactor = saturate((foamSize - distanceThroughOcean) / foamSize); + vec3 foamColor = vec3(0.8); + ambiant = mix(ambiant, foamColor, foamFactor); + vec3 finalColor = vec3(0.0); for (int i = 0; i < nbStars; i++) { vec3 sunDir = normalize(stars[i].position - samplePoint); - float ndl1 = max(dot(normalWave, sunDir), 0.0);// dimming factor due to light inclination relative to vertex normal in world space - float ndl2 = max(dot(planetNormal, sunDir), 0.0); - - ndl += sqrt(ndl1 * ndl2); + float ndl = max(dot(planetNormal, sunDir), 0.0); + finalColor += ambiant * ndl; if (length(rayOrigin - object.position) > ocean.radius) { - // if above cloud coverage then specular highlight - specularHighlight += computeSpecularHighlight(sunDir, rayDir, normalWave, ocean.smoothness, ocean.specularPower) * stars[i].color; + // if above ocean surface then specular highlight + finalColor += computeSpecularHighlight(sunDir, rayDir, normalWave, ocean.smoothness, ocean.specularPower) * stars[i].color; } } - ndl = saturate(ndl); - specularHighlight = clamp(specularHighlight, vec3(0.0), vec3(1.0)); - - if (distanceThroughOcean > 0.0) { - float opticalDepth01 = 1.0 - exp(-distanceThroughOcean * ocean.depthModifier); - float alpha = exp(-distanceThroughOcean * ocean.alphaModifier); - - //vec3 oceanColor = lerp(vec3(10.0, 100.0, 249.0)/255.0, vec3(15.0,94.0,156.0)/255.0, opticalDepth01); - - vec3 deepColor = vec3(0.0, 22.0, 82.0)/255.0; - vec3 shallowColor = vec3(32.0, 193.0, 180.0)/255.0; - vec3 oceanColor = mix(shallowColor, deepColor, opticalDepth01) * stars[0].color; - - vec3 ambiant = mix(oceanColor, originalColor.rgb, alpha); - - float foamSize = 30.0; - float foamFactor = saturate((foamSize - distanceThroughOcean) / foamSize); - vec3 foamColor = vec3(0.8); - ambiant = mix(ambiant, foamColor, foamFactor); - - vec3 finalColor = ambiant * ndl + specularHighlight; - - return vec4(finalColor, 1.0); - } - - return originalColor; + return vec4(finalColor, 1.0); } - - void main() { vec4 screenColor = texture2D(textureSampler, vUV);// the current screen color diff --git a/src/ts/index.ts b/src/ts/index.ts index f52d1da2c..026c076f2 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -99,9 +99,14 @@ const sun = StarSystemHelper.makeStar(starSystem, sunModel); sun.model.orbit.period = 60 * 60 * 24; /*const secundaModel = new StarModel(-672446, sunModel); -secundaModel.orbitalProperties.radius = 4 * sunModel.radius; -secundaModel.orbitalProperties.period = 60 * 60 * 24 * 365.25; -const secunda = starSystem.makeStar(secundaModel);*/ +secundaModel.orbit.radius = 30 * sunModel.radius; +secundaModel.orbit.period = 60; +const secunda = StarSystemHelper.makeStar(starSystem, secundaModel); + +const terminaModel = new StarModel(756263, sunModel); +terminaModel.orbit.radius = 50 * sunModel.radius; +terminaModel.orbit.period = 60 * 10; +const termina = StarSystemHelper.makeStar(starSystem, terminaModel);*/ const planetModel = new TelluricPlanemoModel(0.4233609183800225, sunModel); planetModel.physicalProperties.minTemperature = -37; From 72f9501d323747a276477bc21b6c12d06b211e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:33:36 +0100 Subject: [PATCH 70/86] fixed systemui creating a black screen It is probably caused by the html ui resizing the canvas --- src/ts/controller/spaceEngine.ts | 4 ++-- src/ts/ui/systemUI.ts | 17 ++--------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/src/ts/controller/spaceEngine.ts b/src/ts/controller/spaceEngine.ts index f2a11445c..a0f3c9a44 100644 --- a/src/ts/controller/spaceEngine.ts +++ b/src/ts/controller/spaceEngine.ts @@ -239,8 +239,6 @@ export class SpaceEngine { const ambientLight = new HemisphericLight("ambientLight", Vector3.Zero(), this.starSystemScene); ambientLight.intensity = 0.3; - this.starSystemUI = new SystemUI(this.starSystemScene); - this.havokPlugin = new HavokPlugin(true, havokInstance); this.starSystemScene.enablePhysics(Vector3.Zero(), this.havokPlugin); @@ -287,6 +285,8 @@ export class SpaceEngine { this.bodyEditor.setVisibility(EditorVisibility.HIDDEN); this.helmetOverlay.setVisibility(false); + this.starSystemUI = new SystemUI(this.getStarSystemScene()); + this.activeScene = this.starMap.scene; } diff --git a/src/ts/ui/systemUI.ts b/src/ts/ui/systemUI.ts index a732693f2..7e2711be7 100644 --- a/src/ts/ui/systemUI.ts +++ b/src/ts/ui/systemUI.ts @@ -1,22 +1,9 @@ import { Scene } from "@babylonjs/core/scene"; import { AdvancedDynamicTexture } from "@babylonjs/gui/2D/advancedDynamicTexture"; -import { TextBlock } from "@babylonjs/gui/2D/controls/textBlock"; export class SystemUI { - //private gui: AdvancedDynamicTexture; + private readonly gui: AdvancedDynamicTexture; constructor(scene: Scene) { - //this.gui = AdvancedDynamicTexture.CreateFullscreenUI("SystemUI", true, scene); - //console.log(this.gui); - // display system name - /*const name = new TextBlock(); - name.text = "System Name"; - name.color = "white"; - name.fontSize = 24; - name.fontWeight = "bold"; - name.textHorizontalAlignment = TextBlock.HORIZONTAL_ALIGNMENT_LEFT; - name.textVerticalAlignment = TextBlock.VERTICAL_ALIGNMENT_TOP; - name.paddingLeft = "10px"; - name.paddingTop = "10px"; - this.gui.addControl(name);*/ + this.gui = AdvancedDynamicTexture.CreateFullscreenUI("SystemUI", true, scene); } } From 6c6136af2dddfe51e1c8440a1d5875f6760c3694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:33:53 +0100 Subject: [PATCH 71/86] cleaning --- src/ts/controller/assets.ts | 2 -- src/ts/controller/uberCore/transforms/basicTransform.ts | 8 ++++---- tests/unit/basicTransform.test.ts | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/ts/controller/assets.ts b/src/ts/controller/assets.ts index 5a688a168..6e8a08da7 100644 --- a/src/ts/controller/assets.ts +++ b/src/ts/controller/assets.ts @@ -34,9 +34,7 @@ import { AssetsManager, MeshAssetTask } from "@babylonjs/core/Misc/assetsManager import { Scene } from "@babylonjs/core/scene"; import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; import { Color3 } from "@babylonjs/core/Maths/math.color"; -import { PBRBaseMaterial } from "@babylonjs/core/Materials/PBR/pbrBaseMaterial"; import { InstancedMesh } from "@babylonjs/core/Meshes/instancedMesh"; -import { TransformNode } from "@babylonjs/core/Meshes"; import "@babylonjs/core/Audio/audioEngine"; import "@babylonjs/core/Audio/audioSceneComponent"; import { Sound } from "@babylonjs/core/Audio/sound"; diff --git a/src/ts/controller/uberCore/transforms/basicTransform.ts b/src/ts/controller/uberCore/transforms/basicTransform.ts index 14119d72f..e44ffe32c 100644 --- a/src/ts/controller/uberCore/transforms/basicTransform.ts +++ b/src/ts/controller/uberCore/transforms/basicTransform.ts @@ -59,8 +59,8 @@ export function getInverseRotationMatrix(transformNode: TransformNode): Matrix { /* #region directions */ /** - * - * @returns the unit vector pointing forward the player controler in world space + * This is not equivalent to transform.forward as CosmosJourneyer uses the right-handed coordinate system + * @returns the forward vector of the given transform in world space */ export function getForwardDirection(transformNode: TransformNode): Vector3 { return transformNode.getDirection(Axis.Z); @@ -68,7 +68,7 @@ export function getForwardDirection(transformNode: TransformNode): Vector3 { /** * - * @returns the unit vector pointing backward the player controler in world space + * @returns the unit vector pointing backward the player controller in world space */ export function getBackwardDirection(transformNode: TransformNode): Vector3 { return getForwardDirection(transformNode).negate(); @@ -76,7 +76,7 @@ export function getBackwardDirection(transformNode: TransformNode): Vector3 { /** * - * @returns the unit vector pointing upward the player controler in world space + * @returns the unit vector pointing upward the player controller in world space */ export function getUpwardDirection(transformNode: TransformNode): Vector3 { return transformNode.getDirection(Axis.Y); diff --git a/tests/unit/basicTransform.test.ts b/tests/unit/basicTransform.test.ts index d2d0f0869..857d62b56 100644 --- a/tests/unit/basicTransform.test.ts +++ b/tests/unit/basicTransform.test.ts @@ -1,8 +1,8 @@ import { Scene } from "@babylonjs/core/scene"; -import { Vector3, Quaternion } from "@babylonjs/core/Maths/math"; +import { Vector3 } from "@babylonjs/core/Maths/math"; import { NullEngine } from "@babylonjs/core/Engines/nullEngine"; import { TransformNode } from "@babylonjs/core/Meshes"; -import { getBackwardDirection, getForwardDirection, getLeftDirection, getRightDirection, getRotationQuaternion, translate } from "../../src/ts/controller/uberCore/transforms/basicTransform"; +import { getBackwardDirection, getForwardDirection, getLeftDirection, getRightDirection, translate } from "../../src/ts/controller/uberCore/transforms/basicTransform"; const engine = new NullEngine(); const scene = new Scene(engine); From 4bec4f86e8926099fcf22ab751f65079362af7a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:50:47 +0100 Subject: [PATCH 72/86] aggregates are now part of any abstractobject --- src/ts/view/bodies/abstractObject.ts | 16 ++++++++++++++++ src/ts/view/bodies/planemos/gasPlanet.ts | 17 +---------------- src/ts/view/bodies/planemos/telluricPlanemo.ts | 14 -------------- src/ts/view/bodies/stellarObjects/star.ts | 14 -------------- 4 files changed, 17 insertions(+), 44 deletions(-) diff --git a/src/ts/view/bodies/abstractObject.ts b/src/ts/view/bodies/abstractObject.ts index a8f5ecdb8..deedd69ad 100644 --- a/src/ts/view/bodies/abstractObject.ts +++ b/src/ts/view/bodies/abstractObject.ts @@ -7,10 +7,14 @@ import { Cullable } from "./cullable"; import { TransformNode } from "@babylonjs/core/Meshes"; import { getRotationQuaternion, rotateAround, setRotationQuaternion, translate } from "../../controller/uberCore/transforms/basicTransform"; import { Camera } from "@babylonjs/core/Cameras/camera"; +import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; +import { PhysicsShapeType } from "@babylonjs/core"; export abstract class AbstractObject implements OrbitalObject, BaseObject, Cullable { private readonly transform: TransformNode; + readonly aggregate: PhysicsAggregate; + readonly postProcesses: PostProcessType[] = []; //TODO: make an universal clock ?? or not it could be funny @@ -34,6 +38,18 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla this.parentObject = parentObject ?? null; this.transform = new TransformNode(name, scene); + + this.aggregate = new PhysicsAggregate( + this.getTransform(), + PhysicsShapeType.CONTAINER, + { + mass: 0, + restitution: 0.2 + }, + scene + ); + this.aggregate.body.setMassProperties({ inertia: Vector3.Zero(), mass: 0 }); + this.aggregate.body.disablePreStep = false; } public getTransform(): TransformNode { diff --git a/src/ts/view/bodies/planemos/gasPlanet.ts b/src/ts/view/bodies/planemos/gasPlanet.ts index 411b8e25e..07eae239f 100644 --- a/src/ts/view/bodies/planemos/gasPlanet.ts +++ b/src/ts/view/bodies/planemos/gasPlanet.ts @@ -11,16 +11,13 @@ import { Mesh } from "@babylonjs/core/Meshes/mesh"; import { PostProcessType } from "../../postProcesses/postProcessTypes"; import { isSizeOnScreenEnough } from "../../../utils/isObjectVisibleOnScreen"; import { Camera } from "@babylonjs/core/Cameras/camera"; -import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; -import { PhysicsShapeSphere, PhysicsShapeType } from "@babylonjs/core"; +import { PhysicsShapeSphere } from "@babylonjs/core"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; export class GasPlanet extends AbstractBody implements Planemo, PlanemoMaterial { private readonly mesh: Mesh; readonly material: GasPlanetMaterial; - readonly aggregate: PhysicsAggregate; - readonly model: GasPlanetModel; /** @@ -45,18 +42,6 @@ export class GasPlanet extends AbstractBody implements Planemo, PlanemoMaterial ); this.mesh.parent = this.getTransform(); - this.aggregate = new PhysicsAggregate( - this.getTransform(), - PhysicsShapeType.CONTAINER, - { - mass: 0, - restitution: 0.2 - }, - scene - ); - this.aggregate.body.setMassProperties({ inertia: Vector3.Zero(), mass: 0 }); - this.aggregate.body.disablePreStep = false; - const physicsShape = new PhysicsShapeSphere(Vector3.Zero(), this.model.radius, scene); this.aggregate.shape.addChildFromParent(this.getTransform(), physicsShape, this.mesh); diff --git a/src/ts/view/bodies/planemos/telluricPlanemo.ts b/src/ts/view/bodies/planemos/telluricPlanemo.ts index 47ca37501..ac9d68101 100644 --- a/src/ts/view/bodies/planemos/telluricPlanemo.ts +++ b/src/ts/view/bodies/planemos/telluricPlanemo.ts @@ -25,8 +25,6 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat readonly model: TelluricPlanemoModel; - readonly aggregate: PhysicsAggregate; - /** * New Telluric Planet * @param name The name of the planet @@ -62,18 +60,6 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat this.material = new TelluricPlanemoMaterial(this.name, this.getTransform(), this.model, scene); - this.aggregate = new PhysicsAggregate( - this.getTransform(), - PhysicsShapeType.CONTAINER, - { - mass: 0, - restitution: 0.2 - }, - scene - ); - this.aggregate.body.setMassProperties({ inertia: Vector3.Zero(), mass: 0 }); - this.aggregate.body.disablePreStep = false; - const physicsShape = new PhysicsShapeSphere(Vector3.Zero(), this.model.radius, scene); this.aggregate.shape.addChildFromParent(this.getTransform(), physicsShape, this.getTransform()); diff --git a/src/ts/view/bodies/stellarObjects/star.ts b/src/ts/view/bodies/stellarObjects/star.ts index 1a664c5c8..0a57f51e0 100644 --- a/src/ts/view/bodies/stellarObjects/star.ts +++ b/src/ts/view/bodies/stellarObjects/star.ts @@ -23,8 +23,6 @@ export class Star extends AbstractBody { readonly model: StarModel; - readonly aggregate: PhysicsAggregate; - /** * New Star * @param name The name of the star @@ -50,18 +48,6 @@ export class Star extends AbstractBody { : Assets.CreateBananaClone(this.model.radius * 2); this.mesh.parent = this.getTransform(); - this.aggregate = new PhysicsAggregate( - this.getTransform(), - PhysicsShapeType.CONTAINER, - { - mass: 0, - restitution: 0.2 - }, - scene - ); - this.aggregate.body.setMassProperties({ inertia: Vector3.Zero(), mass: 0 }); - this.aggregate.body.disablePreStep = false; - const physicsShape = new PhysicsShapeSphere(Vector3.Zero(), this.model.radius, scene); this.aggregate.shape.addChildFromParent(this.getTransform(), physicsShape, this.mesh); From 64b37cf8a2969ba6118ef5aa6da7015f285b0ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:51:08 +0100 Subject: [PATCH 73/86] nearest object is only computed once --- src/ts/blackHoleDemo.ts | 2 +- src/ts/controller/spaceEngine.ts | 11 ++++------- src/ts/controller/starSystem.ts | 18 +++++++++++++----- src/ts/index.ts | 6 +++--- src/ts/randomizer.ts | 2 +- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/ts/blackHoleDemo.ts b/src/ts/blackHoleDemo.ts index b67f606b7..5488f67dc 100644 --- a/src/ts/blackHoleDemo.ts +++ b/src/ts/blackHoleDemo.ts @@ -44,7 +44,7 @@ engine.registerStarSystemUpdateCallback(() => { if (scene.getActiveController() != spaceshipController) return; const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); - const nearestBody = engine.getStarSystem().getNearestOrbitalObject(shipPosition); + const nearestBody = engine.getStarSystem().getNearestOrbitalObject(); const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); const radius = nearestBody.getBoundingRadius(); spaceshipController.registerClosestObject(distance, radius); diff --git a/src/ts/controller/spaceEngine.ts b/src/ts/controller/spaceEngine.ts index a0f3c9a44..7df9e8565 100644 --- a/src/ts/controller/spaceEngine.ts +++ b/src/ts/controller/spaceEngine.ts @@ -259,19 +259,16 @@ export class SpaceEngine { const deltaTime = this.getEngine().getDeltaTime() / 1000; - const nearestBody = starSystem.getNearestOrbitalObject(starSystemScene.getActiveUberCamera().position); + Assets.ChunkForge.update(); + starSystem.update(deltaTime * Settings.TIME_MULTIPLIER); + + const nearestBody = starSystem.getNearestOrbitalObject(); if (nearestBody instanceof AbstractBody) { this.bodyEditor.update(nearestBody, starSystem.postProcessManager, starSystemScene); } this.helmetOverlay.update(nearestBody); - //FIXME: should address stars orbits - for (const star of starSystem.stellarObjects) star.model.orbit.period = 0; - - Assets.ChunkForge.update(); - starSystem.update(deltaTime * Settings.TIME_MULTIPLIER); - this.orbitRenderer.update(); }); diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index de40ba707..ad571b3eb 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -66,6 +66,8 @@ export class StarSystem { */ readonly model: StarSystemModel; + private nearestOrbitalObject: AbstractObject | null = null; + constructor(model: StarSystemModel | number, scene: UberScene) { this.scene = scene; this.postProcessManager = new PostProcessManager(this.scene); @@ -162,10 +164,7 @@ export class StarSystem { return this.celestialBodies; } - /** - * Returns the nearest orbital object to the origin - */ - public getNearestOrbitalObject(position: Vector3): AbstractObject { + public computeNearestOrbitalObject(position: Vector3): void { if (this.celestialBodies.length + this.spaceStations.length === 0) throw new Error("There are no bodies or spacestation in the solar system"); let nearest = null; let smallerDistance = -1; @@ -185,6 +184,14 @@ export class StarSystem { smallerDistance = distance; } } + this.nearestOrbitalObject = nearest; + } + + /** + * Returns the nearest orbital object to the origin + */ + public getNearestOrbitalObject(): AbstractObject { + const nearest = this.nearestOrbitalObject; if (nearest === null) throw new Error("There are no bodies in the solar system"); return nearest; } @@ -294,7 +301,8 @@ export class StarSystem { */ public update(deltaTime: number): void { const controller = this.scene.getActiveController(); - const nearestBody = this.getNearestOrbitalObject(this.scene.getActiveUberCamera().position); + this.computeNearestOrbitalObject(controller.getActiveCamera().getAbsolutePosition()); + const nearestBody = this.getNearestOrbitalObject(); const distanceOfNearestToCamera = Vector3.Distance(nearestBody.getTransform().getAbsolutePosition(), controller.getActiveCamera().getAbsolutePosition()); const shouldCompensateTranslation = distanceOfNearestToCamera < nearestBody.getBoundingRadius() * 10; diff --git a/src/ts/index.ts b/src/ts/index.ts index 026c076f2..55e558323 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -63,7 +63,7 @@ engine.registerStarSystemUpdateCallback(() => { if (scene.getActiveController() != spaceshipController) return; const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); - const nearestBody = engine.getStarSystem().getNearestOrbitalObject(shipPosition); + const nearestBody = engine.getStarSystem().getNearestOrbitalObject(); const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); const radius = nearestBody.getBoundingRadius(); spaceshipController.registerClosestObject(distance, radius); @@ -100,12 +100,12 @@ sun.model.orbit.period = 60 * 60 * 24; /*const secundaModel = new StarModel(-672446, sunModel); secundaModel.orbit.radius = 30 * sunModel.radius; -secundaModel.orbit.period = 60; +secundaModel.orbit.period = 60 * 60; const secunda = StarSystemHelper.makeStar(starSystem, secundaModel); const terminaModel = new StarModel(756263, sunModel); terminaModel.orbit.radius = 50 * sunModel.radius; -terminaModel.orbit.period = 60 * 10; +terminaModel.orbit.period = 60 * 60; const termina = StarSystemHelper.makeStar(starSystem, terminaModel);*/ const planetModel = new TelluricPlanemoModel(0.4233609183800225, sunModel); diff --git a/src/ts/randomizer.ts b/src/ts/randomizer.ts index 158a29828..84c1e258e 100644 --- a/src/ts/randomizer.ts +++ b/src/ts/randomizer.ts @@ -45,7 +45,7 @@ engine.registerStarSystemUpdateCallback(() => { if (scene.getActiveController() != spaceshipController) return; const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); - const nearestBody = engine.getStarSystem().getNearestOrbitalObject(shipPosition); + const nearestBody = engine.getStarSystem().getNearestOrbitalObject(); const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); const radius = nearestBody.getBoundingRadius(); spaceshipController.registerClosestObject(distance, radius); From 26dd32d9bc31ff8aee7796659bee7ece5c4f1d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 16:28:04 +0100 Subject: [PATCH 74/86] better separation of concerns The spaceengine class is now much less bloated. The starsystem scene code has been moved to its own StarSystemView. Separation of concerns will need to be sorted out with the existing StarSystem class --- src/ts/blackHoleDemo.ts | 13 +- src/ts/controller/StarSystemView.ts | 161 +++++++++++++ src/ts/controller/spaceEngine.ts | 338 +++++++++------------------- src/ts/controller/starSystem.ts | 2 +- src/ts/index.ts | 39 ++-- src/ts/randomizer.ts | 15 +- src/ts/starmap/starMap.ts | 8 - 7 files changed, 300 insertions(+), 276 deletions(-) create mode 100644 src/ts/controller/StarSystemView.ts diff --git a/src/ts/blackHoleDemo.ts b/src/ts/blackHoleDemo.ts index 5488f67dc..462a58005 100644 --- a/src/ts/blackHoleDemo.ts +++ b/src/ts/blackHoleDemo.ts @@ -18,7 +18,9 @@ const engine = new SpaceEngine(); await engine.setup(); -const scene = engine.getStarSystemScene(); +const starSystemView = engine.getStarSystemView(); + +const scene = starSystemView.scene; const mouse = new Mouse(engine.canvas, 100); const keyboard = new Keyboard(); @@ -40,11 +42,10 @@ spaceshipController.addInput(gamepad); scene.setActiveController(spaceshipController); engine.registerStarSystemUpdateCallback(() => { - if (engine.isPaused()) return; if (scene.getActiveController() != spaceshipController) return; const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); - const nearestBody = engine.getStarSystem().getNearestOrbitalObject(); + const nearestBody = starSystemView.getStarSystem().getNearestOrbitalObject(); const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); const radius = nearestBody.getBoundingRadius(); spaceshipController.registerClosestObject(distance, radius); @@ -62,7 +63,7 @@ engine.registerStarSystemUpdateCallback(() => { const starSystemSeed = randRange(-1, 1, (step: number) => Math.random(), 0); const starSystem = new StarSystem(starSystemSeed, scene); -engine.setStarSystem(starSystem, false); +starSystemView.setStarSystem(starSystem, false); const BH = StarSystemHelper.makeBlackHole(starSystem, 0); BH.model.orbit.radius = 0; @@ -75,13 +76,13 @@ document.addEventListener("keydown", (e) => { if (scene.getActiveController() === spaceshipController) { scene.setActiveController(player); setRotationQuaternion(player.getTransform(), getRotationQuaternion(spaceshipController.getTransform()).clone()); - engine.getStarSystem().postProcessManager.rebuild(); + starSystemView.getStarSystem().postProcessManager.rebuild(); spaceshipController.setEnabled(false, engine.getHavokPlugin()); } else { scene.setActiveController(spaceshipController); setRotationQuaternion(spaceshipController.getTransform(), getRotationQuaternion(player.getTransform()).clone()); - engine.getStarSystem().postProcessManager.rebuild(); + starSystemView.getStarSystem().postProcessManager.rebuild(); spaceshipController.setEnabled(true, engine.getHavokPlugin()); } diff --git a/src/ts/controller/StarSystemView.ts b/src/ts/controller/StarSystemView.ts new file mode 100644 index 000000000..b7006586d --- /dev/null +++ b/src/ts/controller/StarSystemView.ts @@ -0,0 +1,161 @@ +import { HelmetOverlay } from "../ui/helmetOverlay"; +import { BodyEditor, EditorVisibility } from "../ui/bodyEditor/bodyEditor"; +import { UberScene } from "./uberCore/uberScene"; +import { OrbitRenderer } from "../view/orbitRenderer"; +import { AxisRenderer } from "../view/axisRenderer"; +import { SystemUI } from "../ui/systemUI"; +import { Animation } from "@babylonjs/core/Animations/animation"; +import { StarSystem } from "./starSystem"; +import { OverlayPostProcess } from "../view/postProcesses/overlayPostProcess"; +import { Engine } from "@babylonjs/core/Engines/engine"; +import { HavokPlugin } from "@babylonjs/core/Physics/v2/Plugins/havokPlugin"; +import { ScenePerformancePriority } from "@babylonjs/core/scene"; +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; +import { Vector3 } from "@babylonjs/core/Maths/math"; +import { Assets } from "./assets"; +import { Settings } from "../settings"; +import { AbstractBody } from "../view/bodies/abstractBody"; +import { StarSystemHelper } from "./starSystemHelper"; +import { positionNearObject } from "../utils/positionNearObject"; +import { BlackHole } from "../view/bodies/stellarObjects/blackHole"; +import { ShipController } from "../spaceship/shipController"; + +export class StarSystemView { + private readonly helmetOverlay: HelmetOverlay; + readonly bodyEditor: BodyEditor; + readonly scene: UberScene; + + private readonly orbitRenderer: OrbitRenderer = new OrbitRenderer(); + private readonly axisRenderer: AxisRenderer = new AxisRenderer(); + + private ui: SystemUI | null = null; + + private static readonly unZoomAnimation = new Animation("unZoom", "radius", 60, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CYCLE); + + private starSystem: StarSystem | null = null; + + constructor(engine: Engine, havokPlugin: HavokPlugin) { + this.helmetOverlay = new HelmetOverlay(); + this.bodyEditor = new BodyEditor(); + + const canvas = engine.getRenderingCanvas(); + if(canvas === null) throw new Error("Canvas is null"); + this.bodyEditor.setCanvas(canvas); + + StarSystemView.unZoomAnimation.setKeys([ + { + frame: 0, + value: 30 + }, + { + frame: 30, + value: 600 + } + ]); + + document.addEventListener("keydown", (e) => { + if (e.key === "o") OverlayPostProcess.ARE_ENABLED = !OverlayPostProcess.ARE_ENABLED; + if (e.key === "n") { + this.orbitRenderer.setVisibility(!this.orbitRenderer.isVisible()); + this.axisRenderer.setVisibility(!this.axisRenderer.isVisible()); + } + if (e.key === "u") this.bodyEditor.setVisibility(this.bodyEditor.getVisibility() === EditorVisibility.HIDDEN ? EditorVisibility.NAVBAR : EditorVisibility.HIDDEN); + if (e.key === "t") this.helmetOverlay.setVisibility(!this.helmetOverlay.isVisible()); + }); + + this.scene = new UberScene(engine, ScenePerformancePriority.Intermediate); + this.scene.clearColor = new Color4(0, 0, 0, 0); + this.scene.useRightHandedSystem = true; + + this.scene.enablePhysics(Vector3.Zero(), havokPlugin); + + const ambientLight = new HemisphericLight("ambientLight", Vector3.Zero(), this.scene); + ambientLight.intensity = 0.3; + + this.scene.onBeforePhysicsObservable.add(() => { + const starSystemScene = this.scene; + const starSystem = this.getStarSystem(); + + const deltaTime = engine.getDeltaTime() / 1000; + + Assets.ChunkForge.update(); + starSystem.update(deltaTime * Settings.TIME_MULTIPLIER); + + const nearestBody = starSystem.getNearestOrbitalObject(); + + if (nearestBody instanceof AbstractBody) { + this.bodyEditor.update(nearestBody, starSystem.postProcessManager, starSystemScene); + } + this.helmetOverlay.update(nearestBody); + + this.orbitRenderer.update(); + }); + + window.addEventListener("resize", () => { + this.bodyEditor.resize(); + }); + + this.bodyEditor.resize(); + + this.bodyEditor.setVisibility(EditorVisibility.HIDDEN); + this.helmetOverlay.setVisibility(false); + + this.ui = new SystemUI(this.scene); + } + + /** + * Returns the star system + * @returns the star system + * @throws Error if the star system is null + */ + getStarSystem() { + if (this.starSystem === null) throw new Error("Star system not initialized"); + return this.starSystem; + } + + /** + * Sets the star system and generates it if needed and disposes the old one. Does not perform the init method + * @param starSystem the star system to be set + * @param needsGenerating whether the star system needs to be generated or not + */ + setStarSystem(starSystem: StarSystem, needsGenerating = true) { + if (this.starSystem !== null) this.starSystem.dispose(); + this.starSystem = starSystem; + + if (needsGenerating) StarSystemHelper.generate(this.starSystem); + } + + init() { + this.getStarSystem().init(); + + const firstBody = this.getStarSystem().getBodies()[0]; + if (firstBody === undefined) throw new Error("No bodies in star system"); + + this.orbitRenderer.setOrbitalObjects(this.getStarSystem().getBodies()); + this.axisRenderer.setObjects(this.getStarSystem().getBodies()); + + const activeController = this.scene.getActiveController(); + positionNearObject(activeController, firstBody, this.getStarSystem(), firstBody instanceof BlackHole ? 7 : 5); + if (activeController instanceof ShipController) activeController.enableWarpDrive(); + } + + hideUI() { + this.bodyEditor.setVisibility(EditorVisibility.HIDDEN); + this.helmetOverlay.setVisibility(false); + } + + showUI() { + this.helmetOverlay.setVisibility(true); + this.bodyEditor.setVisibility(EditorVisibility.HIDDEN); + } + + unZoom(callback: () => void) { + this.scene.getActiveController().getActiveCamera().animations = [StarSystemView.unZoomAnimation]; + this.scene.beginAnimation(this.scene.getActiveController().getActiveCamera(), 0, 60, false, 2.0, () => { + this.scene.getActiveController().getActiveCamera().animations = []; + this.hideUI(); + callback(); + }); + } +} diff --git a/src/ts/controller/spaceEngine.ts b/src/ts/controller/spaceEngine.ts index 7df9e8565..b820dcc96 100644 --- a/src/ts/controller/spaceEngine.ts +++ b/src/ts/controller/spaceEngine.ts @@ -1,326 +1,149 @@ -import { HelmetOverlay } from "../ui/helmetOverlay"; -import { BodyEditor, EditorVisibility } from "../ui/bodyEditor/bodyEditor"; import { Assets } from "./assets"; -import { AbstractController } from "./uberCore/abstractController"; -import { UberScene } from "./uberCore/uberScene"; import { StarSystem } from "./starSystem"; -import { Settings } from "../settings"; -import { OverlayPostProcess } from "../view/postProcesses/overlayPostProcess"; import { Engine } from "@babylonjs/core/Engines/engine"; import { Tools } from "@babylonjs/core/Misc/tools"; import { VideoRecorder } from "@babylonjs/core/Misc/videoRecorder"; -import { WebGPUEngine } from "@babylonjs/core/Engines/webgpuEngine"; -import { Color4 } from "@babylonjs/core/Maths/math.color"; import "@babylonjs/core/Misc/screenshotTools"; import { StarMap } from "../starmap/starMap"; -import { Scene, ScenePerformancePriority } from "@babylonjs/core/scene"; -import { positionNearObject } from "../utils/positionNearObject"; +import { Scene } from "@babylonjs/core/scene"; import "@babylonjs/core/Physics/physicsEngineComponent"; import { HavokPlugin } from "@babylonjs/core/Physics/v2/Plugins/havokPlugin"; import HavokPhysics from "@babylonjs/havok"; import "@babylonjs/core/Engines/WebGPU/Extensions/"; -import { SystemUI } from "../ui/systemUI"; -import { BlackHole } from "../view/bodies/stellarObjects/blackHole"; -import { ShipController } from "../spaceship/shipController"; -import { Vector3 } from "@babylonjs/core/Maths/math"; import { setMaxLinVel } from "../utils/havok"; -import { Animation } from "@babylonjs/core/Animations/animation"; import { Observable } from "@babylonjs/core/Misc/observable"; -import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; -import { OrbitRenderer } from "../view/orbitRenderer"; import { PauseMenu } from "../ui/pauseMenu"; -import { AxisRenderer } from "../view/axisRenderer"; -import { AbstractBody } from "../view/bodies/abstractBody"; -import { StarSystemHelper } from "./starSystemHelper"; +import { StarSystemView } from "./StarSystemView"; enum EngineState { RUNNING, PAUSED } +/** + * Main class of CosmosJourneyer. It handles the underlying BabylonJS engine, and the communication between + * the starmap view and the star system view. It also provides utility methods to take screenshots and record videos. + * It also handles the pause menu. + */ export class SpaceEngine { - // UI - private readonly helmetOverlay: HelmetOverlay; - readonly bodyEditor: BodyEditor; private readonly pauseMenu: PauseMenu; - readonly canvas: HTMLCanvasElement; - private isFullscreen = false; private videoRecorder: VideoRecorder | null = null; - // BabylonJS + readonly canvas: HTMLCanvasElement; private engine: Engine | null = null; - private starSystemScene: UberScene | null = null; - - private readonly orbitRenderer: OrbitRenderer = new OrbitRenderer(); - private readonly axisRenderer: AxisRenderer = new AxisRenderer(); - private havokPlugin: HavokPlugin | null = null; - private starSystemUI: SystemUI | null = null; - - private starSystem: StarSystem | null = null; + private starSystemView: StarSystemView | null = null; private starMap: StarMap | null = null; private activeScene: Scene | null = null; private state = EngineState.RUNNING; - private static readonly unZoomAnimation = new Animation("unZoom", "radius", 60, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CYCLE); - readonly onToggleStarMapObservable = new Observable(); constructor() { - this.helmetOverlay = new HelmetOverlay(); - this.bodyEditor = new BodyEditor(); this.pauseMenu = new PauseMenu(); - this.pauseMenu.onResume.add(() => this.resume()); this.pauseMenu.onScreenshot.add(() => this.takeScreenshot()); this.pauseMenu.onShare.add(() => { - const seed = this.getStarSystem().model.seed; + const seed = this.getStarSystemView().getStarSystem().model.seed; const url = new URL(`https://barthpaleologue.github.io/CosmosJourneyer/dist/random.html?seed=${seed}`); - navigator.clipboard.writeText(url.toString()); + navigator.clipboard.writeText(url.toString()).then(() => console.log("Copied to clipboard")); }); this.canvas = document.getElementById("renderer") as HTMLCanvasElement; this.canvas.width = window.innerWidth; this.canvas.height = window.innerHeight; - this.bodyEditor.setCanvas(this.canvas); - - SpaceEngine.unZoomAnimation.setKeys([ - { - frame: 0, - value: 30 - }, - { - frame: 30, - value: 600 - } - ]); - window.addEventListener("blur", () => { if (!this.isPaused()) this.pause(); }); //TODO: use the keyboard class document.addEventListener("keydown", (e) => { - if (e.key === "o") OverlayPostProcess.ARE_ENABLED = !OverlayPostProcess.ARE_ENABLED; - if (e.key === "n") { - this.orbitRenderer.setVisibility(!this.orbitRenderer.isVisible()); - this.axisRenderer.setVisibility(!this.axisRenderer.isVisible()); - } if (e.key === "p") this.takeScreenshot(); - if (e.key === "v") { - if (!VideoRecorder.IsSupported(this.getEngine())) console.warn("Your browser does not support video recording!"); - if (this.videoRecorder === null) { - this.videoRecorder = new VideoRecorder(this.getEngine(), { - fps: 60, - recordChunckSize: 3000000, - mimeType: "video/webm;codecs=h264" - }); - this.videoRecorder.startRecording("planetEngine.webm", Number(prompt("Enter video duration in seconds", "10"))); - } else if (this.videoRecorder.isRecording) { - this.videoRecorder.stopRecording(); - } else { - this.videoRecorder.startRecording("planetEngine.webm", Number(prompt("Enter video duration in seconds", "10"))); - } - } - if (e.key === "u") this.bodyEditor.setVisibility(this.bodyEditor.getVisibility() === EditorVisibility.HIDDEN ? EditorVisibility.NAVBAR : EditorVisibility.HIDDEN); - //if (e.key === "m") mouse.deadAreaRadius === 50 ? (mouse.deadAreaRadius = 1e5) : (mouse.deadAreaRadius = 50); - //if (e.key === "w" && isOrbiting(this.getStarSystemScene().getActiveController(), this.getStarSystem().getNearestBody())) - // (this.getStarSystem().getNearestBody() as TelluricPlanemo).material.wireframe = !(this.getStarSystem().getNearestBody() as TelluricPlanemo).material.wireframe; - + if (e.key === "v") this.takeVideoCapture(); if (e.key === "m") this.toggleStarMap(); - if (e.key === "t") { - if (this.getActiveScene() === this.starSystemScene) { - this.helmetOverlay.setVisibility(!this.helmetOverlay.isVisible()); - } - } - - // when pressing f11, the ui is hidden when the browser is in fullscreen mode - if (e.key === "F11") this.isFullscreen = !this.isFullscreen; - if (e.key === "Escape") { - if (this.state === EngineState.RUNNING) this.pause(); + if (!this.isPaused()) this.pause(); else this.resume(); } }); } - takeScreenshot(): void { - const camera = this.getActiveScene().activeCamera; - if (camera === null) throw new Error("Cannot take screenshot: camera is null"); - Tools.CreateScreenshot(this.getEngine(), camera, { precision: 4 }); - } - - pause(): void { - this.state = EngineState.PAUSED; - this.pauseMenu.setVisibility(true); - this.getStarSystemScene().physicsEnabled = false; - this.getStarMap().setRunning(false); - } - - resume(): void { - this.state = EngineState.RUNNING; - this.pauseMenu.setVisibility(false); - this.getStarSystemScene().physicsEnabled = true; - this.getStarMap().setRunning(true); - } - - isPaused(): boolean { - return this.state === EngineState.PAUSED; - } - - /** - * Toggles the star map - * @throws Error if the star map is null - */ - public toggleStarMap(): void { - if (this.activeScene === this.getStarSystemScene()) { - this.getStarSystemScene().getActiveController().getActiveCamera().animations = [SpaceEngine.unZoomAnimation]; - this.getStarSystemScene().beginAnimation(this.getStarSystemScene().getActiveController().getActiveCamera(), 0, 60, false, 2.0, () => { - this.getStarSystemScene().getActiveController().getActiveCamera().animations = []; - this.bodyEditor.setVisibility(EditorVisibility.HIDDEN); - this.helmetOverlay.setVisibility(false); - - const starMap = this.getStarMap(); - this.activeScene = starMap.scene; - starMap.focusOnCurrentSystem(); - }); - } else { - this.activeScene = this.getStarSystemScene(); - this.helmetOverlay.setVisibility(true); - this.bodyEditor.setVisibility(EditorVisibility.HIDDEN); - } - - this.onToggleStarMapObservable.notifyObservers(this.activeScene === this.getStarMap().scene); - } - /** * Creates the engine and the scenes and loads the assets async * @returns A promise that resolves when the engine and the scenes are created and the assets are loaded */ public async setup(): Promise { + // Init BabylonJS engine this.engine = new Engine(this.canvas); //await EngineFactory.CreateAsync(this.canvas, { enableAllFeatures: true }); this.engine.useReverseDepthBuffer = true; - this.engine.loadingScreen.displayLoadingUI(); + window.addEventListener("resize", () => { + this.getEngine().resize(true); + }); - console.log(`API: ${this.engine instanceof WebGPUEngine ? "WebGPU" : "WebGL" + this.engine.webGLVersion}`); + // Log informations about the gpu and the api used + console.log(`API: ${this.engine.isWebGPU ? "WebGPU" : "WebGL" + this.engine.webGLVersion}`); console.log(`GPU detected: ${this.engine.getGlInfo().renderer}`); + // Init Havok physics engine const havokInstance = await HavokPhysics(); + this.havokPlugin = new HavokPlugin(true, havokInstance); + setMaxLinVel(this.havokPlugin, 10000, 10000); + console.log(`Havok initialized`); + // Init starmap view this.starMap = new StarMap(this.engine); this.starMap.onWarpObservable.add((seed: number) => { - this.setStarSystem(new StarSystem(seed, this.getStarSystemScene()), true); - this.init(); - const firstBody = this.getStarSystem().getBodies()[0]; - if (firstBody === undefined) throw new Error("No bodies in star system"); - - this.orbitRenderer.setOrbitalObjects(this.getStarSystem().getBodies()); - this.axisRenderer.setObjects(this.getStarSystem().getBodies()); - - const activeController = this.getStarSystemScene().getActiveController(); - positionNearObject(activeController, firstBody, this.getStarSystem(), firstBody instanceof BlackHole ? 7 : 5); - if (activeController instanceof ShipController) activeController.enableWarpDrive(); - + this.getStarSystemView().setStarSystem(new StarSystem(seed, this.getStarSystemView().scene), true); + this.getStarSystemView().init(); this.toggleStarMap(); }); - this.starSystemScene = new UberScene(this.engine, ScenePerformancePriority.Intermediate); - this.starSystemScene.clearColor = new Color4(0, 0, 0, 0); - this.starSystemScene.useRightHandedSystem = true; + // Init star system view + this.starSystemView = new StarSystemView(this.engine, this.havokPlugin); - const ambientLight = new HemisphericLight("ambientLight", Vector3.Zero(), this.starSystemScene); - ambientLight.intensity = 0.3; + // Init assets used in star system view + await Assets.Init(this.getStarSystemView().scene); - this.havokPlugin = new HavokPlugin(true, havokInstance); - this.starSystemScene.enablePhysics(Vector3.Zero(), this.havokPlugin); - - setMaxLinVel(this.havokPlugin, 10000, 10000); - - await Assets.Init(this.starSystemScene); + // Starmap is the active scene by default + this.activeScene = this.starMap.scene; - this.starSystemScene.executeWhenReady(() => { + // When everything is ready, hide the loading screen and start the render loop + this.starSystemView.scene.executeWhenReady(() => { this.getEngine().loadingScreen.hideLoadingUI(); - this.getEngine().runRenderLoop(() => this.getActiveScene().render()); - }); - - this.starSystemScene.onBeforePhysicsObservable.add(() => { - if (this.isPaused()) return; - - const starSystemScene = this.getStarSystemScene(); - const starSystem = this.getStarSystem(); - - const deltaTime = this.getEngine().getDeltaTime() / 1000; - - Assets.ChunkForge.update(); - starSystem.update(deltaTime * Settings.TIME_MULTIPLIER); - - const nearestBody = starSystem.getNearestOrbitalObject(); - - if (nearestBody instanceof AbstractBody) { - this.bodyEditor.update(nearestBody, starSystem.postProcessManager, starSystemScene); - } - this.helmetOverlay.update(nearestBody); - - this.orbitRenderer.update(); - }); - - window.addEventListener("resize", () => { - this.bodyEditor.resize(); - this.getEngine().resize(true); + this.getEngine().runRenderLoop(() => { + if (this.isPaused()) return; + this.getActiveScene().render(); + }); }); - - this.bodyEditor.resize(); - - this.bodyEditor.setVisibility(EditorVisibility.HIDDEN); - this.helmetOverlay.setVisibility(false); - - this.starSystemUI = new SystemUI(this.getStarSystemScene()); - - this.activeScene = this.starMap.scene; } - /** - * Inits the current star system - */ - public init(): void { - this.getStarSystem().init(); + public pause(): void { + this.state = EngineState.PAUSED; + this.pauseMenu.setVisibility(true); } - /** - * Sets the active controller of the star system scene - * @param controller the controller to be set as active - */ - public setActiveController(controller: AbstractController): void { - this.getStarSystemScene().setActiveController(controller); + public resume(): void { + this.state = EngineState.RUNNING; + this.pauseMenu.setVisibility(false); } - /** - * Sets the star system and generates it if needed and disposes the old one. Does not perform the init method - * @param starSystem the star system to be set - * @param needsGenerating whether the star system needs to be generated or not - */ - public setStarSystem(starSystem: StarSystem, needsGenerating: boolean): void { - this.starSystem?.dispose(); - this.starSystem = starSystem; - if (needsGenerating) StarSystemHelper.generate(this.starSystem); + public isPaused(): boolean { + return this.state === EngineState.PAUSED; } /** - * Returns the star system - * @returns the star system - * @throws Error if the star system is null + * Inits the current star system */ - public getStarSystem(): StarSystem { - if (this.starSystem === null) throw new Error("Star system is null"); - return this.starSystem; + public init(): void { + this.getStarSystemView().init(); } /** @@ -328,17 +151,12 @@ export class SpaceEngine { * @param callback the callback to be called before the star system scene is rendered */ public registerStarSystemUpdateCallback(callback: () => void): void { - this.getStarSystemScene().registerBeforeRender(callback); + this.getStarSystemView().scene.onBeforeRenderObservable.add(callback); } - /** - * Returns the star system scene - * @returns the star system scene - * @throws Error if the star system scene is null - */ - public getStarSystemScene(): UberScene { - if (this.starSystemScene === null) throw new Error("Star system scene is null"); - return this.starSystemScene; + public getStarSystemView(): StarSystemView { + if (this.starSystemView === null) throw new Error("Star system view is null"); + return this.starSystemView; } public getStarMap(): StarMap { @@ -346,6 +164,25 @@ export class SpaceEngine { return this.starMap; } + /** + * Toggles the star map + * @throws Error if the star map is null + */ + public toggleStarMap(): void { + if (this.activeScene === this.getStarSystemView().scene) { + this.getStarSystemView().unZoom(() => { + const starMap = this.getStarMap(); + this.activeScene = starMap.scene; + starMap.focusOnCurrentSystem(); + }); + } else { + this.activeScene = this.getStarSystemView().scene; + this.getStarSystemView().showUI(); + } + + this.onToggleStarMapObservable.notifyObservers(this.activeScene === this.getStarMap().scene); + } + /** * Returns the active scene (star system or star map) * @returns the active scene (star system or star map) @@ -370,4 +207,35 @@ export class SpaceEngine { if (this.havokPlugin === null) throw new Error("Havok plugin is null"); return this.havokPlugin; } + + /** + * Takes a screenshot of the current scene. By default, the screenshot is taken at a 4x the resolution of the canvas + * @param precision The resolution multiplier of the screenshot + */ + public takeScreenshot(precision = 4): void { + const camera = this.getActiveScene().activeCamera; + if (camera === null) throw new Error("Cannot take screenshot: camera is null"); + Tools.CreateScreenshot(this.getEngine(), camera, { precision: precision }); + } + + public takeVideoCapture(): void { + if (!VideoRecorder.IsSupported(this.getEngine())) { + console.warn("Your browser does not support video recording!"); + return; + } + + if (this.videoRecorder === null) { + this.videoRecorder = new VideoRecorder(this.getEngine(), { + fps: 60, + recordChunckSize: 3000000, + mimeType: "video/webm;codecs=h264" + }); + } + + if (this.videoRecorder.isRecording) { + this.videoRecorder.stopRecording(); + } else { + this.videoRecorder.startRecording("planetEngine.webm", Number(prompt("Enter video duration in seconds", "10"))).then(); + } + } } diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index ad571b3eb..a3dbae0d7 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -29,7 +29,7 @@ export class StarSystem { private readonly spaceStations: SpaceStation[] = []; - private readonly celestialBodies: AbstractBody[] = []; + readonly celestialBodies: AbstractBody[] = []; /** * The list of all stellar objects in the system (stars, black holes, pulsars) diff --git a/src/ts/index.ts b/src/ts/index.ts index 55e558323..021327131 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -19,7 +19,6 @@ import { PostProcessType } from "./view/postProcesses/postProcessTypes"; import { TelluricPlanemoModel } from "./model/planemos/telluricPlanemoModel"; import { GasPlanetModel } from "./model/planemos/gasPlanetModel"; import { getRotationQuaternion, setRotationQuaternion } from "./controller/uberCore/transforms/basicTransform"; -import { PhysicsViewer } from "@babylonjs/core/Debug/physicsViewer"; import { parsePercentageFrom01, parseSpeed } from "./utils/parseToStrings"; import { getMoonSeed } from "./model/planemos/common"; import { RingsUniforms } from "./model/ringsUniform"; @@ -30,20 +29,20 @@ const engine = new SpaceEngine(); await engine.setup(); -const scene = engine.getStarSystemScene(); +const starSystemView = engine.getStarSystemView(); const mouse = new Mouse(engine.canvas, 100); const keyboard = new Keyboard(); const gamepad = new Gamepad(); -const player = new DefaultController(scene); +const player = new DefaultController(starSystemView.scene); player.speed = 0.2 * Settings.EARTH_RADIUS; player.getActiveCamera().maxZ = Settings.EARTH_RADIUS * 100000; player.addInput(keyboard); player.addInput(mouse); player.addInput(gamepad); -const spaceshipController = new ShipController(scene); +const spaceshipController = new ShipController(starSystemView.scene); spaceshipController.getActiveCamera().maxZ = Settings.EARTH_RADIUS * 100000; spaceshipController.addInput(keyboard); spaceshipController.addInput(gamepad); @@ -53,17 +52,16 @@ spaceshipController.addInput(mouse); //physicsViewer.showBody(spaceshipController.aggregate.body); mouse.onMouseLeaveObservable.add(() => { - if (scene.getActiveController() === spaceshipController) engine.pause(); + if (starSystemView.scene.getActiveController() === spaceshipController) engine.pause(); }); -scene.setActiveController(spaceshipController); +starSystemView.scene.setActiveController(spaceshipController); engine.registerStarSystemUpdateCallback(() => { - if (engine.isPaused()) return; - if (scene.getActiveController() != spaceshipController) return; + if (starSystemView.scene.getActiveController() != spaceshipController) return; const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); - const nearestBody = engine.getStarSystem().getNearestOrbitalObject(); + const nearestBody = starSystemView.getStarSystem().getNearestOrbitalObject(); const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); const radius = nearestBody.getBoundingRadius(); spaceshipController.registerClosestObject(distance, radius); @@ -90,9 +88,10 @@ engine.onToggleStarMapObservable.add((isStarMapOpen) => { console.log(`Time is going ${Settings.TIME_MULTIPLIER} time${Settings.TIME_MULTIPLIER > 1 ? "s" : ""} faster than in reality`); const starSystemSeed = 0; -const starSystem = new StarSystem(starSystemSeed, scene); +const starSystem = new StarSystem(starSystemSeed, starSystemView.scene); starSystem.model.setName("Alpha Testis"); -engine.setStarSystem(starSystem, false); + +engine.getStarSystemView().setStarSystem(starSystem, false); const sunModel = new StarModel(0.51); const sun = StarSystemHelper.makeStar(starSystem, sunModel); @@ -120,8 +119,8 @@ const planet = StarSystemHelper.makeTelluricPlanet(starSystem, planetModel); planet.model.ringsUniforms = new RingsUniforms(planet.model.rng); planet.postProcesses.push(PostProcessType.RING); -const spacestation = new SpaceStation(scene, planet); -engine.getStarSystem().addSpaceStation(spacestation); +const spacestation = new SpaceStation(starSystemView.scene, planet); +starSystemView.getStarSystem().addSpaceStation(spacestation); const moonModel = new TelluricPlanemoModel(getMoonSeed(planetModel, 0), planetModel); moonModel.physicalProperties.mass = 2; @@ -187,7 +186,9 @@ const blackHole = starSystem.makeBlackHole(blackHoleModel);*/ engine.init(); -positionNearObject(scene.getActiveController(), planet, starSystem, 2); +positionNearObject(starSystemView.scene.getActiveController(), planet, starSystem, 2); + +spaceshipController.toggleWarpDrive(); const aresAtmosphere = starSystem.postProcessManager.getAtmosphere(ares); if (aresAtmosphere) { @@ -200,16 +201,16 @@ if (aresAtmosphere) { document.addEventListener("keydown", (e) => { if (e.key === "g") { - if (scene.getActiveController() === spaceshipController) { - scene.setActiveController(player); + if (starSystemView.scene.getActiveController() === spaceshipController) { + starSystemView.scene.setActiveController(player); setRotationQuaternion(player.getTransform(), getRotationQuaternion(spaceshipController.getTransform()).clone()); - engine.getStarSystem().postProcessManager.rebuild(); + starSystemView.getStarSystem().postProcessManager.rebuild(); spaceshipController.setEnabled(false, engine.getHavokPlugin()); } else { - scene.setActiveController(spaceshipController); + starSystemView.scene.setActiveController(spaceshipController); setRotationQuaternion(spaceshipController.getTransform(), getRotationQuaternion(player.getTransform()).clone()); - engine.getStarSystem().postProcessManager.rebuild(); + starSystemView.getStarSystem().postProcessManager.rebuild(); spaceshipController.setEnabled(true, engine.getHavokPlugin()); } diff --git a/src/ts/randomizer.ts b/src/ts/randomizer.ts index 84c1e258e..cc83c542e 100644 --- a/src/ts/randomizer.ts +++ b/src/ts/randomizer.ts @@ -19,7 +19,9 @@ const engine = new SpaceEngine(); await engine.setup(); -const scene = engine.getStarSystemScene(); +const starSystemView = engine.getStarSystemView(); + +const scene = starSystemView.scene; const mouse = new Mouse(engine.canvas, 100); const keyboard = new Keyboard(); @@ -41,11 +43,10 @@ spaceshipController.addInput(gamepad); scene.setActiveController(spaceshipController); engine.registerStarSystemUpdateCallback(() => { - if (engine.isPaused()) return; if (scene.getActiveController() != spaceshipController) return; const shipPosition = spaceshipController.getTransform().getAbsolutePosition(); - const nearestBody = engine.getStarSystem().getNearestOrbitalObject(); + const nearestBody = starSystemView.getStarSystem().getNearestOrbitalObject(); const distance = nearestBody.getTransform().getAbsolutePosition().subtract(shipPosition).length(); const radius = nearestBody.getBoundingRadius(); spaceshipController.registerClosestObject(distance, radius); @@ -74,20 +75,20 @@ const urlParams = new URLSearchParams(window.location.search); const seed = urlParams.get("seed"); const starSystem = new StarSystem(seed ? Number(seed) : randRange(-1, 1, (step: number) => Math.random(), 0) * Number.MAX_SAFE_INTEGER, scene); -engine.setStarSystem(starSystem, true); +starSystemView.setStarSystem(starSystem, true); document.addEventListener("keydown", (e) => { if (e.key === "g") { if (scene.getActiveController() === spaceshipController) { scene.setActiveController(player); setRotationQuaternion(player.getTransform(), getRotationQuaternion(spaceshipController.getTransform()).clone()); - engine.getStarSystem().postProcessManager.rebuild(); + starSystemView.getStarSystem().postProcessManager.rebuild(); spaceshipController.setEnabled(false, engine.getHavokPlugin()); } else { scene.setActiveController(spaceshipController); setRotationQuaternion(spaceshipController.getTransform(), getRotationQuaternion(player.getTransform()).clone()); - engine.getStarSystem().postProcessManager.rebuild(); + starSystemView.getStarSystem().postProcessManager.rebuild(); spaceshipController.setEnabled(true, engine.getHavokPlugin()); } @@ -99,6 +100,6 @@ engine.init(); const nbRadius = starSystem.model.getBodyTypeOfStar(0) === BODY_TYPE.BLACK_HOLE ? 8 : 3; positionNearObject(scene.getActiveController(), starSystem.planets.length > 0 ? starSystem.getBodies()[1] : starSystem.stellarObjects[0], starSystem, nbRadius); -engine.bodyEditor.setVisibility(EditorVisibility.NAVBAR); +engine.getStarSystemView().bodyEditor.setVisibility(EditorVisibility.NAVBAR); engine.toggleStarMap(); diff --git a/src/ts/starmap/starMap.ts b/src/ts/starmap/starMap.ts index e18799e41..1b174db56 100644 --- a/src/ts/starmap/starMap.ts +++ b/src/ts/starmap/starMap.ts @@ -40,8 +40,6 @@ export class StarMap { readonly scene: Scene; private readonly controller: DefaultController; - private isRunning = true; - private rotationAnimation: TransformRotationAnimation | null = null; private translationAnimation: TransformTranslationAnimation | null = null; @@ -226,8 +224,6 @@ export class StarMap { this.densityRNG = (x: number, y: number, z: number) => (1.0 - Math.abs(perlinRNG(x * 0.2, y * 0.2, z * 0.2))) ** 8; this.scene.onBeforeRenderObservable.add(() => { - if (!this.isRunning) return; - const deltaTime = this.scene.getEngine().getDeltaTime() / 1000; if (this.rotationAnimation !== null) this.rotationAnimation.update(deltaTime); @@ -260,10 +256,6 @@ export class StarMap { for (const mesh of this.scene.meshes) mesh.position.addInPlace(translationToOrigin); } - public setRunning(running: boolean): void { - this.isRunning = running; - } - private dispatchWarpCallbacks() { if (this.selectedSystemSeed === null) throw new Error("No system selected!"); this.onWarpObservable.notifyObservers(this.selectedSystemSeed); From 8db586ce6028c66a9782ff77f983ff139b0da76a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 16:42:42 +0100 Subject: [PATCH 75/86] Update spaceEngine.ts --- src/ts/controller/spaceEngine.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ts/controller/spaceEngine.ts b/src/ts/controller/spaceEngine.ts index b820dcc96..fd75c80ff 100644 --- a/src/ts/controller/spaceEngine.ts +++ b/src/ts/controller/spaceEngine.ts @@ -203,6 +203,11 @@ export class SpaceEngine { return this.engine; } + /** + * Returns the Havok plugin + * @returns the Havok plugin + * @throws Error if the Havok plugin is null + */ public getHavokPlugin(): HavokPlugin { if (this.havokPlugin === null) throw new Error("Havok plugin is null"); return this.havokPlugin; From c47a7787a26f52d97a8769c46ee8223609ce625f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 17:08:16 +0100 Subject: [PATCH 76/86] update deps --- package.json | 26 +- pnpm-lock.yaml | 1791 +++++++++++++++++++++++++----------------------- 2 files changed, 928 insertions(+), 889 deletions(-) diff --git a/package.json b/package.json index 0e223f2d4..d513668b4 100644 --- a/package.json +++ b/package.json @@ -1,22 +1,22 @@ { "devDependencies": { - "@babel/preset-env": "^7.22.20", - "@babel/preset-typescript": "^7.23.0", - "@babylonjs/core": "^6.23.0", - "@babylonjs/gui": "^6.23.0", + "@babel/preset-env": "^7.23.2", + "@babel/preset-typescript": "^7.23.2", + "@babylonjs/core": "^6.28.1", + "@babylonjs/gui": "^6.28.1", "@babylonjs/havok": "^1.2.1", - "@babylonjs/loaders": "^6.23.0", + "@babylonjs/loaders": "^6.28.1", "@jest/types": "^29.6.3", - "@types/jest": "^29.5.5", - "@types/seedrandom": "^3.0.6", + "@types/jest": "^29.5.7", + "@types/seedrandom": "^3.0.7", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "@webpack-cli/generators": "^3.0.7", "babel": "^6.23.0", "babel-jest": "^29.7.0", "css-loader": "^6.8.1", - "eslint": "^8.51.0", - "eslint-plugin-import": "^2.28.1", + "eslint": "^8.53.0", + "eslint-plugin-import": "^2.29.0", "extended-random": "^1.2.2", "fast-simplex-noise": "^4.0.0", "glslify-loader": "^2.0.0", @@ -27,10 +27,10 @@ "jest": "^29.7.0", "jest-transform-stub": "^2.0.0", "mini-css-extract-plugin": "^2.7.6", - "ml-matrix": "^6.10.5", + "ml-matrix": "^6.10.8", "prettier": "^2.8.8", "raw-loader": "^4.0.2", - "sass": "^1.69.0", + "sass": "^1.69.5", "sass-loader": "^13.3.2", "squirrel-noise": "^1.0.0", "style-loader": "^3.3.3", @@ -40,8 +40,8 @@ "ts-node": "^10.9.1", "typedoc": "^0.24.8", "typescript": "^5.1.6", - "typescript-plugin-css-modules": "^5.0.1", - "webpack": "^5.88.2", + "typescript-plugin-css-modules": "^5.0.2", + "webpack": "^5.89.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2c38ff2b3..127dc1cc7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,56 +6,56 @@ settings: devDependencies: '@babel/preset-env': - specifier: ^7.22.20 - version: 7.22.20(@babel/core@7.23.0) + specifier: ^7.23.2 + version: 7.23.2(@babel/core@7.23.2) '@babel/preset-typescript': - specifier: ^7.23.0 - version: 7.23.0(@babel/core@7.23.0) + specifier: ^7.23.2 + version: 7.23.2(@babel/core@7.23.2) '@babylonjs/core': - specifier: ^6.23.0 - version: 6.23.0 + specifier: ^6.28.1 + version: 6.28.1 '@babylonjs/gui': - specifier: ^6.23.0 - version: 6.23.0(@babylonjs/core@6.23.0) + specifier: ^6.28.1 + version: 6.28.1(@babylonjs/core@6.28.1) '@babylonjs/havok': specifier: ^1.2.1 version: 1.2.1 '@babylonjs/loaders': - specifier: ^6.23.0 - version: 6.23.0(@babylonjs/core@6.23.0)(babylonjs-gltf2interface@6.23.0) + specifier: ^6.28.1 + version: 6.28.1(@babylonjs/core@6.28.1)(babylonjs-gltf2interface@6.28.1) '@jest/types': specifier: ^29.6.3 version: 29.6.3 '@types/jest': - specifier: ^29.5.5 - version: 29.5.5 + specifier: ^29.5.7 + version: 29.5.7 '@types/seedrandom': - specifier: ^3.0.6 - version: 3.0.6 + specifier: ^3.0.7 + version: 3.0.7 '@typescript-eslint/eslint-plugin': specifier: ^5.62.0 - version: 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.51.0)(typescript@5.1.6) + version: 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.53.0)(typescript@5.1.6) '@typescript-eslint/parser': specifier: ^5.62.0 - version: 5.62.0(eslint@8.51.0)(typescript@5.1.6) + version: 5.62.0(eslint@8.53.0)(typescript@5.1.6) '@webpack-cli/generators': specifier: ^3.0.7 - version: 3.0.7(prettier@2.8.8)(webpack-cli@5.1.4)(webpack@5.88.2) + version: 3.0.7(prettier@2.8.8)(webpack-cli@5.1.4)(webpack@5.89.0) babel: specifier: ^6.23.0 version: 6.23.0 babel-jest: specifier: ^29.7.0 - version: 29.7.0(@babel/core@7.23.0) + version: 29.7.0(@babel/core@7.23.2) css-loader: specifier: ^6.8.1 - version: 6.8.1(webpack@5.88.2) + version: 6.8.1(webpack@5.89.0) eslint: - specifier: ^8.51.0 - version: 8.51.0 + specifier: ^8.53.0 + version: 8.53.0 eslint-plugin-import: - specifier: ^2.28.1 - version: 2.28.1(@typescript-eslint/parser@5.62.0)(eslint@8.51.0) + specifier: ^2.29.0 + version: 2.29.0(@typescript-eslint/parser@5.62.0)(eslint@8.53.0) extended-random: specifier: ^1.2.2 version: 1.2.2 @@ -70,55 +70,55 @@ devDependencies: version: 1.3.1 html-loader: specifier: ^4.2.0 - version: 4.2.0(webpack@5.88.2) + version: 4.2.0(webpack@5.89.0) html-webpack-plugin: specifier: ^5.5.3 - version: 5.5.3(webpack@5.88.2) + version: 5.5.3(webpack@5.89.0) http-server: specifier: ^14.1.1 version: 14.1.1 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.8.3)(ts-node@10.9.1) + version: 29.7.0(@types/node@20.8.10)(ts-node@10.9.1) jest-transform-stub: specifier: ^2.0.0 version: 2.0.0 mini-css-extract-plugin: specifier: ^2.7.6 - version: 2.7.6(webpack@5.88.2) + version: 2.7.6(webpack@5.89.0) ml-matrix: - specifier: ^6.10.5 - version: 6.10.5 + specifier: ^6.10.8 + version: 6.10.8 prettier: specifier: ^2.8.8 version: 2.8.8 raw-loader: specifier: ^4.0.2 - version: 4.0.2(webpack@5.88.2) + version: 4.0.2(webpack@5.89.0) sass: - specifier: ^1.69.0 - version: 1.69.0 + specifier: ^1.69.5 + version: 1.69.5 sass-loader: specifier: ^13.3.2 - version: 13.3.2(sass@1.69.0)(webpack@5.88.2) + version: 13.3.2(sass@1.69.5)(webpack@5.89.0) squirrel-noise: specifier: ^1.0.0 version: 1.0.0 style-loader: specifier: ^3.3.3 - version: 3.3.3(webpack@5.88.2) + version: 3.3.3(webpack@5.89.0) terrain-generation: specifier: ^1.6.1 version: 1.6.1 ts-jest: specifier: ^29.1.1 - version: 29.1.1(@babel/core@7.23.0)(@jest/types@29.6.3)(babel-jest@29.7.0)(jest@29.7.0)(typescript@5.1.6) + version: 29.1.1(@babel/core@7.23.2)(@jest/types@29.6.3)(babel-jest@29.7.0)(jest@29.7.0)(typescript@5.1.6) ts-loader: specifier: ^9.5.0 - version: 9.5.0(typescript@5.1.6)(webpack@5.88.2) + version: 9.5.0(typescript@5.1.6)(webpack@5.89.0) ts-node: specifier: ^10.9.1 - version: 10.9.1(@types/node@20.8.3)(typescript@5.1.6) + version: 10.9.1(@types/node@20.8.10)(typescript@5.1.6) typedoc: specifier: ^0.24.8 version: 0.24.8(typescript@5.1.6) @@ -126,17 +126,17 @@ devDependencies: specifier: ^5.1.6 version: 5.1.6 typescript-plugin-css-modules: - specifier: ^5.0.1 - version: 5.0.1(ts-node@10.9.1)(typescript@5.1.6) + specifier: ^5.0.2 + version: 5.0.2(ts-node@10.9.1)(typescript@5.1.6) webpack: - specifier: ^5.88.2 - version: 5.88.2(webpack-cli@5.1.4) + specifier: ^5.89.0 + version: 5.89.0(webpack-cli@5.1.4) webpack-cli: specifier: ^5.1.4 - version: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.88.2) + version: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.89.0) webpack-dev-server: specifier: ^4.15.1 - version: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2) + version: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0) packages: @@ -154,7 +154,7 @@ packages: engines: {node: '>=6.0.0'} dependencies: '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 dev: true /@babel/code-frame@7.22.13: @@ -165,24 +165,24 @@ packages: chalk: 2.4.2 dev: true - /@babel/compat-data@7.22.20: - resolution: {integrity: sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==} + /@babel/compat-data@7.23.2: + resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==} engines: {node: '>=6.9.0'} dev: true - /@babel/core@7.23.0: - resolution: {integrity: sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==} + /@babel/core@7.23.2: + resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 '@babel/code-frame': 7.22.13 '@babel/generator': 7.23.0 '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) - '@babel/helpers': 7.23.1 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) + '@babel/helpers': 7.23.2 '@babel/parser': 7.23.0 '@babel/template': 7.22.15 - '@babel/traverse': 7.23.0 + '@babel/traverse': 7.23.2 '@babel/types': 7.23.0 convert-source-map: 2.0.0 debug: 4.3.4 @@ -199,7 +199,7 @@ packages: dependencies: '@babel/types': 7.23.0 '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 jsesc: 2.5.2 dev: true @@ -221,54 +221,54 @@ packages: resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.22.20 + '@babel/compat-data': 7.23.2 '@babel/helper-validator-option': 7.22.15 browserslist: 4.22.1 lru-cache: 5.1.1 semver: 6.3.1 dev: true - /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.23.0): + /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.23.2): resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-member-expression-to-functions': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0) + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 semver: 6.3.1 dev: true - /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.0): + /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.2): resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-annotate-as-pure': 7.22.5 regexpu-core: 5.3.2 semver: 6.3.1 dev: true - /@babel/helper-define-polyfill-provider@0.4.2(@babel/core@7.23.0): - resolution: {integrity: sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==} + /@babel/helper-define-polyfill-provider@0.4.3(@babel/core@7.23.2): + resolution: {integrity: sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 debug: 4.3.4 lodash.debounce: 4.0.8 - resolve: 1.22.6 + resolve: 1.22.8 transitivePeerDependencies: - supports-color dev: true @@ -307,13 +307,13 @@ packages: '@babel/types': 7.23.0 dev: true - /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.0): + /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.2): resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-module-imports': 7.22.15 '@babel/helper-simple-access': 7.22.5 @@ -333,25 +333,25 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.23.0): + /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.23.2): resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-wrap-function': 7.22.20 dev: true - /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.0): + /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.2): resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-member-expression-to-functions': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 @@ -402,12 +402,12 @@ packages: '@babel/types': 7.23.0 dev: true - /@babel/helpers@7.23.1: - resolution: {integrity: sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==} + /@babel/helpers@7.23.2: + resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.15 - '@babel/traverse': 7.23.0 + '@babel/traverse': 7.23.2 '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color @@ -430,902 +430,902 @@ packages: '@babel/types': 7.23.0 dev: true - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.15(@babel/core@7.23.0): + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.15(@babel/core@7.23.2): resolution: {integrity: sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.15(@babel/core@7.23.0): + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.15(@babel/core@7.23.2): resolution: {integrity: sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.0) + '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.2) dev: true - /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.0): + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.2): resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 dev: true - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.0): + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.2): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.0): + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.2): resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.0): + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.2): resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.0): + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.2): resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.0): + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.2): resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.0): + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.2): resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.23.0): + /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.23.0): + /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.0): + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.2): resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.0): + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.2): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.0): + /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.0): + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.2): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.0): + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.2): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.0): + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.2): resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.0): + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.2): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.0): + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.2): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.0): + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.2): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.0): + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.2): resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.0): + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.2): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.23.0): + /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.0): + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.2): resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-async-generator-functions@7.22.15(@babel/core@7.23.0): - resolution: {integrity: sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w==} + /@babel/plugin-transform-async-generator-functions@7.23.2(@babel/core@7.23.2): + resolution: {integrity: sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.0) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.0) + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.0) + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-block-scoping@7.23.0(@babel/core@7.23.0): + /@babel/plugin-transform-block-scoping@7.23.0(@babel/core@7.23.2): resolution: {integrity: sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-class-static-block@7.22.11(@babel/core@7.23.0): + /@babel/plugin-transform-class-static-block@7.22.11(@babel/core@7.23.2): resolution: {integrity: sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-classes@7.22.15(@babel/core@7.23.0): + /@babel/plugin-transform-classes@7.22.15(@babel/core@7.23.2): resolution: {integrity: sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0) + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) '@babel/helper-split-export-declaration': 7.22.6 globals: 11.12.0 dev: true - /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 '@babel/template': 7.22.15 dev: true - /@babel/plugin-transform-destructuring@7.23.0(@babel/core@7.23.0): + /@babel/plugin-transform-destructuring@7.23.0(@babel/core@7.23.2): resolution: {integrity: sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-dynamic-import@7.22.11(@babel/core@7.23.0): + /@babel/plugin-transform-dynamic-import@7.22.11(@babel/core@7.23.2): resolution: {integrity: sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-export-namespace-from@7.22.11(@babel/core@7.23.0): + /@babel/plugin-transform-export-namespace-from@7.22.11(@babel/core@7.23.2): resolution: {integrity: sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-for-of@7.22.15(@babel/core@7.23.0): + /@babel/plugin-transform-for-of@7.22.15(@babel/core@7.23.2): resolution: {integrity: sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-function-name': 7.23.0 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-json-strings@7.22.11(@babel/core@7.23.0): + /@babel/plugin-transform-json-strings@7.22.11(@babel/core@7.23.2): resolution: {integrity: sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-literals@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-literals@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-logical-assignment-operators@7.22.11(@babel/core@7.23.0): + /@babel/plugin-transform-logical-assignment-operators@7.22.11(@babel/core@7.23.2): resolution: {integrity: sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-modules-amd@7.23.0(@babel/core@7.23.0): + /@babel/plugin-transform-modules-amd@7.23.0(@babel/core@7.23.2): resolution: {integrity: sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-modules-commonjs@7.23.0(@babel/core@7.23.0): + /@babel/plugin-transform-modules-commonjs@7.23.0(@babel/core@7.23.2): resolution: {integrity: sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-simple-access': 7.22.5 dev: true - /@babel/plugin-transform-modules-systemjs@7.23.0(@babel/core@7.23.0): + /@babel/plugin-transform-modules-systemjs@7.23.0(@babel/core@7.23.2): resolution: {integrity: sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-validator-identifier': 7.22.20 dev: true - /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-nullish-coalescing-operator@7.22.11(@babel/core@7.23.0): + /@babel/plugin-transform-nullish-coalescing-operator@7.22.11(@babel/core@7.23.2): resolution: {integrity: sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-numeric-separator@7.22.11(@babel/core@7.23.0): + /@babel/plugin-transform-numeric-separator@7.22.11(@babel/core@7.23.2): resolution: {integrity: sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-object-rest-spread@7.22.15(@babel/core@7.23.0): + /@babel/plugin-transform-object-rest-spread@7.22.15(@babel/core@7.23.2): resolution: {integrity: sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.22.20 - '@babel/core': 7.23.0 + '@babel/compat-data': 7.23.2 + '@babel/core': 7.23.2 '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0) + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.23.0): + /@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.23.2): resolution: {integrity: sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-optional-chaining@7.23.0(@babel/core@7.23.0): + /@babel/plugin-transform-optional-chaining@7.23.0(@babel/core@7.23.2): resolution: {integrity: sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-parameters@7.22.15(@babel/core@7.23.0): + /@babel/plugin-transform-parameters@7.22.15(@babel/core@7.23.2): resolution: {integrity: sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-private-property-in-object@7.22.11(@babel/core@7.23.0): + /@babel/plugin-transform-private-property-in-object@7.22.11(@babel/core@7.23.2): resolution: {integrity: sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-regenerator@7.22.10(@babel/core@7.23.0): + /@babel/plugin-transform-regenerator@7.22.10(@babel/core@7.23.2): resolution: {integrity: sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 regenerator-transform: 0.15.2 dev: true - /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-spread@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-spread@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: true - /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-typescript@7.22.15(@babel/core@7.23.0): + /@babel/plugin-transform-typescript@7.22.15(@babel/core@7.23.2): resolution: {integrity: sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2) dev: true - /@babel/plugin-transform-unicode-escapes@7.22.10(@babel/core@7.23.0): + /@babel/plugin-transform-unicode-escapes@7.22.10(@babel/core@7.23.2): resolution: {integrity: sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.23.0): + /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/preset-env@7.22.20(@babel/core@7.23.0): - resolution: {integrity: sha512-11MY04gGC4kSzlPHRfvVkNAZhUxOvm7DCJ37hPDnUENwe06npjIRAfInEMTGSb4LZK5ZgDFkv5hw0lGebHeTyg==} + /@babel/preset-env@7.23.2(@babel/core@7.23.2): + resolution: {integrity: sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.22.20 - '@babel/core': 7.23.0 + '@babel/compat-data': 7.23.2 + '@babel/core': 7.23.2 '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-validator-option': 7.22.15 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.15(@babel/core@7.23.0) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.15(@babel/core@7.23.0) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.0) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.0) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.0) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.0) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.0) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.0) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.0) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.0) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.0) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.0) - '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-async-generator-functions': 7.22.15(@babel/core@7.23.0) - '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-block-scoping': 7.23.0(@babel/core@7.23.0) - '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-class-static-block': 7.22.11(@babel/core@7.23.0) - '@babel/plugin-transform-classes': 7.22.15(@babel/core@7.23.0) - '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-destructuring': 7.23.0(@babel/core@7.23.0) - '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-dynamic-import': 7.22.11(@babel/core@7.23.0) - '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-export-namespace-from': 7.22.11(@babel/core@7.23.0) - '@babel/plugin-transform-for-of': 7.22.15(@babel/core@7.23.0) - '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-json-strings': 7.22.11(@babel/core@7.23.0) - '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-logical-assignment-operators': 7.22.11(@babel/core@7.23.0) - '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-modules-amd': 7.23.0(@babel/core@7.23.0) - '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.0) - '@babel/plugin-transform-modules-systemjs': 7.23.0(@babel/core@7.23.0) - '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.22.11(@babel/core@7.23.0) - '@babel/plugin-transform-numeric-separator': 7.22.11(@babel/core@7.23.0) - '@babel/plugin-transform-object-rest-spread': 7.22.15(@babel/core@7.23.0) - '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-optional-catch-binding': 7.22.11(@babel/core@7.23.0) - '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.0) - '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.0) - '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-private-property-in-object': 7.22.11(@babel/core@7.23.0) - '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-regenerator': 7.22.10(@babel/core@7.23.0) - '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-unicode-escapes': 7.22.10(@babel/core@7.23.0) - '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.23.0) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.2) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.2) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.2) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.2) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.2) + '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-async-generator-functions': 7.23.2(@babel/core@7.23.2) + '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-block-scoping': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-class-static-block': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-classes': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-destructuring': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-dynamic-import': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-export-namespace-from': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-for-of': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-json-strings': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-logical-assignment-operators': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-modules-amd': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-modules-systemjs': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-nullish-coalescing-operator': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-numeric-separator': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-object-rest-spread': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-optional-catch-binding': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-private-property-in-object': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-regenerator': 7.22.10(@babel/core@7.23.2) + '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-unicode-escapes': 7.22.10(@babel/core@7.23.2) + '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.23.2) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.2) '@babel/types': 7.23.0 - babel-plugin-polyfill-corejs2: 0.4.5(@babel/core@7.23.0) - babel-plugin-polyfill-corejs3: 0.8.4(@babel/core@7.23.0) - babel-plugin-polyfill-regenerator: 0.5.2(@babel/core@7.23.0) - core-js-compat: 3.33.0 + babel-plugin-polyfill-corejs2: 0.4.6(@babel/core@7.23.2) + babel-plugin-polyfill-corejs3: 0.8.6(@babel/core@7.23.2) + babel-plugin-polyfill-regenerator: 0.5.3(@babel/core@7.23.2) + core-js-compat: 3.33.2 semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.23.0): + /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.23.2): resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 '@babel/types': 7.23.0 esutils: 2.0.3 dev: true - /@babel/preset-typescript@7.23.0(@babel/core@7.23.0): - resolution: {integrity: sha512-6P6VVa/NM/VlAYj5s2Aq/gdVg8FSENCg3wlZ6Qau9AcPaoF5LbN1nyGlR9DTRIw9PpxI94e+ReydsJHcjwAweg==} + /@babel/preset-typescript@7.23.2(@babel/core@7.23.2): + resolution: {integrity: sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-validator-option': 7.22.15 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.0) - '@babel/plugin-transform-typescript': 7.22.15(@babel/core@7.23.0) + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-typescript': 7.22.15(@babel/core@7.23.2) dev: true /@babel/regjsgen@0.8.0: resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} dev: true - /@babel/runtime@7.23.1: - resolution: {integrity: sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==} + /@babel/runtime@7.23.2: + resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 @@ -1340,8 +1340,8 @@ packages: '@babel/types': 7.23.0 dev: true - /@babel/traverse@7.23.0: - resolution: {integrity: sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==} + /@babel/traverse@7.23.2: + resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.13 @@ -1367,32 +1367,32 @@ packages: to-fast-properties: 2.0.0 dev: true - /@babylonjs/core@6.23.0: - resolution: {integrity: sha512-FnWkZaGGJPr7qxHTotEWvCtlGgjlCbj4FSxnJh2QPe0CWoztF7rHPB8a1obb87fBACHbwBEpQZkBaYOCmnu3Vg==} + /@babylonjs/core@6.28.1: + resolution: {integrity: sha512-7D0L//yQDq0WU5Mj6os3fGNoy8dtCONgRJ2ji2PMNwZlQ6jH3e5OnoaMYss1QuNCoGeTrXbNuNa7z8RezuFrCQ==} dev: true - /@babylonjs/gui@6.23.0(@babylonjs/core@6.23.0): - resolution: {integrity: sha512-Pm2sr3nMO+5KHZYQ2erz2mxTbYj2YG/K62coTGSGE+AxUFtc53UAHgYu96zPgqAR83Hvd3NsnrN0cNid96Lifw==} + /@babylonjs/gui@6.28.1(@babylonjs/core@6.28.1): + resolution: {integrity: sha512-si8REM177m2Pk0DUn1d3xXyfKmOKosK4uY8Dw+eOL8FuCGvGQe5Yuw2qgkw2BbVMkFdg2qSib5vqxaLa97c1kg==} peerDependencies: '@babylonjs/core': ^6.0.0 dependencies: - '@babylonjs/core': 6.23.0 + '@babylonjs/core': 6.28.1 dev: true /@babylonjs/havok@1.2.1: resolution: {integrity: sha512-oWMGjy7h163xoYw+xh2vM0vOBQuymulqpWUDth14/cKwqF6G5Rj09hzT7ocFR6mMMPWx5N95yBwH4sSzp8+dSQ==} dependencies: - '@types/emscripten': 1.39.8 + '@types/emscripten': 1.39.9 dev: true - /@babylonjs/loaders@6.23.0(@babylonjs/core@6.23.0)(babylonjs-gltf2interface@6.23.0): - resolution: {integrity: sha512-xAsNhNZK9UNYnWK9/RvFylyOz0JBCiWSeO8YHSRgYtTg/4S6F9gcw8IzB1Vnb36TAP3aWYVhoFaJRYq4luwy5w==} + /@babylonjs/loaders@6.28.1(@babylonjs/core@6.28.1)(babylonjs-gltf2interface@6.28.1): + resolution: {integrity: sha512-MrvkQxNaWotVE1xnKHCW/mij80efBH4sCM1xybEw2abAxr0jGfdSpPAKnddsqRE3JsAqyp40QaeHd5ngSKIaQg==} peerDependencies: '@babylonjs/core': ^6.0.0 babylonjs-gltf2interface: ^6.0.0 dependencies: - '@babylonjs/core': 6.23.0 - babylonjs-gltf2interface: 6.23.0 + '@babylonjs/core': 6.28.1 + babylonjs-gltf2interface: 6.28.1 dev: true /@bcoe/v8-coverage@0.2.3: @@ -1418,23 +1418,23 @@ packages: engines: {node: '>=10.0.0'} dev: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.51.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.53.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.51.0 + eslint: 8.53.0 eslint-visitor-keys: 3.4.3 dev: true - /@eslint-community/regexpp@4.9.1: - resolution: {integrity: sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==} + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc@2.1.2: - resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} + /@eslint/eslintrc@2.1.3: + resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 @@ -1450,8 +1450,8 @@ packages: - supports-color dev: true - /@eslint/js@8.51.0: - resolution: {integrity: sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==} + /@eslint/js@8.53.0: + resolution: {integrity: sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -1459,11 +1459,11 @@ packages: resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} dev: true - /@humanwhocodes/config-array@0.11.11: - resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==} + /@humanwhocodes/config-array@0.11.13: + resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} engines: {node: '>=10.10.0'} dependencies: - '@humanwhocodes/object-schema': 1.2.1 + '@humanwhocodes/object-schema': 2.0.1 debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: @@ -1475,8 +1475,8 @@ packages: engines: {node: '>=12.22'} dev: true - /@humanwhocodes/object-schema@1.2.1: - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + /@humanwhocodes/object-schema@2.0.1: + resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} dev: true /@isaacs/cliui@8.0.2: @@ -1516,7 +1516,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.8.3 + '@types/node': 20.8.10 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -1537,14 +1537,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.3 + '@types/node': 20.8.10 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.8.3)(ts-node@10.9.1) + jest-config: 29.7.0(@types/node@20.8.10)(ts-node@10.9.1) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -1572,7 +1572,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.3 + '@types/node': 20.8.10 jest-mock: 29.7.0 dev: true @@ -1599,7 +1599,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.8.3 + '@types/node': 20.8.10 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -1631,8 +1631,8 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.19 - '@types/node': 20.8.3 + '@jridgewell/trace-mapping': 0.3.20 + '@types/node': 20.8.10 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -1665,7 +1665,7 @@ packages: resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 callsites: 3.1.0 graceful-fs: 4.2.11 dev: true @@ -1676,7 +1676,7 @@ packages: dependencies: '@jest/console': 29.7.0 '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-lib-coverage': 2.0.5 collect-v8-coverage: 1.0.2 dev: true @@ -1694,9 +1694,9 @@ packages: resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 convert-source-map: 2.0.0 @@ -1718,10 +1718,10 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.4 - '@types/istanbul-reports': 3.0.2 - '@types/node': 20.8.3 - '@types/yargs': 17.0.28 + '@types/istanbul-lib-coverage': 2.0.5 + '@types/istanbul-reports': 3.0.3 + '@types/node': 20.8.10 + '@types/yargs': 17.0.29 chalk: 4.1.2 dev: true @@ -1731,7 +1731,7 @@ packages: dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 dev: true /@jridgewell/resolve-uri@3.1.1: @@ -1748,15 +1748,15 @@ packages: resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} dependencies: '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 dev: true /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} dev: true - /@jridgewell/trace-mapping@0.3.19: - resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + /@jridgewell/trace-mapping@0.3.20: + resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} dependencies: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 @@ -1998,10 +1998,11 @@ packages: dependencies: '@npmcli/node-gyp': 3.0.0 '@npmcli/promise-spawn': 6.0.2 - node-gyp: 9.4.0 + node-gyp: 9.4.1 read-package-json-fast: 3.0.2 which: 3.0.1 transitivePeerDependencies: + - bluebird - supports-color dev: true @@ -2020,7 +2021,7 @@ packages: '@octokit/request-error': 2.1.0 '@octokit/types': 6.41.0 before-after-hook: 2.2.3 - universal-user-agent: 6.0.0 + universal-user-agent: 6.0.1 transitivePeerDependencies: - encoding dev: true @@ -2030,7 +2031,7 @@ packages: dependencies: '@octokit/types': 6.41.0 is-plain-object: 5.0.0 - universal-user-agent: 6.0.0 + universal-user-agent: 6.0.1 dev: true /@octokit/graphql@4.8.0: @@ -2038,7 +2039,7 @@ packages: dependencies: '@octokit/request': 5.6.3 '@octokit/types': 6.41.0 - universal-user-agent: 6.0.0 + universal-user-agent: 6.0.1 transitivePeerDependencies: - encoding dev: true @@ -2090,7 +2091,7 @@ packages: '@octokit/types': 6.41.0 is-plain-object: 5.0.0 node-fetch: 2.7.0 - universal-user-agent: 6.0.0 + universal-user-agent: 6.0.1 transitivePeerDependencies: - encoding dev: true @@ -2207,267 +2208,275 @@ packages: minimatch: 9.0.3 dev: true - /@types/babel__core@7.20.2: - resolution: {integrity: sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==} + /@types/babel__core@7.20.3: + resolution: {integrity: sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA==} dependencies: '@babel/parser': 7.23.0 '@babel/types': 7.23.0 - '@types/babel__generator': 7.6.5 - '@types/babel__template': 7.4.2 - '@types/babel__traverse': 7.20.2 + '@types/babel__generator': 7.6.6 + '@types/babel__template': 7.4.3 + '@types/babel__traverse': 7.20.3 dev: true - /@types/babel__generator@7.6.5: - resolution: {integrity: sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==} + /@types/babel__generator@7.6.6: + resolution: {integrity: sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w==} dependencies: '@babel/types': 7.23.0 dev: true - /@types/babel__template@7.4.2: - resolution: {integrity: sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==} + /@types/babel__template@7.4.3: + resolution: {integrity: sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ==} dependencies: '@babel/parser': 7.23.0 '@babel/types': 7.23.0 dev: true - /@types/babel__traverse@7.20.2: - resolution: {integrity: sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==} + /@types/babel__traverse@7.20.3: + resolution: {integrity: sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw==} dependencies: '@babel/types': 7.23.0 dev: true - /@types/body-parser@1.19.3: - resolution: {integrity: sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==} + /@types/body-parser@1.19.4: + resolution: {integrity: sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA==} dependencies: - '@types/connect': 3.4.36 - '@types/node': 20.8.3 + '@types/connect': 3.4.37 + '@types/node': 20.8.10 dev: true - /@types/bonjour@3.5.11: - resolution: {integrity: sha512-isGhjmBtLIxdHBDl2xGwUzEM8AOyOvWsADWq7rqirdi/ZQoHnLWErHvsThcEzTX8juDRiZtzp2Qkv5bgNh6mAg==} + /@types/bonjour@3.5.12: + resolution: {integrity: sha512-ky0kWSqXVxSqgqJvPIkgFkcn4C8MnRog308Ou8xBBIVo39OmUFy+jqNe0nPwLCDFxUpmT9EvT91YzOJgkDRcFg==} dependencies: - '@types/node': 20.8.3 + '@types/node': 20.8.10 dev: true - /@types/connect-history-api-fallback@1.5.1: - resolution: {integrity: sha512-iaQslNbARe8fctL5Lk+DsmgWOM83lM+7FzP0eQUJs1jd3kBE8NWqBTIT2S8SqQOJjxvt2eyIjpOuYeRXq2AdMw==} + /@types/connect-history-api-fallback@1.5.2: + resolution: {integrity: sha512-gX2j9x+NzSh4zOhnRPSdPPmTepS4DfxES0AvIFv3jGv5QyeAJf6u6dY5/BAoAJU9Qq1uTvwOku8SSC2GnCRl6Q==} dependencies: - '@types/express-serve-static-core': 4.17.37 - '@types/node': 20.8.3 + '@types/express-serve-static-core': 4.17.39 + '@types/node': 20.8.10 dev: true - /@types/connect@3.4.36: - resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==} + /@types/connect@3.4.37: + resolution: {integrity: sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==} dependencies: - '@types/node': 20.8.3 + '@types/node': 20.8.10 dev: true - /@types/emscripten@1.39.8: - resolution: {integrity: sha512-Rk0HKcMXFUuqT32k1kXHZWgxiMvsyYsmlnjp0rLKa0MMoqXLE3T9dogDBTRfuc3SAsXu97KD3k4SKR1lHqd57w==} + /@types/emscripten@1.39.9: + resolution: {integrity: sha512-ILdWj4XYtNOqxJaW22NEQx2gJsLfV5ncxYhhGX1a1H1lXl2Ta0gUz7QOnOoF1xQbJwWDjImi8gXN9mKdIf6n9g==} dev: true - /@types/eslint-scope@3.7.5: - resolution: {integrity: sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA==} + /@types/eslint-scope@3.7.6: + resolution: {integrity: sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ==} dependencies: - '@types/eslint': 8.44.3 - '@types/estree': 1.0.2 + '@types/eslint': 8.44.6 + '@types/estree': 1.0.4 dev: true - /@types/eslint@8.44.3: - resolution: {integrity: sha512-iM/WfkwAhwmPff3wZuPLYiHX18HI24jU8k1ZSH7P8FHwxTjZ2P6CoX2wnF43oprR+YXJM6UUxATkNvyv/JHd+g==} + /@types/eslint@8.44.6: + resolution: {integrity: sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw==} dependencies: - '@types/estree': 1.0.2 - '@types/json-schema': 7.0.13 + '@types/estree': 1.0.4 + '@types/json-schema': 7.0.14 dev: true - /@types/estree@1.0.2: - resolution: {integrity: sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==} + /@types/estree@1.0.4: + resolution: {integrity: sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw==} dev: true /@types/expect@1.20.4: resolution: {integrity: sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==} dev: true - /@types/express-serve-static-core@4.17.37: - resolution: {integrity: sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==} + /@types/express-serve-static-core@4.17.39: + resolution: {integrity: sha512-BiEUfAiGCOllomsRAZOiMFP7LAnrifHpt56pc4Z7l9K6ACyN06Ns1JLMBxwkfLOjJRlSf06NwWsT7yzfpaVpyQ==} dependencies: - '@types/node': 20.8.3 - '@types/qs': 6.9.8 - '@types/range-parser': 1.2.5 - '@types/send': 0.17.2 + '@types/node': 20.8.10 + '@types/qs': 6.9.9 + '@types/range-parser': 1.2.6 + '@types/send': 0.17.3 dev: true - /@types/express@4.17.18: - resolution: {integrity: sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==} + /@types/express@4.17.20: + resolution: {integrity: sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==} dependencies: - '@types/body-parser': 1.19.3 - '@types/express-serve-static-core': 4.17.37 - '@types/qs': 6.9.8 - '@types/serve-static': 1.15.3 + '@types/body-parser': 1.19.4 + '@types/express-serve-static-core': 4.17.39 + '@types/qs': 6.9.9 + '@types/serve-static': 1.15.4 dev: true - /@types/graceful-fs@4.1.7: - resolution: {integrity: sha512-MhzcwU8aUygZroVwL2jeYk6JisJrPl/oov/gsgGCue9mkgl9wjGbzReYQClxiUgFDnib9FuHqTndccKeZKxTRw==} + /@types/graceful-fs@4.1.8: + resolution: {integrity: sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw==} dependencies: - '@types/node': 20.8.3 + '@types/node': 20.8.10 dev: true /@types/html-minifier-terser@6.1.0: resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} dev: true - /@types/http-errors@2.0.2: - resolution: {integrity: sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==} + /@types/http-errors@2.0.3: + resolution: {integrity: sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA==} dev: true - /@types/http-proxy@1.17.12: - resolution: {integrity: sha512-kQtujO08dVtQ2wXAuSFfk9ASy3sug4+ogFR8Kd8UgP8PEuc1/G/8yjYRmp//PcDNJEUKOza/MrQu15bouEUCiw==} + /@types/http-proxy@1.17.13: + resolution: {integrity: sha512-GkhdWcMNiR5QSQRYnJ+/oXzu0+7JJEPC8vkWXK351BkhjraZF+1W13CUYARUvX9+NqIU2n6YHA4iwywsc/M6Sw==} dependencies: - '@types/node': 20.8.3 + '@types/node': 20.8.10 dev: true - /@types/istanbul-lib-coverage@2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + /@types/istanbul-lib-coverage@2.0.5: + resolution: {integrity: sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==} dev: true - /@types/istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-gPQuzaPR5h/djlAv2apEG1HVOyj1IUs7GpfMZixU0/0KXT3pm64ylHuMUI1/Akh+sq/iikxg6Z2j+fcMDXaaTQ==} + /@types/istanbul-lib-report@3.0.2: + resolution: {integrity: sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w==} dependencies: - '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-lib-coverage': 2.0.5 dev: true - /@types/istanbul-reports@3.0.2: - resolution: {integrity: sha512-kv43F9eb3Lhj+lr/Hn6OcLCs/sSM8bt+fIaP11rCYngfV6NVjzWXJ17owQtDQTL9tQ8WSLUrGsSJ6rJz0F1w1A==} + /@types/istanbul-reports@3.0.3: + resolution: {integrity: sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg==} dependencies: - '@types/istanbul-lib-report': 3.0.1 + '@types/istanbul-lib-report': 3.0.2 dev: true - /@types/jest@29.5.5: - resolution: {integrity: sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==} + /@types/jest@29.5.7: + resolution: {integrity: sha512-HLyetab6KVPSiF+7pFcUyMeLsx25LDNDemw9mGsJBkai/oouwrjTycocSDYopMEwFhN2Y4s9oPyOCZNofgSt2g==} dependencies: expect: 29.7.0 pretty-format: 29.7.0 dev: true - /@types/json-schema@7.0.13: - resolution: {integrity: sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==} + /@types/json-schema@7.0.14: + resolution: {integrity: sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==} dev: true /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true - /@types/mime@1.3.3: - resolution: {integrity: sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==} + /@types/mime@1.3.4: + resolution: {integrity: sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==} dev: true - /@types/mime@3.0.2: - resolution: {integrity: sha512-Wj+fqpTLtTbG7c0tH47dkahefpLKEbB+xAZuLq7b4/IDHPl/n6VoXcyUQ2bypFlbSwvCr0y+bD4euTTqTJsPxQ==} + /@types/mime@3.0.3: + resolution: {integrity: sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ==} dev: true /@types/minimatch@3.0.5: resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} dev: true + /@types/node-forge@1.3.8: + resolution: {integrity: sha512-vGXshY9vim9CJjrpcS5raqSjEfKlJcWy2HNdgUasR66fAnVEYarrf1ULV4nfvpC1nZq/moA9qyqBcu83x+Jlrg==} + dependencies: + '@types/node': 20.8.10 + dev: true + /@types/node@15.14.9: resolution: {integrity: sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==} dev: true - /@types/node@20.8.3: - resolution: {integrity: sha512-jxiZQFpb+NlH5kjW49vXxvxTjeeqlbsnTAdBTKpzEdPs9itay7MscYXz3Fo9VYFEsfQ6LJFitHad3faerLAjCw==} + /@types/node@20.8.10: + resolution: {integrity: sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==} + dependencies: + undici-types: 5.26.5 dev: true - /@types/normalize-package-data@2.4.2: - resolution: {integrity: sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==} + /@types/normalize-package-data@2.4.3: + resolution: {integrity: sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==} dev: true - /@types/postcss-modules-local-by-default@4.0.0: - resolution: {integrity: sha512-0VLab/pcLTLcfbxi6THSIMVYcw9hEUBGvjwwaGpW77mMgRXfGF+a76t7BxTGyLh1y68tBvrffp8UWnqvm76+yg==} + /@types/postcss-modules-local-by-default@4.0.1: + resolution: {integrity: sha512-8Vf6MA7x68/XKCgIOFGGDtkfKzcIp0LuQcYGUqG+Ip1kIDIlTekH1u147obRXXSdv44q9HtT2sJQGWQkzLjMuQ==} dependencies: postcss: 8.4.31 dev: true - /@types/postcss-modules-scope@3.0.2: - resolution: {integrity: sha512-Q+OIqRncPV2WB+HXFA9WSZmIhDMUqxE5HgU81WA4oof3NutXhh8bHzB5ypbxRKi8NaPzByoSR5o9qHYW1lMOAg==} + /@types/postcss-modules-scope@3.0.3: + resolution: {integrity: sha512-VfPns6aDJt/Bp3dvjnkgbsOfJQLMldZjWT+rnOH/QVSgfutgVEH6fUf2SPLN47lhUjp7ejoC9BUdrjx8m94IUg==} dependencies: postcss: 8.4.31 dev: true - /@types/qs@6.9.8: - resolution: {integrity: sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==} + /@types/qs@6.9.9: + resolution: {integrity: sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==} dev: true - /@types/range-parser@1.2.5: - resolution: {integrity: sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA==} + /@types/range-parser@1.2.6: + resolution: {integrity: sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA==} dev: true /@types/retry@0.12.0: resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} dev: true - /@types/seedrandom@3.0.6: - resolution: {integrity: sha512-3+JLzzsdbTrEDXSKaudKajj3w8x4ZWDk7CunwHnSWxtfMoetnKtIbFXMru7RXw6Hq1dU0td+soPX8vVjdgCPBA==} + /@types/seedrandom@3.0.7: + resolution: {integrity: sha512-2kwVU6ijXQblfsC8uqhBxslJC2wJfgTE1hINNkj29TL37fc8Uli5Ew43xTv2tShH3FeoKv8jkH2WgeVLd5QWzA==} dev: true - /@types/semver@7.5.3: - resolution: {integrity: sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==} + /@types/semver@7.5.4: + resolution: {integrity: sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==} dev: true - /@types/send@0.17.2: - resolution: {integrity: sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==} + /@types/send@0.17.3: + resolution: {integrity: sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug==} dependencies: - '@types/mime': 1.3.3 - '@types/node': 20.8.3 + '@types/mime': 1.3.4 + '@types/node': 20.8.10 dev: true - /@types/serve-index@1.9.2: - resolution: {integrity: sha512-asaEIoc6J+DbBKXtO7p2shWUpKacZOoMBEGBgPG91P8xhO53ohzHWGCs4ScZo5pQMf5ukQzVT9fhX1WzpHihig==} + /@types/serve-index@1.9.3: + resolution: {integrity: sha512-4KG+yMEuvDPRrYq5fyVm/I2uqAJSAwZK9VSa+Zf+zUq9/oxSSvy3kkIqyL+jjStv6UCVi8/Aho0NHtB1Fwosrg==} dependencies: - '@types/express': 4.17.18 + '@types/express': 4.17.20 dev: true - /@types/serve-static@1.15.3: - resolution: {integrity: sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==} + /@types/serve-static@1.15.4: + resolution: {integrity: sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw==} dependencies: - '@types/http-errors': 2.0.2 - '@types/mime': 3.0.2 - '@types/node': 20.8.3 + '@types/http-errors': 2.0.3 + '@types/mime': 3.0.3 + '@types/node': 20.8.10 dev: true - /@types/sockjs@0.3.34: - resolution: {integrity: sha512-R+n7qBFnm/6jinlteC9DBL5dGiDGjWAvjo4viUanpnc/dG1y7uDoacXPIQ/PQEg1fI912SMHIa014ZjRpvDw4g==} + /@types/sockjs@0.3.35: + resolution: {integrity: sha512-tIF57KB+ZvOBpAQwSaACfEu7htponHXaFzP7RfKYgsOS0NoYnn+9+jzp7bbq4fWerizI3dTB4NfAZoyeQKWJLw==} dependencies: - '@types/node': 20.8.3 + '@types/node': 20.8.10 dev: true - /@types/stack-utils@2.0.1: - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + /@types/stack-utils@2.0.2: + resolution: {integrity: sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw==} dev: true - /@types/vinyl@2.0.8: - resolution: {integrity: sha512-bls3EAsYVnVoPKoqgFC4Rtq7Kzte4MCk8xMA9UEPPVncJFsov9FJWYj0uxqJRwNEi9b4i4zX13FydaDrhadmHg==} + /@types/vinyl@2.0.9: + resolution: {integrity: sha512-KCr4aTEUkzSF89qw09e2oxsC/RXXT3K5ZPv4gvj3XTiWVrxNoi7WrqNTahNE/Hul5C9z3B8w+yWNTQgua12oag==} dependencies: '@types/expect': 1.20.4 '@types/node': 15.14.9 dev: true - /@types/ws@8.5.6: - resolution: {integrity: sha512-8B5EO9jLVCy+B58PLHvLDuOD8DRVMgQzq8d55SjLCOn9kqGyqOvy27exVaTio1q1nX5zLu8/6N0n2ThSxOM6tg==} + /@types/ws@8.5.8: + resolution: {integrity: sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg==} dependencies: - '@types/node': 20.8.3 + '@types/node': 20.8.10 dev: true - /@types/yargs-parser@21.0.1: - resolution: {integrity: sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==} + /@types/yargs-parser@21.0.2: + resolution: {integrity: sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw==} dev: true - /@types/yargs@17.0.28: - resolution: {integrity: sha512-N3e3fkS86hNhtk6BEnc0rj3zcehaxx8QWhCROJkqpl5Zaoi7nAic3jH8q94jVD3zu5LGk+PUB6KAiDmimYOEQw==} + /@types/yargs@17.0.29: + resolution: {integrity: sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA==} dependencies: - '@types/yargs-parser': 21.0.1 + '@types/yargs-parser': 21.0.2 dev: true - /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.51.0)(typescript@5.1.6): + /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.53.0)(typescript@5.1.6): resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2478,13 +2487,13 @@ packages: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.9.1 - '@typescript-eslint/parser': 5.62.0(eslint@8.51.0)(typescript@5.1.6) + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 5.62.0(eslint@8.53.0)(typescript@5.1.6) '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.51.0)(typescript@5.1.6) - '@typescript-eslint/utils': 5.62.0(eslint@8.51.0)(typescript@5.1.6) + '@typescript-eslint/type-utils': 5.62.0(eslint@8.53.0)(typescript@5.1.6) + '@typescript-eslint/utils': 5.62.0(eslint@8.53.0)(typescript@5.1.6) debug: 4.3.4 - eslint: 8.51.0 + eslint: 8.53.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare-lite: 1.4.0 @@ -2495,7 +2504,7 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@5.62.0(eslint@8.51.0)(typescript@5.1.6): + /@typescript-eslint/parser@5.62.0(eslint@8.53.0)(typescript@5.1.6): resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2509,7 +2518,7 @@ packages: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6) debug: 4.3.4 - eslint: 8.51.0 + eslint: 8.53.0 typescript: 5.1.6 transitivePeerDependencies: - supports-color @@ -2523,7 +2532,7 @@ packages: '@typescript-eslint/visitor-keys': 5.62.0 dev: true - /@typescript-eslint/type-utils@5.62.0(eslint@8.51.0)(typescript@5.1.6): + /@typescript-eslint/type-utils@5.62.0(eslint@8.53.0)(typescript@5.1.6): resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2534,9 +2543,9 @@ packages: optional: true dependencies: '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6) - '@typescript-eslint/utils': 5.62.0(eslint@8.51.0)(typescript@5.1.6) + '@typescript-eslint/utils': 5.62.0(eslint@8.53.0)(typescript@5.1.6) debug: 4.3.4 - eslint: 8.51.0 + eslint: 8.53.0 tsutils: 3.21.0(typescript@5.1.6) typescript: 5.1.6 transitivePeerDependencies: @@ -2569,19 +2578,19 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@5.62.0(eslint@8.51.0)(typescript@5.1.6): + /@typescript-eslint/utils@5.62.0(eslint@8.53.0)(typescript@5.1.6): resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0) - '@types/json-schema': 7.0.13 - '@types/semver': 7.5.3 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) + '@types/json-schema': 7.0.14 + '@types/semver': 7.5.4 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6) - eslint: 8.51.0 + eslint: 8.53.0 eslint-scope: 5.1.1 semver: 7.5.4 transitivePeerDependencies: @@ -2597,6 +2606,10 @@ packages: eslint-visitor-keys: 3.4.3 dev: true + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + /@webassemblyjs/ast@1.11.6: resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==} dependencies: @@ -2703,18 +2716,18 @@ packages: '@xtuc/long': 4.2.2 dev: true - /@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.88.2): + /@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.89.0): resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==} engines: {node: '>=14.15.0'} peerDependencies: webpack: 5.x.x webpack-cli: 5.x.x dependencies: - webpack: 5.88.2(webpack-cli@5.1.4) - webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.88.2) + webpack: 5.89.0(webpack-cli@5.1.4) + webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.89.0) dev: true - /@webpack-cli/generators@3.0.7(prettier@2.8.8)(webpack-cli@5.1.4)(webpack@5.88.2): + /@webpack-cli/generators@3.0.7(prettier@2.8.8)(webpack-cli@5.1.4)(webpack@5.89.0): resolution: {integrity: sha512-H4dlEX8CzO5EHBYYZQop9x4w6lG9FenSF/1spLRlvRAULDgTs0VfmwOuwp03tTLml9jpMsouuVw6vEN8KpwE/w==} engines: {node: '>=14.15.0'} peerDependencies: @@ -2726,10 +2739,10 @@ packages: optional: true dependencies: prettier: 2.8.8 - webpack: 5.88.2(webpack-cli@5.1.4) - webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.88.2) + webpack: 5.89.0(webpack-cli@5.1.4) + webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.89.0) yeoman-environment: 3.19.3 - yeoman-generator: 5.9.0(yeoman-environment@3.19.3) + yeoman-generator: 5.10.0(yeoman-environment@3.19.3) transitivePeerDependencies: - bluebird - encoding @@ -2737,18 +2750,18 @@ packages: - supports-color dev: true - /@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.88.2): + /@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.89.0): resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==} engines: {node: '>=14.15.0'} peerDependencies: webpack: 5.x.x webpack-cli: 5.x.x dependencies: - webpack: 5.88.2(webpack-cli@5.1.4) - webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.88.2) + webpack: 5.89.0(webpack-cli@5.1.4) + webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.89.0) dev: true - /@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.1)(webpack@5.88.2): + /@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.1)(webpack@5.89.0): resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==} engines: {node: '>=14.15.0'} peerDependencies: @@ -2759,9 +2772,9 @@ packages: webpack-dev-server: optional: true dependencies: - webpack: 5.88.2(webpack-cli@5.1.4) - webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.88.2) - webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2) + webpack: 5.89.0(webpack-cli@5.1.4) + webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.89.0) + webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0) dev: true /@xtuc/ieee754@1.2.0: @@ -2791,29 +2804,29 @@ packages: negotiator: 0.6.3 dev: true - /acorn-import-assertions@1.9.0(acorn@8.10.0): + /acorn-import-assertions@1.9.0(acorn@8.11.2): resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} peerDependencies: acorn: ^8 dependencies: - acorn: 8.10.0 + acorn: 8.11.2 dev: true - /acorn-jsx@5.3.2(acorn@8.10.0): + /acorn-jsx@5.3.2(acorn@8.11.2): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 8.10.0 + acorn: 8.11.2 dev: true - /acorn-walk@8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + /acorn-walk@8.3.0: + resolution: {integrity: sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==} engines: {node: '>=0.4.0'} dev: true - /acorn@8.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + /acorn@8.11.2: + resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} engines: {node: '>=0.4.0'} hasBin: true dev: true @@ -2984,7 +2997,7 @@ packages: /array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 is-array-buffer: 3.0.2 dev: true @@ -3005,10 +3018,10 @@ packages: resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 - get-intrinsic: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 is-string: 1.0.7 dev: true @@ -3021,31 +3034,31 @@ packages: resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 - es-shim-unscopables: 1.0.0 - get-intrinsic: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 + get-intrinsic: 1.2.2 dev: true /array.prototype.flat@1.3.2: resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 - es-shim-unscopables: 1.0.0 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 dev: true /array.prototype.flatmap@1.3.2: resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 - es-shim-unscopables: 1.0.0 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 dev: true /arraybuffer.prototype.slice@1.0.2: @@ -3053,10 +3066,10 @@ packages: engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.0 - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 - get-intrinsic: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 is-array-buffer: 3.0.2 is-shared-array-buffer: 1.0.2 dev: true @@ -3076,8 +3089,8 @@ packages: lodash: 4.17.21 dev: true - /async@3.2.4: - resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} + /async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} dev: true /available-typed-arrays@1.0.5: @@ -3085,17 +3098,17 @@ packages: engines: {node: '>= 0.4'} dev: true - /babel-jest@29.7.0(@babel/core@7.23.0): + /babel-jest@29.7.0(@babel/core@7.23.2): resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.8.0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.2 + '@types/babel__core': 7.20.3 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.23.0) + babel-preset-jest: 29.6.3(@babel/core@7.23.2) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -3122,75 +3135,75 @@ packages: dependencies: '@babel/template': 7.22.15 '@babel/types': 7.23.0 - '@types/babel__core': 7.20.2 - '@types/babel__traverse': 7.20.2 + '@types/babel__core': 7.20.3 + '@types/babel__traverse': 7.20.3 dev: true - /babel-plugin-polyfill-corejs2@0.4.5(@babel/core@7.23.0): - resolution: {integrity: sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==} + /babel-plugin-polyfill-corejs2@0.4.6(@babel/core@7.23.2): + resolution: {integrity: sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/compat-data': 7.22.20 - '@babel/core': 7.23.0 - '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.23.0) + '@babel/compat-data': 7.23.2 + '@babel/core': 7.23.2 + '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2) semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-corejs3@0.8.4(@babel/core@7.23.0): - resolution: {integrity: sha512-9l//BZZsPR+5XjyJMPtZSK4jv0BsTO1zDac2GC6ygx9WLGlcsnRd1Co0B2zT5fF5Ic6BZy+9m3HNZ3QcOeDKfg==} + /babel-plugin-polyfill-corejs3@0.8.6(@babel/core@7.23.2): + resolution: {integrity: sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.23.0) - core-js-compat: 3.33.0 + '@babel/core': 7.23.2 + '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2) + core-js-compat: 3.33.2 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-regenerator@0.5.2(@babel/core@7.23.0): - resolution: {integrity: sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==} + /babel-plugin-polyfill-regenerator@0.5.3(@babel/core@7.23.2): + resolution: {integrity: sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.23.0 - '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.23.0) + '@babel/core': 7.23.2 + '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2) transitivePeerDependencies: - supports-color dev: true - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.0): + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.2): resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.0 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.0) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.0) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.0) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.0) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.0) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.0) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.0) - dev: true - - /babel-preset-jest@29.6.3(@babel/core@7.23.0): + '@babel/core': 7.23.2 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.2) + dev: true + + /babel-preset-jest@29.6.3(@babel/core@7.23.2): resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.0) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.2) dev: true /babel@6.23.0: @@ -3199,8 +3212,8 @@ packages: hasBin: true dev: true - /babylonjs-gltf2interface@6.23.0: - resolution: {integrity: sha512-bgoBsL7IzSuL72ZIJCvGV6PJ6FKngI3WWi6OQMup1WxLRKpjmKFAhaMCF/ERjB/hzeukLSXtF3g86+d9hrkLYw==} + /babylonjs-gltf2interface@6.28.1: + resolution: {integrity: sha512-rBOS/Vl2xpsHx93m2mGJOOqi1ofLgVGNFp5C56byrUqqlDz+GdmuLtROrHTDMZaEkHsCv8GWW72o3qFTBjSJOQ==} dev: true /balanced-match@1.0.2: @@ -3247,8 +3260,8 @@ packages: engines: {node: '>=8'} dev: true - /binaryextensions@4.18.0: - resolution: {integrity: sha512-PQu3Kyv9dM4FnwB7XGj1+HucW+ShvJzJqjuw1JkKVs1mWdwOKVcRjOi+pV9X52A0tNvrPCsPkbFFQb+wE1EAXw==} + /binaryextensions@4.19.0: + resolution: {integrity: sha512-DRxnVbOi/1OgA5pA9EDiRT8gvVYeqfuN7TmPfLyt6cyho3KbHCi3EtDQf39TTmGDrR5dZ9CspdXhPkL/j/WGbg==} engines: {node: '>=0.8'} dev: true @@ -3318,8 +3331,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001546 - electron-to-chromium: 1.4.544 + caniuse-lite: 1.0.30001561 + electron-to-chromium: 1.4.576 node-releases: 2.0.13 update-browserslist-db: 1.0.13(browserslist@4.22.1) dev: true @@ -3445,11 +3458,12 @@ packages: unique-filename: 3.0.0 dev: true - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + set-function-length: 1.1.1 dev: true /callsites@3.1.0: @@ -3474,8 +3488,8 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite@1.0.30001546: - resolution: {integrity: sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==} + /caniuse-lite@1.0.30001561: + resolution: {integrity: sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==} dev: true /chalk@2.4.2: @@ -3763,8 +3777,8 @@ packages: is-what: 3.14.1 dev: true - /core-js-compat@3.33.0: - resolution: {integrity: sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==} + /core-js-compat@3.33.2: + resolution: {integrity: sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw==} dependencies: browserslist: 4.22.1 dev: true @@ -3778,7 +3792,7 @@ packages: engines: {node: '>= 0.4.0'} dev: true - /create-jest@29.7.0(@types/node@20.8.3)(ts-node@10.9.1): + /create-jest@29.7.0(@types/node@20.8.10)(ts-node@10.9.1): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -3787,7 +3801,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.8.3)(ts-node@10.9.1) + jest-config: 29.7.0(@types/node@20.8.10)(ts-node@10.9.1) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -3810,7 +3824,7 @@ packages: which: 2.0.2 dev: true - /css-loader@6.8.1(webpack@5.88.2): + /css-loader@6.8.1(webpack@5.89.0): resolution: {integrity: sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -3824,7 +3838,7 @@ packages: postcss-modules-values: 4.0.0(postcss@8.4.31) postcss-value-parser: 4.2.0 semver: 7.5.4 - webpack: 5.88.2(webpack-cli@5.1.4) + webpack: 5.89.0(webpack-cli@5.1.4) dev: true /css-select@4.3.0: @@ -3932,13 +3946,13 @@ packages: clone: 1.0.4 dev: true - /define-data-property@1.1.0: - resolution: {integrity: sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==} + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 gopd: 1.0.1 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.1 dev: true /define-lazy-prop@2.0.0: @@ -3950,8 +3964,8 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.0 - has-property-descriptors: 1.0.0 + define-data-property: 1.1.1 + has-property-descriptors: 1.0.1 object-keys: 1.1.1 dev: true @@ -4102,8 +4116,8 @@ packages: jake: 10.8.7 dev: true - /electron-to-chromium@1.4.544: - resolution: {integrity: sha512-54z7squS1FyFRSUqq/knOFSptjjogLZXbKcYk3B0qkE1KZzvqASwRZnY2KzZQJqIYLVD38XZeoiMRflYSwyO4w==} + /electron-to-chromium@1.4.576: + resolution: {integrity: sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA==} dev: true /emittery@0.13.1: @@ -4159,8 +4173,8 @@ packages: engines: {node: '>=6'} dev: true - /envinfo@7.10.0: - resolution: {integrity: sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==} + /envinfo@7.11.0: + resolution: {integrity: sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==} engines: {node: '>=4'} hasBin: true dev: true @@ -4188,26 +4202,26 @@ packages: resolution: {integrity: sha512-YxIFEJuhgcICugOUvRx5th0UM+ActZ9sjY0QJmeVwsQdvosZ7kYzc9QqS0Da3R5iUmgU5meGIxh0xBeZpMVeLw==} dev: true - /es-abstract@1.22.2: - resolution: {integrity: sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==} + /es-abstract@1.22.3: + resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.0 arraybuffer.prototype.slice: 1.0.2 available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - es-set-tostringtag: 2.0.1 + call-bind: 1.0.5 + es-set-tostringtag: 2.0.2 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 get-symbol-description: 1.0.0 globalthis: 1.0.3 gopd: 1.0.1 - has: 1.0.4 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.1 has-proto: 1.0.1 has-symbols: 1.0.3 - internal-slot: 1.0.5 + hasown: 2.0.0 + internal-slot: 1.0.6 is-array-buffer: 3.0.2 is-callable: 1.2.7 is-negative-zero: 2.0.2 @@ -4216,7 +4230,7 @@ packages: is-string: 1.0.7 is-typed-array: 1.1.12 is-weakref: 1.0.2 - object-inspect: 1.12.3 + object-inspect: 1.13.1 object-keys: 1.1.1 object.assign: 4.1.4 regexp.prototype.flags: 1.5.1 @@ -4230,26 +4244,26 @@ packages: typed-array-byte-offset: 1.0.0 typed-array-length: 1.0.4 unbox-primitive: 1.0.2 - which-typed-array: 1.1.11 + which-typed-array: 1.1.13 dev: true /es-module-lexer@1.3.1: resolution: {integrity: sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==} dev: true - /es-set-tostringtag@2.0.1: - resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + /es-set-tostringtag@2.0.2: + resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.1 - has: 1.0.4 + get-intrinsic: 1.2.2 has-tostringtag: 1.0.0 + hasown: 2.0.0 dev: true - /es-shim-unscopables@1.0.0: - resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + /es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} dependencies: - has: 1.0.4 + hasown: 2.0.0 dev: true /es-to-primitive@1.2.1: @@ -4289,13 +4303,13 @@ packages: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} dependencies: debug: 3.2.7 - is-core-module: 2.13.0 - resolve: 1.22.6 + is-core-module: 2.13.1 + resolve: 1.22.8 transitivePeerDependencies: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint@8.51.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint@8.53.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -4316,16 +4330,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.51.0)(typescript@5.1.6) + '@typescript-eslint/parser': 5.62.0(eslint@8.53.0)(typescript@5.1.6) debug: 3.2.7 - eslint: 8.51.0 + eslint: 8.53.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-import@2.28.1(@typescript-eslint/parser@5.62.0)(eslint@8.51.0): - resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==} + /eslint-plugin-import@2.29.0(@typescript-eslint/parser@5.62.0)(eslint@8.53.0): + resolution: {integrity: sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -4334,18 +4348,18 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.51.0)(typescript@5.1.6) + '@typescript-eslint/parser': 5.62.0(eslint@8.53.0)(typescript@5.1.6) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.51.0 + eslint: 8.53.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint@8.51.0) - has: 1.0.4 - is-core-module: 2.13.0 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint@8.53.0) + hasown: 2.0.0 + is-core-module: 2.13.1 is-glob: 4.0.3 minimatch: 3.1.2 object.fromentries: 2.0.7 @@ -4380,18 +4394,19 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.51.0: - resolution: {integrity: sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==} + /eslint@8.53.0: + resolution: {integrity: sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0) - '@eslint-community/regexpp': 4.9.1 - '@eslint/eslintrc': 2.1.2 - '@eslint/js': 8.51.0 - '@humanwhocodes/config-array': 0.11.11 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.3 + '@eslint/js': 8.53.0 + '@humanwhocodes/config-array': 0.11.13 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 @@ -4430,8 +4445,8 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.10.0 - acorn-jsx: 5.3.2(acorn@8.10.0) + acorn: 8.11.2 + acorn-jsx: 5.3.2(acorn@8.11.2) eslint-visitor-keys: 3.4.3 dev: true @@ -4708,6 +4723,11 @@ packages: rimraf: 3.0.2 dev: true + /flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + dev: true + /flatted@3.2.9: resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} dev: true @@ -4776,17 +4796,17 @@ packages: dev: true optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} dev: true /function.prototype.name@1.1.6: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 functions-have-names: 1.2.3 dev: true @@ -4833,13 +4853,13 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true - /get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + /get-intrinsic@1.2.2: + resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} dependencies: - function-bind: 1.1.1 - has: 1.0.4 + function-bind: 1.1.2 has-proto: 1.0.1 has-symbols: 1.0.3 + hasown: 2.0.0 dev: true /get-package-type@0.1.0: @@ -4856,8 +4876,8 @@ packages: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 dev: true /github-username@6.0.0: @@ -5041,7 +5061,7 @@ packages: graceful-fs: 4.2.11 inherits: 2.0.4 map-limit: 0.0.1 - resolve: 1.22.6 + resolve: 1.22.8 dev: true /glslify-loader@2.0.0: @@ -5051,13 +5071,13 @@ packages: glslify-bundle: 5.1.1 glslify-deps: 1.3.2 loader-utils: 1.4.2 - resolve: 1.22.6 + resolve: 1.22.8 dev: true /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 dev: true /graceful-fs@4.2.11: @@ -5095,10 +5115,10 @@ packages: engines: {node: '>=8'} dev: true - /has-property-descriptors@1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + /has-property-descriptors@1.0.1: + resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 dev: true /has-proto@1.0.1: @@ -5122,9 +5142,11 @@ packages: resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} dev: true - /has@1.0.4: - resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} - engines: {node: '>= 0.4.0'} + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 dev: true /he@1.2.0: @@ -5174,7 +5196,7 @@ packages: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true - /html-loader@4.2.0(webpack@5.88.2): + /html-loader@4.2.0(webpack@5.89.0): resolution: {integrity: sha512-OxCHD3yt+qwqng2vvcaPApCEvbx+nXWu+v69TYHx1FO8bffHn/JjHtE3TTQZmHjwvnJe4xxzuecetDVBrQR1Zg==} engines: {node: '>= 14.15.0'} peerDependencies: @@ -5182,7 +5204,7 @@ packages: dependencies: html-minifier-terser: 7.2.0 parse5: 7.1.2 - webpack: 5.88.2(webpack-cli@5.1.4) + webpack: 5.89.0(webpack-cli@5.1.4) dev: true /html-minifier-terser@6.1.0: @@ -5196,7 +5218,7 @@ packages: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.21.0 + terser: 5.24.0 dev: true /html-minifier-terser@7.2.0: @@ -5210,10 +5232,10 @@ packages: entities: 4.5.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.21.0 + terser: 5.24.0 dev: true - /html-webpack-plugin@5.5.3(webpack@5.88.2): + /html-webpack-plugin@5.5.3(webpack@5.89.0): resolution: {integrity: sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==} engines: {node: '>=10.13.0'} peerDependencies: @@ -5224,7 +5246,7 @@ packages: lodash: 4.17.21 pretty-error: 4.0.0 tapable: 2.2.1 - webpack: 5.88.2(webpack-cli@5.1.4) + webpack: 5.89.0(webpack-cli@5.1.4) dev: true /htmlparser2@6.1.0: @@ -5291,7 +5313,7 @@ packages: - supports-color dev: true - /http-proxy-middleware@2.0.6(@types/express@4.17.18): + /http-proxy-middleware@2.0.6(@types/express@4.17.20): resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -5300,8 +5322,8 @@ packages: '@types/express': optional: true dependencies: - '@types/express': 4.17.18 - '@types/http-proxy': 1.17.12 + '@types/express': 4.17.20 + '@types/http-proxy': 1.17.13 http-proxy: 1.18.1 is-glob: 4.0.3 is-plain-obj: 3.0.0 @@ -5490,12 +5512,12 @@ packages: wrap-ansi: 6.2.0 dev: true - /internal-slot@1.0.5: - resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + /internal-slot@1.0.6: + resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.1 - has: 1.0.4 + get-intrinsic: 1.2.2 + hasown: 2.0.0 side-channel: 1.0.4 dev: true @@ -5530,8 +5552,8 @@ packages: /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-typed-array: 1.1.12 dev: true @@ -5556,7 +5578,7 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-tostringtag: 1.0.0 dev: true @@ -5565,10 +5587,10 @@ packages: engines: {node: '>= 0.4'} dev: true - /is-core-module@2.13.0: - resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: - has: 1.0.4 + hasown: 2.0.0 dev: true /is-date-object@1.0.5: @@ -5663,7 +5685,7 @@ packages: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-tostringtag: 1.0.0 dev: true @@ -5677,7 +5699,7 @@ packages: /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 dev: true /is-stream@2.0.1: @@ -5703,7 +5725,7 @@ packages: resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} dependencies: - which-typed-array: 1.1.11 + which-typed-array: 1.1.13 dev: true /is-unicode-supported@0.1.0: @@ -5718,7 +5740,7 @@ packages: /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 dev: true /is-what@3.14.1: @@ -5772,7 +5794,7 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/parser': 7.23.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 @@ -5785,7 +5807,7 @@ packages: resolution: {integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==} engines: {node: '>=10'} dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/parser': 7.23.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 @@ -5836,7 +5858,7 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - async: 3.2.4 + async: 3.2.5 chalk: 4.1.2 filelist: 1.0.4 minimatch: 3.1.2 @@ -5859,7 +5881,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.3 + '@types/node': 20.8.10 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 @@ -5880,7 +5902,7 @@ packages: - supports-color dev: true - /jest-cli@29.7.0(@types/node@20.8.3)(ts-node@10.9.1): + /jest-cli@29.7.0(@types/node@20.8.10)(ts-node@10.9.1): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -5894,10 +5916,10 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.8.3)(ts-node@10.9.1) + create-jest: 29.7.0(@types/node@20.8.10)(ts-node@10.9.1) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.8.3)(ts-node@10.9.1) + jest-config: 29.7.0(@types/node@20.8.10)(ts-node@10.9.1) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -5908,7 +5930,7 @@ packages: - ts-node dev: true - /jest-config@29.7.0(@types/node@20.8.3)(ts-node@10.9.1): + /jest-config@29.7.0(@types/node@20.8.10)(ts-node@10.9.1): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -5920,11 +5942,11 @@ packages: ts-node: optional: true dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.3 - babel-jest: 29.7.0(@babel/core@7.23.0) + '@types/node': 20.8.10 + babel-jest: 29.7.0(@babel/core@7.23.2) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -5943,7 +5965,7 @@ packages: pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 - ts-node: 10.9.1(@types/node@20.8.3)(typescript@5.1.6) + ts-node: 10.9.1(@types/node@20.8.10)(typescript@5.1.6) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -5984,7 +6006,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.3 + '@types/node': 20.8.10 jest-mock: 29.7.0 jest-util: 29.7.0 dev: true @@ -5999,8 +6021,8 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.7 - '@types/node': 20.8.3 + '@types/graceful-fs': 4.1.8 + '@types/node': 20.8.10 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -6037,7 +6059,7 @@ packages: dependencies: '@babel/code-frame': 7.22.13 '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.1 + '@types/stack-utils': 2.0.2 chalk: 4.1.2 graceful-fs: 4.2.11 micromatch: 4.0.5 @@ -6051,7 +6073,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.8.3 + '@types/node': 20.8.10 jest-util: 29.7.0 dev: true @@ -6092,7 +6114,7 @@ packages: jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) jest-util: 29.7.0 jest-validate: 29.7.0 - resolve: 1.22.6 + resolve: 1.22.8 resolve.exports: 2.0.2 slash: 3.0.0 dev: true @@ -6106,7 +6128,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.3 + '@types/node': 20.8.10 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -6137,7 +6159,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.3 + '@types/node': 20.8.10 chalk: 4.1.2 cjs-module-lexer: 1.2.3 collect-v8-coverage: 1.0.2 @@ -6160,15 +6182,15 @@ packages: resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@babel/generator': 7.23.0 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2) '@babel/types': 7.23.0 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.0) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.2) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -6193,7 +6215,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.8.3 + '@types/node': 20.8.10 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -6218,7 +6240,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.3 + '@types/node': 20.8.10 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -6230,7 +6252,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 20.8.3 + '@types/node': 20.8.10 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -6239,13 +6261,13 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.8.3 + '@types/node': 20.8.10 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest@29.7.0(@types/node@20.8.3)(ts-node@10.9.1): + /jest@29.7.0(@types/node@20.8.10)(ts-node@10.9.1): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -6258,7 +6280,7 @@ packages: '@jest/core': 29.7.0(ts-node@10.9.1) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.8.3)(ts-node@10.9.1) + jest-cli: 29.7.0(@types/node@20.8.10)(ts-node@10.9.1) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -6654,7 +6676,7 @@ packages: mem-fs: optional: true dependencies: - binaryextensions: 4.18.0 + binaryextensions: 4.19.0 commondir: 1.0.1 deep-extend: 0.6.0 ejs: 3.1.9 @@ -6672,7 +6694,7 @@ packages: engines: {node: '>=12'} dependencies: '@types/node': 15.14.9 - '@types/vinyl': 2.0.8 + '@types/vinyl': 2.0.9 vinyl: 2.2.1 vinyl-file: 3.0.0 dev: true @@ -6733,14 +6755,14 @@ packages: engines: {node: '>=6'} dev: true - /mini-css-extract-plugin@2.7.6(webpack@5.88.2): + /mini-css-extract-plugin@2.7.6(webpack@5.89.0): resolution: {integrity: sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==} engines: {node: '>= 12.13.0'} peerDependencies: webpack: ^5.0.0 dependencies: schema-utils: 4.2.0 - webpack: 5.88.2(webpack-cli@5.1.4) + webpack: 5.89.0(webpack-cli@5.1.4) dev: true /minimalistic-assert@1.0.1: @@ -6913,8 +6935,8 @@ packages: ml-array-min: 1.2.3 dev: true - /ml-matrix@6.10.5: - resolution: {integrity: sha512-3RNGo8Ls3JR/f+8t0pNrvoDW6SmLNDBpQN6FzkFvNx7FJ3GL7Ic1kdxlDYavU3pRwxJFgBrRwZ0FwE+JjX+tvQ==} + /ml-matrix@6.10.8: + resolution: {integrity: sha512-AOWniClvQMbGx2V0mqzOScINLe+PjAjpjTN3zYRG7gV5Zp29fu9b2E0PfTdnupN03USOQMvkjT9/8yB4hEEahg==} dependencies: is-any-array: 2.0.1 ml-array-rescale: 1.3.7 @@ -7040,8 +7062,8 @@ packages: - supports-color dev: true - /node-gyp@9.4.0: - resolution: {integrity: sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==} + /node-gyp@9.4.1: + resolution: {integrity: sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==} engines: {node: ^12.13 || ^14.13 || >=16} hasBin: true dependencies: @@ -7049,7 +7071,7 @@ packages: exponential-backoff: 3.1.1 glob: 7.2.3 graceful-fs: 4.2.11 - make-fetch-happen: 11.1.1 + make-fetch-happen: 10.2.1 nopt: 6.0.0 npmlog: 6.0.2 rimraf: 3.0.2 @@ -7057,6 +7079,7 @@ packages: tar: 6.2.0 which: 2.0.2 transitivePeerDependencies: + - bluebird - supports-color dev: true @@ -7088,7 +7111,7 @@ packages: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.6 + resolve: 1.22.8 semver: 5.7.2 validate-npm-package-license: 3.0.4 dev: true @@ -7098,7 +7121,7 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: hosted-git-info: 6.1.1 - is-core-module: 2.13.0 + is-core-module: 2.13.1 semver: 7.5.4 validate-npm-package-license: 3.0.4 dev: true @@ -7272,8 +7295,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} dev: true /object-keys@1.1.1: @@ -7285,7 +7308,7 @@ packages: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 @@ -7295,27 +7318,27 @@ packages: resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 dev: true /object.groupby@1.0.1: resolution: {integrity: sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 - get-intrinsic: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 dev: true /object.values@1.1.7: resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 dev: true /obuf@1.1.2: @@ -7682,7 +7705,7 @@ packages: dependencies: lilconfig: 2.1.0 postcss: 8.4.31 - ts-node: 10.9.1(@types/node@20.8.3)(typescript@5.1.6) + ts-node: 10.9.1(@types/node@20.8.10)(typescript@5.1.6) yaml: 1.10.2 dev: true @@ -7854,8 +7877,8 @@ packages: dev: true optional: true - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} dev: true @@ -7902,7 +7925,7 @@ packages: unpipe: 1.0.0 dev: true - /raw-loader@4.0.2(webpack@5.88.2): + /raw-loader@4.0.2(webpack@5.89.0): resolution: {integrity: sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==} engines: {node: '>= 10.13.0'} peerDependencies: @@ -7910,7 +7933,7 @@ packages: dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.88.2(webpack-cli@5.1.4) + webpack: 5.89.0(webpack-cli@5.1.4) dev: true /react-is@18.2.0: @@ -7961,7 +7984,7 @@ packages: resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} engines: {node: '>=8'} dependencies: - '@types/normalize-package-data': 2.4.2 + '@types/normalize-package-data': 2.4.3 normalize-package-data: 2.5.0 parse-json: 5.2.0 type-fest: 0.6.0 @@ -8029,14 +8052,14 @@ packages: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} engines: {node: '>= 0.10'} dependencies: - resolve: 1.22.6 + resolve: 1.22.8 dev: true /rechoir@0.8.0: resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} engines: {node: '>= 10.13.0'} dependencies: - resolve: 1.22.6 + resolve: 1.22.8 dev: true /regenerate-unicode-properties@10.1.1: @@ -8057,14 +8080,14 @@ packages: /regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} dependencies: - '@babel/runtime': 7.23.1 + '@babel/runtime': 7.23.2 dev: true /regexp.prototype.flags@1.5.1: resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 set-function-name: 2.0.1 dev: true @@ -8156,11 +8179,11 @@ packages: resolution: {integrity: sha512-UHBY3viPlJKf85YijDUcikKX6tmF4SokIDp518ZDVT92JNDcG5uKIthaT/owt3Sar0lwtOafsQuwrg22/v2Dwg==} dev: true - /resolve@1.22.6: - resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==} + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true dependencies: - is-core-module: 2.13.0 + is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 dev: true @@ -8216,8 +8239,8 @@ packages: resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} engines: {node: '>=0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 has-symbols: 1.0.3 isarray: 2.0.5 dev: true @@ -8233,8 +8256,8 @@ packages: /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-regex: 1.1.4 dev: true @@ -8242,7 +8265,7 @@ packages: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} dev: true - /sass-loader@13.3.2(sass@1.69.0)(webpack@5.88.2): + /sass-loader@13.3.2(sass@1.69.5)(webpack@5.89.0): resolution: {integrity: sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==} engines: {node: '>= 14.15.0'} peerDependencies: @@ -8262,12 +8285,12 @@ packages: optional: true dependencies: neo-async: 2.6.2 - sass: 1.69.0 - webpack: 5.88.2(webpack-cli@5.1.4) + sass: 1.69.5 + webpack: 5.89.0(webpack-cli@5.1.4) dev: true - /sass@1.69.0: - resolution: {integrity: sha512-l3bbFpfTOGgQZCLU/gvm1lbsQ5mC/WnLz3djL2v4WCJBDrWm58PO+jgngcGRNnKUh6wSsdm50YaovTqskZ0xDQ==} + /sass@1.69.5: + resolution: {integrity: sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==} engines: {node: '>=14.0.0'} hasBin: true dependencies: @@ -8289,7 +8312,7 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/json-schema': 7.0.13 + '@types/json-schema': 7.0.14 ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) dev: true @@ -8298,7 +8321,7 @@ packages: resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} engines: {node: '>= 12.13.0'} dependencies: - '@types/json-schema': 7.0.13 + '@types/json-schema': 7.0.14 ajv: 8.12.0 ajv-formats: 2.1.1(ajv@8.12.0) ajv-keywords: 5.1.0(ajv@8.12.0) @@ -8317,10 +8340,11 @@ packages: resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} dev: true - /selfsigned@2.1.1: - resolution: {integrity: sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==} + /selfsigned@2.4.1: + resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} dependencies: + '@types/node-forge': 1.3.8 node-forge: 1.3.1 dev: true @@ -8400,13 +8424,23 @@ packages: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + /set-function-name@2.0.1: resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.0 + define-data-property: 1.1.1 functions-have-names: 1.2.3 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.1 dev: true /setprototypeof@1.1.0: @@ -8454,8 +8488,8 @@ packages: rechoir: 0.6.2 dev: true - /shiki@0.14.4: - resolution: {integrity: sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==} + /shiki@0.14.5: + resolution: {integrity: sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==} dependencies: ansi-sequence-parser: 1.1.1 jsonc-parser: 3.2.0 @@ -8466,9 +8500,9 @@ packages: /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - object-inspect: 1.12.3 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + object-inspect: 1.13.1 dev: true /signal-exit@3.0.7: @@ -8706,25 +8740,25 @@ packages: resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 dev: true /string.prototype.trimend@1.0.7: resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 dev: true /string.prototype.trimstart@1.0.7: resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 dev: true /string_decoder@0.10.31: @@ -8799,13 +8833,13 @@ packages: engines: {node: '>=8'} dev: true - /style-loader@3.3.3(webpack@5.88.2): + /style-loader@3.3.3(webpack@5.89.0): resolution: {integrity: sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw==} engines: {node: '>= 12.13.0'} peerDependencies: webpack: ^5.0.0 dependencies: - webpack: 5.88.2(webpack-cli@5.1.4) + webpack: 5.89.0(webpack-cli@5.1.4) dev: true /stylus@0.59.0: @@ -8868,7 +8902,7 @@ packages: resolution: {integrity: sha512-HLq1y471mzTF1OeGEyDPKtGCwGsI73YYcMIJqAM2Qinrr2lIp0+9FdZU6V7H+aiTVsZ+c6YNn8eF8MI8Sa4eyQ==} dev: true - /terser-webpack-plugin@5.3.9(webpack@5.88.2): + /terser-webpack-plugin@5.3.9(webpack@5.89.0): resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} engines: {node: '>= 10.13.0'} peerDependencies: @@ -8884,21 +8918,21 @@ packages: uglify-js: optional: true dependencies: - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.1 - terser: 5.21.0 - webpack: 5.88.2(webpack-cli@5.1.4) + terser: 5.24.0 + webpack: 5.89.0(webpack-cli@5.1.4) dev: true - /terser@5.21.0: - resolution: {integrity: sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==} + /terser@5.24.0: + resolution: {integrity: sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==} engines: {node: '>=10'} hasBin: true dependencies: '@jridgewell/source-map': 0.3.5 - acorn: 8.10.0 + acorn: 8.11.2 commander: 2.20.3 source-map-support: 0.5.21 dev: true @@ -8972,7 +9006,7 @@ packages: resolution: {integrity: sha512-whw60l7r+8ZU8Tu/Uc2yxtc4ZTZbR/PF3u1IPNKGQ6p8EICLb3Z2lAgoqw9bqYd8IkgnsaOcLzYHFckjqNsf0g==} dev: true - /ts-jest@29.1.1(@babel/core@7.23.0)(@jest/types@29.6.3)(babel-jest@29.7.0)(jest@29.7.0)(typescript@5.1.6): + /ts-jest@29.1.1(@babel/core@7.23.2)(@jest/types@29.6.3)(babel-jest@29.7.0)(jest@29.7.0)(typescript@5.1.6): resolution: {integrity: sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -8993,12 +9027,12 @@ packages: esbuild: optional: true dependencies: - '@babel/core': 7.23.0 + '@babel/core': 7.23.2 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.23.0) + babel-jest: 29.7.0(@babel/core@7.23.2) bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.8.3)(ts-node@10.9.1) + jest: 29.7.0(@types/node@20.8.10)(ts-node@10.9.1) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -9008,7 +9042,7 @@ packages: yargs-parser: 21.1.1 dev: true - /ts-loader@9.5.0(typescript@5.1.6)(webpack@5.88.2): + /ts-loader@9.5.0(typescript@5.1.6)(webpack@5.89.0): resolution: {integrity: sha512-LLlB/pkB4q9mW2yLdFMnK3dEHbrBjeZTYguaaIfusyojBgAGf5kF+O6KcWqiGzWqHk0LBsoolrp4VftEURhybg==} engines: {node: '>=12.0.0'} peerDependencies: @@ -9021,10 +9055,10 @@ packages: semver: 7.5.4 source-map: 0.7.4 typescript: 5.1.6 - webpack: 5.88.2(webpack-cli@5.1.4) + webpack: 5.89.0(webpack-cli@5.1.4) dev: true - /ts-node@10.9.1(@types/node@20.8.3)(typescript@5.1.6): + /ts-node@10.9.1(@types/node@20.8.10)(typescript@5.1.6): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -9043,9 +9077,9 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.8.3 - acorn: 8.10.0 - acorn-walk: 8.2.0 + '@types/node': 20.8.10 + acorn: 8.11.2 + acorn-walk: 8.3.0 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 @@ -9146,8 +9180,8 @@ packages: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-typed-array: 1.1.12 dev: true @@ -9155,7 +9189,7 @@ packages: resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -9166,7 +9200,7 @@ packages: engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -9175,7 +9209,7 @@ packages: /typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 is-typed-array: 1.1.12 dev: true @@ -9190,17 +9224,17 @@ packages: lunr: 2.3.9 marked: 4.3.0 minimatch: 9.0.3 - shiki: 0.14.4 + shiki: 0.14.5 typescript: 5.1.6 dev: true - /typescript-plugin-css-modules@5.0.1(ts-node@10.9.1)(typescript@5.1.6): - resolution: {integrity: sha512-hKXObfwfjx2/myRq4JeQ8D3xIWYTFqusi0hS/Aka7RFX1xQEoEkdOGDWyXNb8LmObawsUzbI30gQnZvqYXCrkA==} + /typescript-plugin-css-modules@5.0.2(ts-node@10.9.1)(typescript@5.1.6): + resolution: {integrity: sha512-ej/Og4Y8mF+43P14P9Ik1MGqNXcXBVgO1TltkESegdnZsaaRXnaJ5CoJmTPRkg25ysQlOV6P94wNhI4VxIzlkw==} peerDependencies: typescript: '>=4.0.0' dependencies: - '@types/postcss-modules-local-by-default': 4.0.0 - '@types/postcss-modules-scope': 3.0.2 + '@types/postcss-modules-local-by-default': 4.0.1 + '@types/postcss-modules-scope': 3.0.3 dotenv: 16.3.1 icss-utils: 5.1.0(postcss@8.4.31) less: 4.2.0 @@ -9211,7 +9245,7 @@ packages: postcss-modules-local-by-default: 4.0.3(postcss@8.4.31) postcss-modules-scope: 3.0.0(postcss@8.4.31) reserved-words: 0.1.2 - sass: 1.69.0 + sass: 1.69.5 source-map-js: 1.0.2 stylus: 0.59.0 tsconfig-paths: 4.2.0 @@ -9230,12 +9264,16 @@ packages: /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 dev: true + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + /unicode-canonical-property-names-ecmascript@2.0.0: resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} engines: {node: '>=4'} @@ -9306,8 +9344,8 @@ packages: imurmurhash: 0.1.4 dev: true - /universal-user-agent@6.0.0: - resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==} + /universal-user-agent@6.0.1: + resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} dev: true /unpipe@1.0.0: @@ -9334,7 +9372,7 @@ packages: /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: true /url-join@4.0.1: @@ -9367,8 +9405,8 @@ packages: resolution: {integrity: sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==} engines: {node: '>=10.12.0'} dependencies: - '@jridgewell/trace-mapping': 0.3.19 - '@types/istanbul-lib-coverage': 2.0.4 + '@jridgewell/trace-mapping': 0.3.20 + '@types/istanbul-lib-coverage': 2.0.5 convert-source-map: 2.0.0 dev: true @@ -9462,7 +9500,7 @@ packages: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: true - /webpack-cli@5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.88.2): + /webpack-cli@5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.89.0): resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==} engines: {node: '>=14.15.0'} hasBin: true @@ -9480,24 +9518,24 @@ packages: optional: true dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.88.2) - '@webpack-cli/generators': 3.0.7(prettier@2.8.8)(webpack-cli@5.1.4)(webpack@5.88.2) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.88.2) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.1)(webpack@5.88.2) + '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.89.0) + '@webpack-cli/generators': 3.0.7(prettier@2.8.8)(webpack-cli@5.1.4)(webpack@5.89.0) + '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.89.0) + '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.1)(webpack@5.89.0) colorette: 2.0.20 commander: 10.0.1 cross-spawn: 7.0.3 - envinfo: 7.10.0 + envinfo: 7.11.0 fastest-levenshtein: 1.0.16 import-local: 3.1.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.88.2(webpack-cli@5.1.4) - webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2) - webpack-merge: 5.9.0 + webpack: 5.89.0(webpack-cli@5.1.4) + webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0) + webpack-merge: 5.10.0 dev: true - /webpack-dev-middleware@5.3.3(webpack@5.88.2): + /webpack-dev-middleware@5.3.3(webpack@5.89.0): resolution: {integrity: sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -9508,10 +9546,10 @@ packages: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.88.2(webpack-cli@5.1.4) + webpack: 5.89.0(webpack-cli@5.1.4) dev: true - /webpack-dev-server@4.15.1(webpack-cli@5.1.4)(webpack@5.88.2): + /webpack-dev-server@4.15.1(webpack-cli@5.1.4)(webpack@5.89.0): resolution: {integrity: sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==} engines: {node: '>= 12.13.0'} hasBin: true @@ -9524,13 +9562,13 @@ packages: webpack-cli: optional: true dependencies: - '@types/bonjour': 3.5.11 - '@types/connect-history-api-fallback': 1.5.1 - '@types/express': 4.17.18 - '@types/serve-index': 1.9.2 - '@types/serve-static': 1.15.3 - '@types/sockjs': 0.3.34 - '@types/ws': 8.5.6 + '@types/bonjour': 3.5.12 + '@types/connect-history-api-fallback': 1.5.2 + '@types/express': 4.17.20 + '@types/serve-index': 1.9.3 + '@types/serve-static': 1.15.4 + '@types/sockjs': 0.3.35 + '@types/ws': 8.5.8 ansi-html-community: 0.0.8 bonjour-service: 1.1.1 chokidar: 3.5.3 @@ -9541,20 +9579,20 @@ packages: express: 4.18.2 graceful-fs: 4.2.11 html-entities: 2.4.0 - http-proxy-middleware: 2.0.6(@types/express@4.17.18) + http-proxy-middleware: 2.0.6(@types/express@4.17.20) ipaddr.js: 2.1.0 launch-editor: 2.6.1 open: 8.4.2 p-retry: 4.6.2 rimraf: 3.0.2 schema-utils: 4.2.0 - selfsigned: 2.1.1 + selfsigned: 2.4.1 serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.88.2(webpack-cli@5.1.4) - webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.88.2) - webpack-dev-middleware: 5.3.3(webpack@5.88.2) + webpack: 5.89.0(webpack-cli@5.1.4) + webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.89.0) + webpack-dev-middleware: 5.3.3(webpack@5.89.0) ws: 8.14.2 transitivePeerDependencies: - bufferutil @@ -9563,11 +9601,12 @@ packages: - utf-8-validate dev: true - /webpack-merge@5.9.0: - resolution: {integrity: sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==} + /webpack-merge@5.10.0: + resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} engines: {node: '>=10.0.0'} dependencies: clone-deep: 4.0.1 + flat: 5.0.2 wildcard: 2.0.1 dev: true @@ -9576,8 +9615,8 @@ packages: engines: {node: '>=10.13.0'} dev: true - /webpack@5.88.2(webpack-cli@5.1.4): - resolution: {integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==} + /webpack@5.89.0(webpack-cli@5.1.4): + resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -9586,13 +9625,13 @@ packages: webpack-cli: optional: true dependencies: - '@types/eslint-scope': 3.7.5 - '@types/estree': 1.0.2 + '@types/eslint-scope': 3.7.6 + '@types/estree': 1.0.4 '@webassemblyjs/ast': 1.11.6 '@webassemblyjs/wasm-edit': 1.11.6 '@webassemblyjs/wasm-parser': 1.11.6 - acorn: 8.10.0 - acorn-import-assertions: 1.9.0(acorn@8.10.0) + acorn: 8.11.2 + acorn-import-assertions: 1.9.0(acorn@8.11.2) browserslist: 4.22.1 chrome-trace-event: 1.0.3 enhanced-resolve: 5.15.0 @@ -9607,9 +9646,9 @@ packages: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.9(webpack@5.88.2) + terser-webpack-plugin: 5.3.9(webpack@5.89.0) watchpack: 2.4.0 - webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.88.2) + webpack-cli: 5.1.4(@webpack-cli/generators@3.0.7)(webpack-dev-server@4.15.1)(webpack@5.89.0) webpack-sources: 3.2.3 transitivePeerDependencies: - '@swc/core' @@ -9663,12 +9702,12 @@ packages: path-exists: 4.0.0 dev: true - /which-typed-array@1.1.11: - resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} + /which-typed-array@1.1.13: + resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0 @@ -9806,7 +9845,7 @@ packages: '@npmcli/arborist': 4.3.1 are-we-there-yet: 2.0.0 arrify: 2.0.1 - binaryextensions: 4.18.0 + binaryextensions: 4.19.0 chalk: 4.1.2 cli-table: 0.3.11 commander: 7.1.0 @@ -9845,8 +9884,8 @@ packages: - supports-color dev: true - /yeoman-generator@5.9.0(yeoman-environment@3.19.3): - resolution: {integrity: sha512-sN1e01Db4fdd8P/n/yYvizfy77HdbwzvXmPxps9Gwz2D24slegrkSn+qyj+0nmZhtFwGX2i/cH29QDrvAFT9Aw==} + /yeoman-generator@5.10.0(yeoman-environment@3.19.3): + resolution: {integrity: sha512-iDUKykV7L4nDNzeYSedRmSeJ5eMYFucnKDi6KN1WNASXErgPepKqsQw55TgXPHnmpcyOh2Dd/LAZkyc+f0qaAw==} engines: {node: '>=12.10.0'} peerDependencies: yeoman-environment: ^3.2.0 From 89511210b53f1648435a9e0dc014ce82a5e4069e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 17:26:38 +0100 Subject: [PATCH 77/86] basic text overlay --- src/ts/controller/StarSystemView.ts | 3 ++- src/ts/ui/objectOverlay.ts | 32 +++++++++++++++++++++++++++++ src/ts/ui/systemUI.ts | 16 +++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/ts/ui/objectOverlay.ts diff --git a/src/ts/controller/StarSystemView.ts b/src/ts/controller/StarSystemView.ts index b7006586d..f8fe0bed9 100644 --- a/src/ts/controller/StarSystemView.ts +++ b/src/ts/controller/StarSystemView.ts @@ -29,7 +29,7 @@ export class StarSystemView { private readonly orbitRenderer: OrbitRenderer = new OrbitRenderer(); private readonly axisRenderer: AxisRenderer = new AxisRenderer(); - private ui: SystemUI | null = null; + private readonly ui: SystemUI; private static readonly unZoomAnimation = new Animation("unZoom", "radius", 60, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CYCLE); @@ -128,6 +128,7 @@ export class StarSystemView { init() { this.getStarSystem().init(); + this.ui.createObjectOverlays(this.getStarSystem().getBodies()); const firstBody = this.getStarSystem().getBodies()[0]; if (firstBody === undefined) throw new Error("No bodies in star system"); diff --git a/src/ts/ui/objectOverlay.ts b/src/ts/ui/objectOverlay.ts new file mode 100644 index 000000000..28000d2c0 --- /dev/null +++ b/src/ts/ui/objectOverlay.ts @@ -0,0 +1,32 @@ +import { TextBlock } from "@babylonjs/gui/2D/controls/textBlock"; +import { AbstractObject } from "../view/bodies/abstractObject"; +import { StackPanel } from "@babylonjs/gui/2D/controls/stackPanel"; + +export class ObjectOverlay { + readonly textRoot: StackPanel; + readonly namePlate: TextBlock; + readonly object: AbstractObject; + + constructor(object: AbstractObject) { + this.object = object; + + this.textRoot = new StackPanel(); + this.textRoot.width = "200px"; + this.textRoot.height = "70px"; + this.textRoot.background = "darkred"; + this.textRoot.linkOffsetX = 100; + this.textRoot.zIndex = 6; + this.textRoot.alpha = 0.95; + + this.namePlate = new TextBlock(); + this.namePlate.text = object.name; + this.namePlate.color = "white"; + this.namePlate.zIndex = 6; + this.textRoot.addControl(this.namePlate); + //this.namePlate.setPadding(15, 15, 10, 15); + } + + init() { + this.textRoot.linkWithMesh(this.object.getTransform()); + } +} diff --git a/src/ts/ui/systemUI.ts b/src/ts/ui/systemUI.ts index 7e2711be7..121bb456b 100644 --- a/src/ts/ui/systemUI.ts +++ b/src/ts/ui/systemUI.ts @@ -1,9 +1,25 @@ import { Scene } from "@babylonjs/core/scene"; import { AdvancedDynamicTexture } from "@babylonjs/gui/2D/advancedDynamicTexture"; +import { AbstractObject } from "../view/bodies/abstractObject"; +import { ObjectOverlay } from "./objectOverlay"; export class SystemUI { private readonly gui: AdvancedDynamicTexture; + private objectOverlays: ObjectOverlay[] = []; + constructor(scene: Scene) { this.gui = AdvancedDynamicTexture.CreateFullscreenUI("SystemUI", true, scene); } + + public createObjectOverlays(objects: AbstractObject[]) { + for (const object of objects) { + const overlay = new ObjectOverlay(object); + this.gui.addControl(overlay.textRoot); + this.objectOverlays.push(overlay); + } + + for (const overlay of this.objectOverlays) { + overlay.init(); + } + } } From b7edab944b67817ee8d04f4c7be40a4267c15430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 17:54:01 +0100 Subject: [PATCH 78/86] ui based cursors --- src/ts/controller/StarSystemView.ts | 5 +++-- src/ts/ui/objectOverlay.ts | 35 ++++++++++++++++++++++++----- src/ts/ui/systemUI.ts | 8 +++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/ts/controller/StarSystemView.ts b/src/ts/controller/StarSystemView.ts index f8fe0bed9..670a94924 100644 --- a/src/ts/controller/StarSystemView.ts +++ b/src/ts/controller/StarSystemView.ts @@ -74,7 +74,6 @@ export class StarSystemView { ambientLight.intensity = 0.3; this.scene.onBeforePhysicsObservable.add(() => { - const starSystemScene = this.scene; const starSystem = this.getStarSystem(); const deltaTime = engine.getDeltaTime() / 1000; @@ -82,10 +81,12 @@ export class StarSystemView { Assets.ChunkForge.update(); starSystem.update(deltaTime * Settings.TIME_MULTIPLIER); + this.ui.update(this.scene.getActiveUberCamera().getAbsolutePosition()); + const nearestBody = starSystem.getNearestOrbitalObject(); if (nearestBody instanceof AbstractBody) { - this.bodyEditor.update(nearestBody, starSystem.postProcessManager, starSystemScene); + this.bodyEditor.update(nearestBody, starSystem.postProcessManager, this.scene); } this.helmetOverlay.update(nearestBody); diff --git a/src/ts/ui/objectOverlay.ts b/src/ts/ui/objectOverlay.ts index 28000d2c0..bb2da5ff1 100644 --- a/src/ts/ui/objectOverlay.ts +++ b/src/ts/ui/objectOverlay.ts @@ -1,32 +1,57 @@ import { TextBlock } from "@babylonjs/gui/2D/controls/textBlock"; import { AbstractObject } from "../view/bodies/abstractObject"; import { StackPanel } from "@babylonjs/gui/2D/controls/stackPanel"; +import { Image } from "@babylonjs/gui/2D/controls/image"; +import cursorImage from "../../asset/textures/hoveredCircle.png"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; export class ObjectOverlay { readonly textRoot: StackPanel; + readonly cursor: Image; readonly namePlate: TextBlock; readonly object: AbstractObject; constructor(object: AbstractObject) { this.object = object; - this.textRoot = new StackPanel(); - this.textRoot.width = "200px"; + this.textRoot = new StackPanel(object.name + "OverlayTextRoot"); + this.textRoot.width = "150px"; this.textRoot.height = "70px"; this.textRoot.background = "darkred"; - this.textRoot.linkOffsetX = 100; + this.textRoot.linkOffsetX = 130; this.textRoot.zIndex = 6; this.textRoot.alpha = 0.95; - this.namePlate = new TextBlock(); + this.namePlate = new TextBlock(object.name + "OverlayNamePlate"); this.namePlate.text = object.name; this.namePlate.color = "white"; this.namePlate.zIndex = 6; + this.namePlate.height = "50px"; + this.namePlate.textHorizontalAlignment = TextBlock.HORIZONTAL_ALIGNMENT_LEFT; this.textRoot.addControl(this.namePlate); - //this.namePlate.setPadding(15, 15, 10, 15); + + this.cursor = new Image(object.name + "Cursor", cursorImage); + this.cursor.fixedRatio = 1; + this.cursor.width = 1; + this.cursor.alpha = 0.8; + this.cursor.zIndex = 4; } init() { + console.log(this.object.getTransform()); this.textRoot.linkWithMesh(this.object.getTransform()); + this.cursor.linkWithMesh(this.object.getTransform()); + } + + update(cameraPosition: Vector3) { + if (this.cursor.linkedMesh === null) return; + const distance = this.cursor.linkedMesh.getAbsolutePosition().subtract(cameraPosition).length(); + const scale = 0.03 * Math.pow(this.object.getBoundingRadius() / 1e6, 0.2); + this.cursor.scaleX = scale; + this.cursor.scaleY = scale; + + const alpha = 1e-3 * distance / this.object.getBoundingRadius(); + this.textRoot.alpha = alpha; + this.cursor.alpha = Math.min(alpha, 0.5); } } diff --git a/src/ts/ui/systemUI.ts b/src/ts/ui/systemUI.ts index 121bb456b..4d6fb6f50 100644 --- a/src/ts/ui/systemUI.ts +++ b/src/ts/ui/systemUI.ts @@ -2,6 +2,7 @@ import { Scene } from "@babylonjs/core/scene"; import { AdvancedDynamicTexture } from "@babylonjs/gui/2D/advancedDynamicTexture"; import { AbstractObject } from "../view/bodies/abstractObject"; import { ObjectOverlay } from "./objectOverlay"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; export class SystemUI { private readonly gui: AdvancedDynamicTexture; @@ -15,6 +16,7 @@ export class SystemUI { for (const object of objects) { const overlay = new ObjectOverlay(object); this.gui.addControl(overlay.textRoot); + this.gui.addControl(overlay.cursor); this.objectOverlays.push(overlay); } @@ -22,4 +24,10 @@ export class SystemUI { overlay.init(); } } + + public update(cameraPosition: Vector3) { + for (const overlay of this.objectOverlays) { + overlay.update(cameraPosition); + } + } } From f4ef5857861c93fec253614bd54148532eb69957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 18:09:40 +0100 Subject: [PATCH 79/86] removed old overlay shader --- src/shaders/overlayFragment.glsl | 76 ------------------- src/ts/controller/StarSystemView.ts | 7 +- src/ts/controller/postProcessManager.ts | 24 ------ src/ts/controller/starSystem.ts | 10 ++- src/ts/ui/objectOverlay.ts | 2 +- src/ts/ui/systemUI.ts | 8 ++ src/ts/view/bodies/planemos/gasPlanet.ts | 2 +- src/ts/view/bodies/planemos/mandelbulb.ts | 2 +- .../view/bodies/planemos/telluricPlanemo.ts | 2 +- .../view/bodies/stellarObjects/blackHole.ts | 2 +- src/ts/view/bodies/stellarObjects/star.ts | 2 +- .../view/postProcesses/overlayPostProcess.ts | 43 ----------- src/ts/view/postProcesses/postProcessTypes.ts | 1 - src/ts/view/spaceStation.ts | 2 - 14 files changed, 25 insertions(+), 158 deletions(-) delete mode 100644 src/shaders/overlayFragment.glsl delete mode 100644 src/ts/view/postProcesses/overlayPostProcess.ts diff --git a/src/shaders/overlayFragment.glsl b/src/shaders/overlayFragment.glsl deleted file mode 100644 index 0a453e2eb..000000000 --- a/src/shaders/overlayFragment.glsl +++ /dev/null @@ -1,76 +0,0 @@ -precision lowp float; - -in vec2 vUV; - -uniform sampler2D textureSampler; -uniform sampler2D depthSampler; - -#pragma glslify: camera = require(./utils/camera.glsl) - -#pragma glslify: object = require(./utils/object.glsl) - -uniform bool isEnabled; - -uniform float aspectRatio; - -#pragma glslify: worldFromUV = require(./utils/worldFromUV.glsl, inverseProjection=camera.inverseProjection, inverseView=camera.inverseView); -#pragma glslify: uvFromWorld = require(./utils/uvFromWorld.glsl, projection=camera.projection, view=camera.view); - -#pragma glslify: remap = require(./utils/remap.glsl) - -void main() { - vec4 screenColor = texture2D(textureSampler, vUV); - if (!isEnabled) { - gl_FragColor = screenColor; - return; - } - - float depth = texture2D(depthSampler, vUV).r;// the depth corresponding to the pixel in the depth map - - vec3 pixelWorldPosition = worldFromUV(vUV);// the pixel position in world space (near plane) - // actual depth of the scene - float maximumDistance = length(pixelWorldPosition - camera.position) * remap(depth, 0.0, 1.0, camera.near, camera.far); - vec3 rayDir = normalize(pixelWorldPosition - camera.position); - - vec3 closestPoint = camera.position + rayDir * maximumDistance; - - if (maximumDistance < camera.far) { - gl_FragColor = screenColor; - return; - } - - vec4 overlayColor = vec4(0.0, 0.0, 0.0, screenColor.a); - - float planetDistance = length(object.position - camera.position); - vec3 planetDirection = (object.position - camera.position) / planetDistance; - - if (dot(planetDirection, normalize(closestPoint)) < 0.0) { - gl_FragColor = screenColor; - return; - } - - vec2 uv = uvFromWorld(object.position); - - vec2 vUVSquare = vec2(vUV.x * aspectRatio, vUV.y); - vec2 uvSquare = vec2(uv.x * aspectRatio, uv.y); - float distance = length(uvSquare - vUVSquare); - vec2 unitUVSquare = (uvSquare - vUVSquare) / distance; - - float limit1 = 0.03 * pow(object.radius / 1e6, 0.2); - float limit2 = max(limit1 + 0.005, 0.032 * limit1); - - if (distance >= limit1 && distance <= limit2) { - float angle = atan(unitUVSquare.y, unitUVSquare.x); - float angleOff = 0.2; - float targetAlpha = 1e-3 * planetDistance / object.radius; - if ((angle > angleOff && angle < 0.5 * 3.14 - angleOff) - || (angle < -angleOff && angle > -0.5 * 3.14 + angleOff) - || (angle > 0.5 * 3.14 + angleOff && angle < 3.14 - angleOff) - || (angle < -0.5 * 3.14 - angleOff && angle > -3.14 + angleOff)) { - overlayColor.rgb = vec3(targetAlpha); - overlayColor.rgb = min(overlayColor.rgb, vec3(0.3)); - overlayColor.a = 1.0; - } - } - gl_FragColor = vec4(screenColor.rgb + overlayColor.rgb, overlayColor.a); -} diff --git a/src/ts/controller/StarSystemView.ts b/src/ts/controller/StarSystemView.ts index 670a94924..2f3d8278d 100644 --- a/src/ts/controller/StarSystemView.ts +++ b/src/ts/controller/StarSystemView.ts @@ -6,7 +6,6 @@ import { AxisRenderer } from "../view/axisRenderer"; import { SystemUI } from "../ui/systemUI"; import { Animation } from "@babylonjs/core/Animations/animation"; import { StarSystem } from "./starSystem"; -import { OverlayPostProcess } from "../view/postProcesses/overlayPostProcess"; import { Engine } from "@babylonjs/core/Engines/engine"; import { HavokPlugin } from "@babylonjs/core/Physics/v2/Plugins/havokPlugin"; import { ScenePerformancePriority } from "@babylonjs/core/scene"; @@ -55,7 +54,9 @@ export class StarSystemView { ]); document.addEventListener("keydown", (e) => { - if (e.key === "o") OverlayPostProcess.ARE_ENABLED = !OverlayPostProcess.ARE_ENABLED; + if (e.key === "o") { + this.ui.setEnabled(!this.ui.isEnabled()); + } if (e.key === "n") { this.orbitRenderer.setVisibility(!this.orbitRenderer.isVisible()); this.axisRenderer.setVisibility(!this.axisRenderer.isVisible()); @@ -129,7 +130,7 @@ export class StarSystemView { init() { this.getStarSystem().init(); - this.ui.createObjectOverlays(this.getStarSystem().getBodies()); + this.ui.createObjectOverlays(this.getStarSystem().getObjects()); const firstBody = this.getStarSystem().getBodies()[0]; if (firstBody === undefined) throw new Error("No bodies in star system"); diff --git a/src/ts/controller/postProcessManager.ts b/src/ts/controller/postProcessManager.ts index 43eeb32a7..d4d46bee0 100644 --- a/src/ts/controller/postProcessManager.ts +++ b/src/ts/controller/postProcessManager.ts @@ -10,7 +10,6 @@ import { AtmosphericScatteringPostProcess } from "../view/postProcesses/atmosphe import { AbstractBody } from "../view/bodies/abstractBody"; import { RingsPostProcess } from "../view/postProcesses/ringsPostProcess"; import { StarfieldPostProcess } from "../view/postProcesses/starfieldPostProcess"; -import { OverlayPostProcess } from "../view/postProcesses/overlayPostProcess"; import { VolumetricLight } from "../view/postProcesses/volumetricLight"; import { BlackHolePostProcess } from "../view/postProcesses/blackHolePostProcess"; import { GasPlanet } from "../view/bodies/planemos/gasPlanet"; @@ -90,7 +89,6 @@ export class PostProcessManager { private readonly rings: RingsPostProcess[] = []; private readonly mandelbulbs: MandelbulbPostProcess[] = []; private readonly blackHoles: BlackHolePostProcess[] = []; - private readonly overlays: OverlayPostProcess[] = []; private readonly matterJets: MatterJetPostProcess[] = []; private readonly shadows: ShadowPostProcess[] = []; private readonly lensFlares: LensFlarePostProcess[] = []; @@ -105,7 +103,6 @@ export class PostProcessManager { this.rings, this.mandelbulbs, this.blackHoles, - this.overlays, this.volumetricLights, this.matterJets, this.shadows, @@ -121,7 +118,6 @@ export class PostProcessManager { readonly fxaa: FxaaPostProcess; private readonly starFieldRenderEffect: PostProcessRenderEffect; - private readonly overlayRenderEffect: PostProcessRenderEffect; private readonly colorCorrectionRenderEffect: PostProcessRenderEffect; private readonly fxaaRenderEffect: PostProcessRenderEffect; @@ -157,10 +153,6 @@ export class PostProcessManager { return this.starFields; }); - this.overlayRenderEffect = new PostProcessRenderEffect(this.engine, "overlayRenderEffect", () => { - return this.overlays; - }); - this.bloomRenderEffect = new BloomEffect(scene, 1, 0.3, 32); } @@ -263,15 +255,6 @@ export class PostProcessManager { this.starFields.push(new StarfieldPostProcess(this.scene, stellarObjects, planets, starfieldRotation)); } - /** - * Creates a new Overlay postprocess for the given body and adds it to the manager. - * @param body A body - */ - public addOverlay(body: BaseObject) { - const overlay = new OverlayPostProcess(body, this.scene); - this.overlays.push(overlay); - } - /** * Creates a new VolumetricLight postprocess for the given star and adds it to the manager. * @param star A star @@ -417,9 +400,6 @@ export class PostProcessManager { case PostProcessType.LENS_FLARE: //this.currentRenderingPipeline.addEffect(otherLensFlaresRenderEffect); break; - case PostProcessType.OVERLAY: - // do nothing as they are added at the end of the function - break; } } @@ -455,15 +435,11 @@ export class PostProcessManager { case PostProcessType.SHADOW: //this.currentRenderingPipeline.addEffect(bodyShadowRenderEffect); break; - case PostProcessType.OVERLAY: - // do nothing as they are added at the end of the function - break; } } this.currentRenderingPipeline.addEffect(shadowRenderEffect); this.currentRenderingPipeline.addEffect(lensFlareRenderEffect); - this.currentRenderingPipeline.addEffect(this.overlayRenderEffect); this.currentRenderingPipeline.addEffect(this.fxaaRenderEffect); this.currentRenderingPipeline.addEffect(this.bloomRenderEffect); this.currentRenderingPipeline.addEffect(this.colorCorrectionRenderEffect); diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index a3dbae0d7..f06a1dce5 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -164,6 +164,13 @@ export class StarSystem { return this.celestialBodies; } + public getObjects(): AbstractObject[] { + const objects = []; + for (const body of this.celestialBodies) objects.push(body); + for (const spacestation of this.spaceStations) objects.push(spacestation); + return objects; + } + public computeNearestOrbitalObject(position: Vector3): void { if (this.celestialBodies.length + this.spaceStations.length === 0) throw new Error("There are no bodies or spacestation in the solar system"); let nearest = null; @@ -251,9 +258,6 @@ export class StarSystem { if (!(object instanceof AbstractBody)) throw new Error("Rings post process can only be added to bodies. Source:" + object.name); this.postProcessManager.addRings(object, this.stellarObjects); break; - case PostProcessType.OVERLAY: - this.postProcessManager.addOverlay(object); - break; case PostProcessType.ATMOSPHERE: if (!(object instanceof GasPlanet) && !(object instanceof TelluricPlanemo)) throw new Error("Atmosphere post process can only be added to gas or telluric planets. Source:" + object.name); diff --git a/src/ts/ui/objectOverlay.ts b/src/ts/ui/objectOverlay.ts index bb2da5ff1..22e876ac2 100644 --- a/src/ts/ui/objectOverlay.ts +++ b/src/ts/ui/objectOverlay.ts @@ -46,7 +46,7 @@ export class ObjectOverlay { update(cameraPosition: Vector3) { if (this.cursor.linkedMesh === null) return; const distance = this.cursor.linkedMesh.getAbsolutePosition().subtract(cameraPosition).length(); - const scale = 0.03 * Math.pow(this.object.getBoundingRadius() / 1e6, 0.2); + const scale = Math.max(0.02, 0.03 * Math.pow(this.object.getBoundingRadius() / 1e6, 0.2)); this.cursor.scaleX = scale; this.cursor.scaleY = scale; diff --git a/src/ts/ui/systemUI.ts b/src/ts/ui/systemUI.ts index 4d6fb6f50..9ccd46be8 100644 --- a/src/ts/ui/systemUI.ts +++ b/src/ts/ui/systemUI.ts @@ -12,6 +12,14 @@ export class SystemUI { this.gui = AdvancedDynamicTexture.CreateFullscreenUI("SystemUI", true, scene); } + public setEnabled(enabled: boolean) { + this.gui.rootContainer.alpha = enabled ? 1 : 0; + } + + public isEnabled() { + return this.gui.rootContainer.alpha > 0; + } + public createObjectOverlays(objects: AbstractObject[]) { for (const object of objects) { const overlay = new ObjectOverlay(object); diff --git a/src/ts/view/bodies/planemos/gasPlanet.ts b/src/ts/view/bodies/planemos/gasPlanet.ts index 07eae239f..6f9aef3e7 100644 --- a/src/ts/view/bodies/planemos/gasPlanet.ts +++ b/src/ts/view/bodies/planemos/gasPlanet.ts @@ -48,7 +48,7 @@ export class GasPlanet extends AbstractBody implements Planemo, PlanemoMaterial this.material = new GasPlanetMaterial(this.name, this.getTransform(), this.model, scene); this.mesh.material = this.material; - this.postProcesses.push(PostProcessType.OVERLAY, PostProcessType.ATMOSPHERE, PostProcessType.SHADOW); + this.postProcesses.push(PostProcessType.ATMOSPHERE, PostProcessType.SHADOW); if (this.model.ringsUniforms !== null) this.postProcesses.push(PostProcessType.RING); this.getTransform().rotate(Axis.X, this.model.physicalProperties.axialTilt); diff --git a/src/ts/view/bodies/planemos/mandelbulb.ts b/src/ts/view/bodies/planemos/mandelbulb.ts index ebe8a67a9..07aa5fb47 100644 --- a/src/ts/view/bodies/planemos/mandelbulb.ts +++ b/src/ts/view/bodies/planemos/mandelbulb.ts @@ -21,7 +21,7 @@ export class Mandelbulb extends AbstractBody implements Planemo { this.model = model instanceof MandelbulbModel ? model : new MandelbulbModel(model, parentBody?.model); - this.postProcesses.push(PostProcessType.OVERLAY, PostProcessType.MANDELBULB); + this.postProcesses.push(PostProcessType.MANDELBULB); this.getTransform().rotate(Axis.X, this.model.physicalProperties.axialTilt); } diff --git a/src/ts/view/bodies/planemos/telluricPlanemo.ts b/src/ts/view/bodies/planemos/telluricPlanemo.ts index ac9d68101..97d78b7b6 100644 --- a/src/ts/view/bodies/planemos/telluricPlanemo.ts +++ b/src/ts/view/bodies/planemos/telluricPlanemo.ts @@ -39,7 +39,7 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat this.getTransform().rotate(Axis.X, this.model.physicalProperties.axialTilt); - this.postProcesses.push(PostProcessType.OVERLAY, PostProcessType.SHADOW); + this.postProcesses.push(PostProcessType.SHADOW); const waterBoilingPoint = waterBoilingPointCelsius(this.model.physicalProperties.pressure); const waterFreezingPoint = 0.0; diff --git a/src/ts/view/bodies/stellarObjects/blackHole.ts b/src/ts/view/bodies/stellarObjects/blackHole.ts index f4676f0bb..e38c8c7c9 100644 --- a/src/ts/view/bodies/stellarObjects/blackHole.ts +++ b/src/ts/view/bodies/stellarObjects/blackHole.ts @@ -26,7 +26,7 @@ export class BlackHole extends AbstractBody { this.light.parent = this.getTransform(); if (this.model.physicalProperties.accretionDiskRadius === 0) this.light.intensity = 0; - this.postProcesses.push(PostProcessType.OVERLAY, PostProcessType.BLACK_HOLE); + this.postProcesses.push(PostProcessType.BLACK_HOLE); } public override computeCulling(camera: Camera): void { diff --git a/src/ts/view/bodies/stellarObjects/star.ts b/src/ts/view/bodies/stellarObjects/star.ts index 0a57f51e0..e3d81f2b1 100644 --- a/src/ts/view/bodies/stellarObjects/star.ts +++ b/src/ts/view/bodies/stellarObjects/star.ts @@ -62,7 +62,7 @@ export class Star extends AbstractBody { // TODO: remove when rotation is transmitted to children setRotationQuaternion(this.getTransform(), Quaternion.Identity()); - this.postProcesses.push(PostProcessType.OVERLAY, PostProcessType.VOLUMETRIC_LIGHT, PostProcessType.LENS_FLARE); + this.postProcesses.push(PostProcessType.VOLUMETRIC_LIGHT, PostProcessType.LENS_FLARE); if (this.model.ringsUniforms !== null) this.postProcesses.push(PostProcessType.RING); } diff --git a/src/ts/view/postProcesses/overlayPostProcess.ts b/src/ts/view/postProcesses/overlayPostProcess.ts deleted file mode 100644 index 9cec5a844..000000000 --- a/src/ts/view/postProcesses/overlayPostProcess.ts +++ /dev/null @@ -1,43 +0,0 @@ -import overlayFragment from "../../../shaders/overlayFragment.glsl"; -import { UberScene } from "../../controller/uberCore/uberScene"; -import { getActiveCameraUniforms, getObjectUniforms, getSamplers } from "./uniforms"; -import { UberPostProcess } from "../../controller/uberCore/postProcesses/uberPostProcess"; -import { ObjectPostProcess } from "./objectPostProcess"; -import { Effect } from "@babylonjs/core/Materials/effect"; -import { BaseObject } from "../common"; -import { UniformEnumType, ShaderUniforms } from "../../controller/uberCore/postProcesses/types"; - -const shaderName = "overlay"; -Effect.ShadersStore[`${shaderName}FragmentShader`] = overlayFragment; - -export class OverlayPostProcess extends UberPostProcess implements ObjectPostProcess { - static ARE_ENABLED = true; - readonly object: BaseObject; - - constructor(object: BaseObject, scene: UberScene) { - const uniforms: ShaderUniforms = [ - ...getActiveCameraUniforms(scene), - ...getObjectUniforms(object), - { - name: "aspectRatio", - type: UniformEnumType.Float, - get: () => { - return scene.getEngine().getScreenAspectRatio(); - } - }, - { - name: "isEnabled", - type: UniformEnumType.Bool, - get: () => { - return OverlayPostProcess.ARE_ENABLED; - } - } - ]; - - const samplers = getSamplers(scene); - - super(object.name + "Overlay", shaderName, uniforms, samplers, scene); - - this.object = object; - } -} diff --git a/src/ts/view/postProcesses/postProcessTypes.ts b/src/ts/view/postProcesses/postProcessTypes.ts index 447536916..f95782e5b 100644 --- a/src/ts/view/postProcesses/postProcessTypes.ts +++ b/src/ts/view/postProcesses/postProcessTypes.ts @@ -8,6 +8,5 @@ export enum PostProcessType { MANDELBULB, BLACK_HOLE, SHADOW, - OVERLAY, LENS_FLARE } diff --git a/src/ts/view/spaceStation.ts b/src/ts/view/spaceStation.ts index 882826771..915fad52b 100644 --- a/src/ts/view/spaceStation.ts +++ b/src/ts/view/spaceStation.ts @@ -35,8 +35,6 @@ export class SpaceStation extends AbstractObject { this.getTransform().rotate(Axis.X, this.model.physicalProperties.axialTilt); this.getTransform().rotate(Axis.Y, this.model.physicalProperties.axialTilt); - - this.postProcesses.push(PostProcessType.OVERLAY); } public override getBoundingRadius(): number { From 182418a35a6dcb6d0f9e69341d005c8cfb1d96d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 20:02:57 +0100 Subject: [PATCH 80/86] Fixed ui wrong display Check orientation to camera to cull some ui + display distance --- src/ts/controller/StarSystemView.ts | 2 +- src/ts/ui/objectOverlay.ts | 44 ++++++++++++++++++++++++----- src/ts/ui/systemUI.ts | 10 +++---- src/ts/utils/parseToStrings.ts | 12 ++++++++ 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/ts/controller/StarSystemView.ts b/src/ts/controller/StarSystemView.ts index 2f3d8278d..e54990a28 100644 --- a/src/ts/controller/StarSystemView.ts +++ b/src/ts/controller/StarSystemView.ts @@ -82,7 +82,7 @@ export class StarSystemView { Assets.ChunkForge.update(); starSystem.update(deltaTime * Settings.TIME_MULTIPLIER); - this.ui.update(this.scene.getActiveUberCamera().getAbsolutePosition()); + this.ui.update(this.scene.getActiveUberCamera()); const nearestBody = starSystem.getNearestOrbitalObject(); diff --git a/src/ts/ui/objectOverlay.ts b/src/ts/ui/objectOverlay.ts index 22e876ac2..62cf3caef 100644 --- a/src/ts/ui/objectOverlay.ts +++ b/src/ts/ui/objectOverlay.ts @@ -3,12 +3,16 @@ import { AbstractObject } from "../view/bodies/abstractObject"; import { StackPanel } from "@babylonjs/gui/2D/controls/stackPanel"; import { Image } from "@babylonjs/gui/2D/controls/image"; import cursorImage from "../../asset/textures/hoveredCircle.png"; +import { parseDistance } from "../utils/parseToStrings"; +import { Camera } from "@babylonjs/core/Cameras/camera"; +import { Axis } from "@babylonjs/core/Maths/math.axis"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; export class ObjectOverlay { readonly textRoot: StackPanel; readonly cursor: Image; readonly namePlate: TextBlock; + readonly distanceText: TextBlock; readonly object: AbstractObject; constructor(object: AbstractObject) { @@ -27,9 +31,20 @@ export class ObjectOverlay { this.namePlate.color = "white"; this.namePlate.zIndex = 6; this.namePlate.height = "50px"; + this.namePlate.fontSize = 20; this.namePlate.textHorizontalAlignment = TextBlock.HORIZONTAL_ALIGNMENT_LEFT; + this.namePlate.textVerticalAlignment = TextBlock.VERTICAL_ALIGNMENT_CENTER; this.textRoot.addControl(this.namePlate); + this.distanceText = new TextBlock(object.name + "OverlayDistanceText"); + this.distanceText.color = "white"; + this.distanceText.zIndex = 6; + this.distanceText.height = "20px"; + this.distanceText.fontSize = 16; + this.distanceText.textHorizontalAlignment = TextBlock.HORIZONTAL_ALIGNMENT_LEFT; + this.distanceText.textVerticalAlignment = TextBlock.VERTICAL_ALIGNMENT_CENTER; + this.textRoot.addControl(this.distanceText); + this.cursor = new Image(object.name + "Cursor", cursorImage); this.cursor.fixedRatio = 1; this.cursor.width = 1; @@ -38,20 +53,35 @@ export class ObjectOverlay { } init() { - console.log(this.object.getTransform()); this.textRoot.linkWithMesh(this.object.getTransform()); this.cursor.linkWithMesh(this.object.getTransform()); } - update(cameraPosition: Vector3) { - if (this.cursor.linkedMesh === null) return; - const distance = this.cursor.linkedMesh.getAbsolutePosition().subtract(cameraPosition).length(); + update(camera: Camera) { + const viewRay = camera.getDirection(new Vector3(0, 0, -1)); + const objectRay = this.object.getTransform().getAbsolutePosition().subtract(camera.globalPosition); + const distance = objectRay.length(); + objectRay.scaleInPlace(1 / distance); + + if(Vector3.Dot(viewRay, objectRay) < 0) { + this.cursor.isVisible = false; + this.textRoot.isVisible = false; + return; + } + + this.cursor.isVisible = true; + this.textRoot.isVisible = true; + const scale = Math.max(0.02, 0.03 * Math.pow(this.object.getBoundingRadius() / 1e6, 0.2)); this.cursor.scaleX = scale; this.cursor.scaleY = scale; - const alpha = 1e-3 * distance / this.object.getBoundingRadius(); - this.textRoot.alpha = alpha; - this.cursor.alpha = Math.min(alpha, 0.5); + const alphaCursor = 1e-3 * distance / this.object.getBoundingRadius(); + this.cursor.alpha = Math.min(alphaCursor, 0.5); + + const alphaText = distance < 10 * this.object.getBoundingRadius() ? 0 : 0.95; + this.textRoot.alpha = alphaText; + + this.distanceText.text = parseDistance(distance); } } diff --git a/src/ts/ui/systemUI.ts b/src/ts/ui/systemUI.ts index 9ccd46be8..0bda161a4 100644 --- a/src/ts/ui/systemUI.ts +++ b/src/ts/ui/systemUI.ts @@ -2,7 +2,7 @@ import { Scene } from "@babylonjs/core/scene"; import { AdvancedDynamicTexture } from "@babylonjs/gui/2D/advancedDynamicTexture"; import { AbstractObject } from "../view/bodies/abstractObject"; import { ObjectOverlay } from "./objectOverlay"; -import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { Camera } from "@babylonjs/core/Cameras/camera"; export class SystemUI { private readonly gui: AdvancedDynamicTexture; @@ -13,11 +13,11 @@ export class SystemUI { } public setEnabled(enabled: boolean) { - this.gui.rootContainer.alpha = enabled ? 1 : 0; + this.gui.rootContainer.isEnabled = enabled; } public isEnabled() { - return this.gui.rootContainer.alpha > 0; + return this.gui.rootContainer.isEnabled; } public createObjectOverlays(objects: AbstractObject[]) { @@ -33,9 +33,9 @@ export class SystemUI { } } - public update(cameraPosition: Vector3) { + public update(camera: Camera) { for (const overlay of this.objectOverlays) { - overlay.update(cameraPosition); + overlay.update(camera); } } } diff --git a/src/ts/utils/parseToStrings.ts b/src/ts/utils/parseToStrings.ts index 74422af60..5e4bc9788 100644 --- a/src/ts/utils/parseToStrings.ts +++ b/src/ts/utils/parseToStrings.ts @@ -12,6 +12,18 @@ export function parseSpeed(speed: number): string { } } +export function parseDistance(distance: number): string { + if (distance < 1000) { + return `${distance.toFixed(0)} m`; + } else if (distance < 1000000) { + return `${(distance / 1000).toFixed(2)} km`; + } else if (distance < 20000000) { + return `${(distance / 1000000).toFixed(2)} Mm`; + } else { + return `${(distance / Settings.C).toFixed(2)} ls`; + } +} + /** * Parse a number between 0 and 1 to a percentage string. * Example: 0.5 -> "50%" From 1dff9afecadd9faf0d4af136970f8f36185c9870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 20:21:56 +0100 Subject: [PATCH 81/86] added utility quaternion computation to get the transformation needed to go from one vector to another --- src/ts/controller/starSystem.ts | 8 +++----- src/ts/utils/algebra.ts | 6 ++++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index f06a1dce5..017826e9d 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -17,6 +17,7 @@ import { rotateAround, setUpVector, translate } from "./uberCore/transforms/basi import { Mandelbulb } from "../view/bodies/planemos/mandelbulb"; import { Quaternion } from "@babylonjs/core/Maths/math"; import { PostProcessType } from "../view/postProcesses/postProcessTypes"; +import { getTransformationQuaternion } from "../utils/algebra"; export class StarSystem { readonly scene: UberScene; @@ -204,7 +205,7 @@ export class StarSystem { } /** - * Returns the nearest body to the the given position + * Returns the nearest body to the given position */ public getNearestCelestialBody(position: Vector3): AbstractBody { if (this.celestialBodies.length === 0) throw new Error("There are no bodies or spacestation in the solar system"); @@ -230,10 +231,7 @@ export class StarSystem { for (const object of this.orbitalObjects) { const displacement = new Vector3(object.model.orbit.radius, 0, 0); - const targetNormal = object.model.orbit.normalToPlane; - const rotationAxis = Vector3.Cross(Vector3.Up(), targetNormal); - const angle = Math.acos(Vector3.Dot(Vector3.Up(), targetNormal)); - const quaternion = Quaternion.RotationAxis(rotationAxis, angle); + const quaternion = getTransformationQuaternion(Vector3.Up(), object.model.orbit.normalToPlane); displacement.applyRotationQuaternionInPlace(quaternion); if (object.parentObject !== null) { translate(object.getTransform(), object.parentObject.getTransform().getAbsolutePosition()); diff --git a/src/ts/utils/algebra.ts b/src/ts/utils/algebra.ts index e8af2593e..db4f6d88d 100644 --- a/src/ts/utils/algebra.ts +++ b/src/ts/utils/algebra.ts @@ -22,6 +22,12 @@ export function getAxisComponentFromQuaternion(quaternion: Quaternion, axisToGet return twist.normalize().conjugate(); } +export function getTransformationQuaternion(from: Vector3, to: Vector3): Quaternion { + const rotationAxis = Vector3.Cross(from, to); + const angle = Math.acos(Vector3.Dot(from, to)); + return Quaternion.RotationAxis(rotationAxis, angle); +} + export function flattenVector3Array(vector3Array: Vector3[]): number[] { const result: number[] = []; for (const vector3 of vector3Array) { From 1ed4dd8ab9ae35283db3324b99df1aa72223026d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 20:22:23 +0100 Subject: [PATCH 82/86] dispose old ui when changing system --- src/ts/controller/uberCore/uberCamera.ts | 9 +++++---- src/ts/ui/objectOverlay.ts | 12 ++++++++---- src/ts/ui/systemUI.ts | 13 +++++++++++-- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/ts/controller/uberCore/uberCamera.ts b/src/ts/controller/uberCore/uberCamera.ts index 12d600282..b4352dd4c 100644 --- a/src/ts/controller/uberCore/uberCamera.ts +++ b/src/ts/controller/uberCore/uberCamera.ts @@ -11,13 +11,10 @@ export class UberCamera extends FreeCamera { this.inverseProjectionMatrix = Matrix.Invert(this.getProjectionMatrix()); this.inverseViewMatrix = Matrix.Invert(this.getViewMatrix()); - - this.onProjectionMatrixChangedObservable.add(() => { - this.inverseProjectionMatrix = Matrix.Invert(this.getProjectionMatrix()); - }); } getInverseProjectionMatrix(): Matrix { + this.inverseProjectionMatrix = Matrix.Invert(this.getProjectionMatrix()); return this.inverseProjectionMatrix; } @@ -26,6 +23,10 @@ export class UberCamera extends FreeCamera { return this.inverseViewMatrix; } + forward(): Vector3 { + return this.getDirection(new Vector3(0, 0, -1)); + } + getAbsolutePosition(): Vector3 { this.computeWorldMatrix(); return this.globalPosition; diff --git a/src/ts/ui/objectOverlay.ts b/src/ts/ui/objectOverlay.ts index 62cf3caef..66bddb06a 100644 --- a/src/ts/ui/objectOverlay.ts +++ b/src/ts/ui/objectOverlay.ts @@ -4,9 +4,8 @@ import { StackPanel } from "@babylonjs/gui/2D/controls/stackPanel"; import { Image } from "@babylonjs/gui/2D/controls/image"; import cursorImage from "../../asset/textures/hoveredCircle.png"; import { parseDistance } from "../utils/parseToStrings"; -import { Camera } from "@babylonjs/core/Cameras/camera"; -import { Axis } from "@babylonjs/core/Maths/math.axis"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { UberCamera } from "../controller/uberCore/uberCamera"; export class ObjectOverlay { readonly textRoot: StackPanel; @@ -57,8 +56,8 @@ export class ObjectOverlay { this.cursor.linkWithMesh(this.object.getTransform()); } - update(camera: Camera) { - const viewRay = camera.getDirection(new Vector3(0, 0, -1)); + update(camera: UberCamera) { + const viewRay = camera.forward(); const objectRay = this.object.getTransform().getAbsolutePosition().subtract(camera.globalPosition); const distance = objectRay.length(); objectRay.scaleInPlace(1 / distance); @@ -84,4 +83,9 @@ export class ObjectOverlay { this.distanceText.text = parseDistance(distance); } + + dispose() { + this.textRoot.dispose(); + this.cursor.dispose(); + } } diff --git a/src/ts/ui/systemUI.ts b/src/ts/ui/systemUI.ts index 0bda161a4..689f2c77e 100644 --- a/src/ts/ui/systemUI.ts +++ b/src/ts/ui/systemUI.ts @@ -2,7 +2,7 @@ import { Scene } from "@babylonjs/core/scene"; import { AdvancedDynamicTexture } from "@babylonjs/gui/2D/advancedDynamicTexture"; import { AbstractObject } from "../view/bodies/abstractObject"; import { ObjectOverlay } from "./objectOverlay"; -import { Camera } from "@babylonjs/core/Cameras/camera"; +import { UberCamera } from "../controller/uberCore/uberCamera"; export class SystemUI { private readonly gui: AdvancedDynamicTexture; @@ -21,6 +21,8 @@ export class SystemUI { } public createObjectOverlays(objects: AbstractObject[]) { + this.removeObjectOverlays(); + for (const object of objects) { const overlay = new ObjectOverlay(object); this.gui.addControl(overlay.textRoot); @@ -33,7 +35,14 @@ export class SystemUI { } } - public update(camera: Camera) { + public removeObjectOverlays() { + for (const overlay of this.objectOverlays) { + overlay.dispose(); + } + this.objectOverlays = []; + } + + public update(camera: UberCamera) { for (const overlay of this.objectOverlays) { overlay.update(camera); } From c488d7a74766a4d29285cba672c0fcfe053245fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 20:40:20 +0100 Subject: [PATCH 83/86] added targeting with T key The ui will only be displayed for the targeted object --- src/ts/controller/StarSystemView.ts | 6 +++++- src/ts/controller/starSystem.ts | 33 ++++++++++++++++++++++++++++- src/ts/ui/objectOverlay.ts | 4 ++-- src/ts/ui/systemUI.ts | 8 ++++++- 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/ts/controller/StarSystemView.ts b/src/ts/controller/StarSystemView.ts index e54990a28..148e9d3be 100644 --- a/src/ts/controller/StarSystemView.ts +++ b/src/ts/controller/StarSystemView.ts @@ -62,7 +62,11 @@ export class StarSystemView { this.axisRenderer.setVisibility(!this.axisRenderer.isVisible()); } if (e.key === "u") this.bodyEditor.setVisibility(this.bodyEditor.getVisibility() === EditorVisibility.HIDDEN ? EditorVisibility.NAVBAR : EditorVisibility.HIDDEN); - if (e.key === "t") this.helmetOverlay.setVisibility(!this.helmetOverlay.isVisible()); + if (e.key === "b") this.helmetOverlay.setVisibility(!this.helmetOverlay.isVisible()); + + if(e.key === "t") { + this.ui.setTarget(this.getStarSystem().getClosestToScreenCenterOrbitalObject()); + } }); this.scene = new UberScene(engine, ScenePerformancePriority.Intermediate); diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index 017826e9d..6dedb7c3d 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -15,7 +15,7 @@ import { SpaceStation } from "../view/spaceStation"; import { AbstractObject } from "../view/bodies/abstractObject"; import { rotateAround, setUpVector, translate } from "./uberCore/transforms/basicTransform"; import { Mandelbulb } from "../view/bodies/planemos/mandelbulb"; -import { Quaternion } from "@babylonjs/core/Maths/math"; +import { Matrix, Quaternion } from "@babylonjs/core/Maths/math"; import { PostProcessType } from "../view/postProcesses/postProcessTypes"; import { getTransformationQuaternion } from "../utils/algebra"; @@ -69,6 +69,8 @@ export class StarSystem { private nearestOrbitalObject: AbstractObject | null = null; + private closestToScreenCenterOrbitalObject: AbstractObject | null = null; + constructor(model: StarSystemModel | number, scene: UberScene) { this.scene = scene; this.postProcessManager = new PostProcessManager(this.scene); @@ -195,6 +197,34 @@ export class StarSystem { this.nearestOrbitalObject = nearest; } + public computeClosestToScreenCenterOrbitalObject() { + let nearest = null; + let closestDistance = Number.POSITIVE_INFINITY; + for (const object of this.orbitalObjects) { + const screenCoordinates = Vector3.Project( + object.getTransform().getAbsolutePosition(), + Matrix.IdentityReadOnly, + this.scene.getTransformMatrix(), + this.scene.getActiveUberCamera().viewport + ); + + if (screenCoordinates.z < 0) continue; + + const distance = screenCoordinates.subtract(new Vector3(0.5, 0.5, 0)).length(); + + if (distance < closestDistance) { + closestDistance = distance; + nearest = object; + } + } + + this.closestToScreenCenterOrbitalObject = nearest; + } + + public getClosestToScreenCenterOrbitalObject(): AbstractObject | null { + return this.closestToScreenCenterOrbitalObject; + } + /** * Returns the nearest orbital object to the origin */ @@ -304,6 +334,7 @@ export class StarSystem { public update(deltaTime: number): void { const controller = this.scene.getActiveController(); this.computeNearestOrbitalObject(controller.getActiveCamera().getAbsolutePosition()); + this.computeClosestToScreenCenterOrbitalObject(); const nearestBody = this.getNearestOrbitalObject(); const distanceOfNearestToCamera = Vector3.Distance(nearestBody.getTransform().getAbsolutePosition(), controller.getActiveCamera().getAbsolutePosition()); diff --git a/src/ts/ui/objectOverlay.ts b/src/ts/ui/objectOverlay.ts index 66bddb06a..46f71381c 100644 --- a/src/ts/ui/objectOverlay.ts +++ b/src/ts/ui/objectOverlay.ts @@ -56,7 +56,7 @@ export class ObjectOverlay { this.cursor.linkWithMesh(this.object.getTransform()); } - update(camera: UberCamera) { + update(camera: UberCamera, target: AbstractObject | null) { const viewRay = camera.forward(); const objectRay = this.object.getTransform().getAbsolutePosition().subtract(camera.globalPosition); const distance = objectRay.length(); @@ -69,7 +69,7 @@ export class ObjectOverlay { } this.cursor.isVisible = true; - this.textRoot.isVisible = true; + this.textRoot.isVisible = this.object === target; const scale = Math.max(0.02, 0.03 * Math.pow(this.object.getBoundingRadius() / 1e6, 0.2)); this.cursor.scaleX = scale; diff --git a/src/ts/ui/systemUI.ts b/src/ts/ui/systemUI.ts index 689f2c77e..8f1ed43b7 100644 --- a/src/ts/ui/systemUI.ts +++ b/src/ts/ui/systemUI.ts @@ -8,6 +8,8 @@ export class SystemUI { private readonly gui: AdvancedDynamicTexture; private objectOverlays: ObjectOverlay[] = []; + private target: AbstractObject | null = null; + constructor(scene: Scene) { this.gui = AdvancedDynamicTexture.CreateFullscreenUI("SystemUI", true, scene); } @@ -44,7 +46,11 @@ export class SystemUI { public update(camera: UberCamera) { for (const overlay of this.objectOverlays) { - overlay.update(camera); + overlay.update(camera, this.target); } } + + setTarget(object: AbstractObject | null) { + this.target = object; + } } From adb901d437e642e88e3a78cc91531d8fdb609d49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 20:45:23 +0100 Subject: [PATCH 84/86] fixed bodyeditor resize bug it would resize during startup and that would distort starmap ui --- src/ts/controller/StarSystemView.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ts/controller/StarSystemView.ts b/src/ts/controller/StarSystemView.ts index 148e9d3be..d64f0351a 100644 --- a/src/ts/controller/StarSystemView.ts +++ b/src/ts/controller/StarSystemView.ts @@ -36,10 +36,10 @@ export class StarSystemView { constructor(engine: Engine, havokPlugin: HavokPlugin) { this.helmetOverlay = new HelmetOverlay(); - this.bodyEditor = new BodyEditor(); + this.bodyEditor = new BodyEditor(EditorVisibility.HIDDEN); const canvas = engine.getRenderingCanvas(); - if(canvas === null) throw new Error("Canvas is null"); + if (canvas === null) throw new Error("Canvas is null"); this.bodyEditor.setCanvas(canvas); StarSystemView.unZoomAnimation.setKeys([ @@ -64,7 +64,7 @@ export class StarSystemView { if (e.key === "u") this.bodyEditor.setVisibility(this.bodyEditor.getVisibility() === EditorVisibility.HIDDEN ? EditorVisibility.NAVBAR : EditorVisibility.HIDDEN); if (e.key === "b") this.helmetOverlay.setVisibility(!this.helmetOverlay.isVisible()); - if(e.key === "t") { + if (e.key === "t") { this.ui.setTarget(this.getStarSystem().getClosestToScreenCenterOrbitalObject()); } }); @@ -103,8 +103,6 @@ export class StarSystemView { }); this.bodyEditor.resize(); - - this.bodyEditor.setVisibility(EditorVisibility.HIDDEN); this.helmetOverlay.setVisibility(false); this.ui = new SystemUI(this.scene); From e769b36587e86e44e20997031ac6bbc2dd0a5323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 21:01:22 +0100 Subject: [PATCH 85/86] better positioning of object ui --- src/ts/ui/objectOverlay.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ts/ui/objectOverlay.ts b/src/ts/ui/objectOverlay.ts index 46f71381c..21e7cddf6 100644 --- a/src/ts/ui/objectOverlay.ts +++ b/src/ts/ui/objectOverlay.ts @@ -6,6 +6,7 @@ import cursorImage from "../../asset/textures/hoveredCircle.png"; import { parseDistance } from "../utils/parseToStrings"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { UberCamera } from "../controller/uberCore/uberCamera"; +import { getAngularSize } from "../utils/isObjectVisibleOnScreen"; export class ObjectOverlay { readonly textRoot: StackPanel; @@ -21,7 +22,6 @@ export class ObjectOverlay { this.textRoot.width = "150px"; this.textRoot.height = "70px"; this.textRoot.background = "darkred"; - this.textRoot.linkOffsetX = 130; this.textRoot.zIndex = 6; this.textRoot.alpha = 0.95; @@ -71,16 +71,21 @@ export class ObjectOverlay { this.cursor.isVisible = true; this.textRoot.isVisible = this.object === target; + const angularSize = getAngularSize(this.object.getTransform().getAbsolutePosition(), this.object.getBoundingRadius(), camera.getAbsolutePosition()); + const screenRatio = angularSize / camera.fov; + const scale = Math.max(0.02, 0.03 * Math.pow(this.object.getBoundingRadius() / 1e6, 0.2)); - this.cursor.scaleX = scale; - this.cursor.scaleY = scale; + this.cursor.scaleX = Math.max(scale, screenRatio); + this.cursor.scaleY = Math.max(scale, screenRatio); - const alphaCursor = 1e-3 * distance / this.object.getBoundingRadius(); + const alphaCursor = Math.max(0, (1e-3 * (distance - this.object.getBoundingRadius() * 3)) / this.object.getBoundingRadius()); this.cursor.alpha = Math.min(alphaCursor, 0.5); const alphaText = distance < 10 * this.object.getBoundingRadius() ? 0 : 0.95; this.textRoot.alpha = alphaText; + this.textRoot.linkOffsetXInPixels = 0.5 * Math.max(scale, screenRatio) * window.innerWidth + 75 + 20; + this.distanceText.text = parseDistance(distance); } From c26293a6b6dcb21ac3b72f42b5b494a8ba37b7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Sun, 5 Nov 2023 22:40:22 +0100 Subject: [PATCH 86/86] Added typename to ui + better fading when getting close --- src/ts/controller/starSystem.ts | 2 +- src/ts/ui/objectOverlay.ts | 19 +++++++++++++++---- src/ts/ui/systemUI.ts | 8 ++++++-- src/ts/view/bodies/abstractObject.ts | 2 ++ src/ts/view/bodies/planemos/gasPlanet.ts | 4 ++++ src/ts/view/bodies/planemos/mandelbulb.ts | 4 ++++ .../view/bodies/planemos/telluricPlanemo.ts | 4 ++++ .../view/bodies/stellarObjects/blackHole.ts | 4 ++++ .../view/bodies/stellarObjects/neutronStar.ts | 4 ++++ src/ts/view/bodies/stellarObjects/star.ts | 5 +++++ src/ts/view/spaceStation.ts | 6 +++++- 11 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/ts/controller/starSystem.ts b/src/ts/controller/starSystem.ts index 6dedb7c3d..59084e5ef 100644 --- a/src/ts/controller/starSystem.ts +++ b/src/ts/controller/starSystem.ts @@ -338,7 +338,7 @@ export class StarSystem { const nearestBody = this.getNearestOrbitalObject(); const distanceOfNearestToCamera = Vector3.Distance(nearestBody.getTransform().getAbsolutePosition(), controller.getActiveCamera().getAbsolutePosition()); - const shouldCompensateTranslation = distanceOfNearestToCamera < nearestBody.getBoundingRadius() * 10; + const shouldCompensateTranslation = distanceOfNearestToCamera < nearestBody.getBoundingRadius() * (nearestBody instanceof SpaceStation ? 80 : 10); const shouldCompensateRotation = distanceOfNearestToCamera < nearestBody.getBoundingRadius() * 4; nearestBody.updateInternalClock(deltaTime); diff --git a/src/ts/ui/objectOverlay.ts b/src/ts/ui/objectOverlay.ts index 21e7cddf6..a5f0a69a4 100644 --- a/src/ts/ui/objectOverlay.ts +++ b/src/ts/ui/objectOverlay.ts @@ -12,6 +12,7 @@ export class ObjectOverlay { readonly textRoot: StackPanel; readonly cursor: Image; readonly namePlate: TextBlock; + readonly typeText: TextBlock; readonly distanceText: TextBlock; readonly object: AbstractObject; @@ -20,8 +21,8 @@ export class ObjectOverlay { this.textRoot = new StackPanel(object.name + "OverlayTextRoot"); this.textRoot.width = "150px"; - this.textRoot.height = "70px"; - this.textRoot.background = "darkred"; + this.textRoot.height = "90px"; + this.textRoot.background = "transparent"; this.textRoot.zIndex = 6; this.textRoot.alpha = 0.95; @@ -35,6 +36,16 @@ export class ObjectOverlay { this.namePlate.textVerticalAlignment = TextBlock.VERTICAL_ALIGNMENT_CENTER; this.textRoot.addControl(this.namePlate); + this.typeText = new TextBlock(object.name + "OverlayTypeText"); + this.typeText.text = object.getTypeName(); + this.typeText.color = "white"; + this.typeText.zIndex = 6; + this.typeText.height = "20px"; + this.typeText.fontSize = 16; + this.typeText.textHorizontalAlignment = TextBlock.HORIZONTAL_ALIGNMENT_LEFT; + this.typeText.textVerticalAlignment = TextBlock.VERTICAL_ALIGNMENT_CENTER; + this.textRoot.addControl(this.typeText); + this.distanceText = new TextBlock(object.name + "OverlayDistanceText"); this.distanceText.color = "white"; this.distanceText.zIndex = 6; @@ -78,10 +89,10 @@ export class ObjectOverlay { this.cursor.scaleX = Math.max(scale, screenRatio); this.cursor.scaleY = Math.max(scale, screenRatio); - const alphaCursor = Math.max(0, (1e-3 * (distance - this.object.getBoundingRadius() * 3)) / this.object.getBoundingRadius()); + const alphaCursor = 100 * Math.max(scale - screenRatio, 0.0); this.cursor.alpha = Math.min(alphaCursor, 0.5); - const alphaText = distance < 10 * this.object.getBoundingRadius() ? 0 : 0.95; + const alphaText = Math.max(0, (distance / (3 * this.object.getBoundingRadius())) - 1.0); this.textRoot.alpha = alphaText; this.textRoot.linkOffsetXInPixels = 0.5 * Math.max(scale, screenRatio) * window.innerWidth + 75 + 20; diff --git a/src/ts/ui/systemUI.ts b/src/ts/ui/systemUI.ts index 8f1ed43b7..010292b0e 100644 --- a/src/ts/ui/systemUI.ts +++ b/src/ts/ui/systemUI.ts @@ -15,11 +15,11 @@ export class SystemUI { } public setEnabled(enabled: boolean) { - this.gui.rootContainer.isEnabled = enabled; + this.gui.rootContainer.alpha = enabled ? 1 : 0; } public isEnabled() { - return this.gui.rootContainer.isEnabled; + return this.gui.rootContainer.alpha === 1; } public createObjectOverlays(objects: AbstractObject[]) { @@ -51,6 +51,10 @@ export class SystemUI { } setTarget(object: AbstractObject | null) { + if (this.target === object) { + this.target = null; + return; + } this.target = object; } } diff --git a/src/ts/view/bodies/abstractObject.ts b/src/ts/view/bodies/abstractObject.ts index deedd69ad..9b038f9a6 100644 --- a/src/ts/view/bodies/abstractObject.ts +++ b/src/ts/view/bodies/abstractObject.ts @@ -58,6 +58,8 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla public abstract getBoundingRadius(): number; + public abstract getTypeName(): string; + /** * Returns the axis of rotation of the body */ diff --git a/src/ts/view/bodies/planemos/gasPlanet.ts b/src/ts/view/bodies/planemos/gasPlanet.ts index 6f9aef3e7..84184282b 100644 --- a/src/ts/view/bodies/planemos/gasPlanet.ts +++ b/src/ts/view/bodies/planemos/gasPlanet.ts @@ -58,6 +58,10 @@ export class GasPlanet extends AbstractBody implements Planemo, PlanemoMaterial this.material.update(controller, stellarObjects, deltaTime); } + getTypeName(): string { + return "Gas Planet"; + } + public override computeCulling(camera: Camera): void { this.mesh.isVisible = isSizeOnScreenEnough(this, camera); } diff --git a/src/ts/view/bodies/planemos/mandelbulb.ts b/src/ts/view/bodies/planemos/mandelbulb.ts index 07aa5fb47..88ce271a6 100644 --- a/src/ts/view/bodies/planemos/mandelbulb.ts +++ b/src/ts/view/bodies/planemos/mandelbulb.ts @@ -26,6 +26,10 @@ export class Mandelbulb extends AbstractBody implements Planemo { this.getTransform().rotate(Axis.X, this.model.physicalProperties.axialTilt); } + getTypeName(): string { + return "Anomaly"; + } + public override computeCulling(camera: Camera): void { // do nothing } diff --git a/src/ts/view/bodies/planemos/telluricPlanemo.ts b/src/ts/view/bodies/planemos/telluricPlanemo.ts index 97d78b7b6..b1d882ba5 100644 --- a/src/ts/view/bodies/planemos/telluricPlanemo.ts +++ b/src/ts/view/bodies/planemos/telluricPlanemo.ts @@ -81,6 +81,10 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat } } + getTypeName(): string { + return "Telluric Planemo"; + } + /** * Update terrain of the sphere relative to the observer position * @param observerPosition diff --git a/src/ts/view/bodies/stellarObjects/blackHole.ts b/src/ts/view/bodies/stellarObjects/blackHole.ts index e38c8c7c9..e9b749d95 100644 --- a/src/ts/view/bodies/stellarObjects/blackHole.ts +++ b/src/ts/view/bodies/stellarObjects/blackHole.ts @@ -29,6 +29,10 @@ export class BlackHole extends AbstractBody { this.postProcesses.push(PostProcessType.BLACK_HOLE); } + getTypeName(): string { + return "Black Hole"; + } + public override computeCulling(camera: Camera): void { // nothing to do } diff --git a/src/ts/view/bodies/stellarObjects/neutronStar.ts b/src/ts/view/bodies/stellarObjects/neutronStar.ts index 9220557d4..39375292f 100644 --- a/src/ts/view/bodies/stellarObjects/neutronStar.ts +++ b/src/ts/view/bodies/stellarObjects/neutronStar.ts @@ -22,4 +22,8 @@ export class NeutronStar extends Star { this.postProcesses.push(PostProcessType.MATTER_JETS); } + + getTypeName(): string { + return "Neutron Star"; + } } diff --git a/src/ts/view/bodies/stellarObjects/star.ts b/src/ts/view/bodies/stellarObjects/star.ts index e3d81f2b1..492731b98 100644 --- a/src/ts/view/bodies/stellarObjects/star.ts +++ b/src/ts/view/bodies/stellarObjects/star.ts @@ -15,6 +15,7 @@ import { setRotationQuaternion } from "../../../controller/uberCore/transforms/b import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; import { PhysicsShapeSphere, PhysicsShapeType } from "@babylonjs/core"; import { Camera } from "@babylonjs/core/Cameras/camera"; +import { getStellarTypeString } from "../../../model/stellarObjects/common"; export class Star extends AbstractBody { readonly mesh: Mesh; @@ -66,6 +67,10 @@ export class Star extends AbstractBody { if (this.model.ringsUniforms !== null) this.postProcesses.push(PostProcessType.RING); } + getTypeName(): string { + return `${getStellarTypeString(this.model.stellarType)} star`; + } + public updateMaterial(): void { this.material.update(this.getInternalClock()); } diff --git a/src/ts/view/spaceStation.ts b/src/ts/view/spaceStation.ts index 915fad52b..cfbc6a3b2 100644 --- a/src/ts/view/spaceStation.ts +++ b/src/ts/view/spaceStation.ts @@ -38,7 +38,11 @@ export class SpaceStation extends AbstractObject { } public override getBoundingRadius(): number { - return 2e3; + return 1e3; + } + + getTypeName(): string { + return "Space Station"; } public override computeCulling(camera: Camera): void {