From a1f3102e7a1b3cbde71be2ce9bb7893e6d38e747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 15 Jan 2024 09:53:02 +0100 Subject: [PATCH 01/11] starfield performs depth test rather than color test --- src/shaders/starfieldFragment.glsl | 2 +- src/ts/uberCore/uberScene.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/shaders/starfieldFragment.glsl b/src/shaders/starfieldFragment.glsl index 2b35f8cdd..3ba1c9ba1 100644 --- a/src/shaders/starfieldFragment.glsl +++ b/src/shaders/starfieldFragment.glsl @@ -32,7 +32,7 @@ void main() { vec2 starfieldUV = vec2(0.0); - if (screenColor == vec4(0.0)) { + if (depth == 1.0) { // get the starfield color // get spherical coordinates uv for the starfield texture starfieldUV = vec2( diff --git a/src/ts/uberCore/uberScene.ts b/src/ts/uberCore/uberScene.ts index 840e19873..0becd28d3 100644 --- a/src/ts/uberCore/uberScene.ts +++ b/src/ts/uberCore/uberScene.ts @@ -4,7 +4,6 @@ import { DepthRenderer } from "@babylonjs/core/Rendering/depthRenderer"; import { Engine } from "@babylonjs/core/Engines/engine"; import "@babylonjs/core/Rendering/depthRendererSceneComponent"; import { Camera } from "@babylonjs/core/Cameras/camera"; -import { Color4 } from "@babylonjs/core/Maths/math.color"; export class UberScene extends Scene { private activeController: Controls | null = null; @@ -13,7 +12,6 @@ export class UberScene extends Scene { constructor(engine: Engine, performancePriority = ScenePerformancePriority.BackwardCompatible) { super(engine); this.performancePriority = performancePriority; - this.clearColor = new Color4(0, 0, 0, 0); } public getDepthRenderer(): DepthRenderer { From 76c58e3a9488f1361aaea0ef0b8e6f283b2594c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 15 Jan 2024 10:06:00 +0100 Subject: [PATCH 02/11] Revert "starfield performs depth test rather than color test" This reverts commit a1f3102e7a1b3cbde71be2ce9bb7893e6d38e747. --- src/shaders/starfieldFragment.glsl | 2 +- src/ts/uberCore/uberScene.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shaders/starfieldFragment.glsl b/src/shaders/starfieldFragment.glsl index 3ba1c9ba1..2b35f8cdd 100644 --- a/src/shaders/starfieldFragment.glsl +++ b/src/shaders/starfieldFragment.glsl @@ -32,7 +32,7 @@ void main() { vec2 starfieldUV = vec2(0.0); - if (depth == 1.0) { + if (screenColor == vec4(0.0)) { // get the starfield color // get spherical coordinates uv for the starfield texture starfieldUV = vec2( diff --git a/src/ts/uberCore/uberScene.ts b/src/ts/uberCore/uberScene.ts index 0becd28d3..840e19873 100644 --- a/src/ts/uberCore/uberScene.ts +++ b/src/ts/uberCore/uberScene.ts @@ -4,6 +4,7 @@ import { DepthRenderer } from "@babylonjs/core/Rendering/depthRenderer"; import { Engine } from "@babylonjs/core/Engines/engine"; import "@babylonjs/core/Rendering/depthRendererSceneComponent"; import { Camera } from "@babylonjs/core/Cameras/camera"; +import { Color4 } from "@babylonjs/core/Maths/math.color"; export class UberScene extends Scene { private activeController: Controls | null = null; @@ -12,6 +13,7 @@ export class UberScene extends Scene { constructor(engine: Engine, performancePriority = ScenePerformancePriority.BackwardCompatible) { super(engine); this.performancePriority = performancePriority; + this.clearColor = new Color4(0, 0, 0, 0); } public getDepthRenderer(): DepthRenderer { From 05cab2b7b73bb8d99d1413cb88c070310bf7a2f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 15 Jan 2024 10:08:13 +0100 Subject: [PATCH 03/11] Update starfieldFragment.glsl --- src/shaders/starfieldFragment.glsl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/shaders/starfieldFragment.glsl b/src/shaders/starfieldFragment.glsl index 2b35f8cdd..70232c824 100644 --- a/src/shaders/starfieldFragment.glsl +++ b/src/shaders/starfieldFragment.glsl @@ -32,6 +32,10 @@ void main() { vec2 starfieldUV = vec2(0.0); + // Here, a color test is used and not a depth test + // You may wonder why. The answer is that using a depth test wouldn't account for the 2D UI and the starfield would be drawn on top of it. + // In fact the UI has no depth information, so we need to use something else. I chose this color test as it works in practice but it could break. + // If you have a better idea, please let me know or make a pull request. if (screenColor == vec4(0.0)) { // get the starfield color // get spherical coordinates uv for the starfield texture From 1097e40652947cfc0381760bd66a0f9f7f2dfc14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 15 Jan 2024 10:08:48 +0100 Subject: [PATCH 04/11] fixed playground crash there is still an occlusion bug though --- src/ts/playground.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ts/playground.ts b/src/ts/playground.ts index 13115f8cc..284a21559 100644 --- a/src/ts/playground.ts +++ b/src/ts/playground.ts @@ -15,12 +15,12 @@ import { TelluricPlanemo } from "./planemos/telluricPlanemo/telluricPlanemo"; import { ChunkForge } from "./planemos/telluricPlanemo/terrain/chunks/chunkForge"; import { StarfieldPostProcess } from "./postProcesses/starfieldPostProcess"; import { Quaternion } from "@babylonjs/core/Maths/math"; -import { FlatCloudsPostProcess } from "./postProcesses/clouds/flatCloudsPostProcess"; import { AtmosphericScatteringPostProcess } from "./postProcesses/atmosphericScatteringPostProcess"; import { Star } from "./stellarObjects/star/star"; import { LensFlarePostProcess } from "./postProcesses/lensFlarePostProcess"; import { Settings } from "./settings"; import { ScenePerformancePriority } from "@babylonjs/core"; +import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; const canvas = document.getElementById("renderer") as HTMLCanvasElement; canvas.width = window.innerWidth; @@ -53,6 +53,7 @@ camera.attachControl(canvas, true); const planet = new TelluricPlanemo("xrPlanet", scene, 0.51, undefined); translate(planet.getTransform(), new Vector3(0, 0, sphereRadius * 4)); +const hemiLight = new HemisphericLight("hemiLight", new Vector3(0, 1, 0), scene); const star = new Star("star", scene, 0.2); //PointLightWrapper(new PointLight("dir01", new Vector3(0, 1, 0), scene)); translate(star.getTransform(), new Vector3(0, 0, -sphereRadius * 5000)); From 42e65e3b902af8a1f1c9c053cef04cb404fa4a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 15 Jan 2024 10:20:20 +0100 Subject: [PATCH 05/11] added basic time estimation for hyperspace travelling --- src/ts/ui/objectOverlay.ts | 22 ++++++++++++++++++++-- src/ts/utils/parseToStrings.ts | 12 ++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/ts/ui/objectOverlay.ts b/src/ts/ui/objectOverlay.ts index 355d27376..397b909ce 100644 --- a/src/ts/ui/objectOverlay.ts +++ b/src/ts/ui/objectOverlay.ts @@ -3,7 +3,7 @@ import { AbstractObject } from "../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 { parseDistance, parseSeconds } from "../utils/parseToStrings"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { getAngularSize } from "../utils/isObjectVisibleOnScreen"; import { Camera } from "@babylonjs/core/Cameras/camera"; @@ -15,14 +15,17 @@ export class ObjectOverlay { readonly namePlate: TextBlock; readonly typeText: TextBlock; readonly distanceText: TextBlock; + readonly etaText: TextBlock; readonly object: AbstractObject; + private lastDistance: number = 0; + constructor(object: AbstractObject) { this.object = object; this.textRoot = new StackPanel(object.name + "OverlayTextRoot"); this.textRoot.width = "150px"; - this.textRoot.height = "90px"; + this.textRoot.height = "130px"; this.textRoot.background = "transparent"; this.textRoot.zIndex = 6; this.textRoot.alpha = 0.95; @@ -56,6 +59,15 @@ export class ObjectOverlay { this.distanceText.textVerticalAlignment = TextBlock.VERTICAL_ALIGNMENT_CENTER; this.textRoot.addControl(this.distanceText); + this.etaText = new TextBlock(object.name + "OverlayEtaText"); + this.etaText.color = "white"; + this.etaText.zIndex = 6; + this.etaText.height = "20px"; + this.etaText.fontSize = 16; + this.etaText.textHorizontalAlignment = TextBlock.HORIZONTAL_ALIGNMENT_LEFT; + this.etaText.textVerticalAlignment = TextBlock.VERTICAL_ALIGNMENT_CENTER; + this.textRoot.addControl(this.etaText); + this.cursor = new Image(object.name + "Cursor", cursorImage); this.cursor.fixedRatio = 1; this.cursor.width = 1; @@ -72,6 +84,8 @@ export class ObjectOverlay { const viewRay = camera.getDirection(LOCAL_DIRECTION.BACKWARD); const objectRay = this.object.getTransform().getAbsolutePosition().subtract(camera.globalPosition); const distance = objectRay.length(); + const deltaDistance = Math.abs(distance - this.lastDistance); + const speed = deltaDistance > 0 ? deltaDistance / (camera.getScene().getEngine().getDeltaTime() / 1000) : 0; objectRay.scaleInPlace(1 / distance); if (Vector3.Dot(viewRay, objectRay) < 0) { @@ -99,6 +113,10 @@ export class ObjectOverlay { this.textRoot.linkOffsetXInPixels = 0.5 * Math.max(scale, screenRatio) * window.innerWidth + 75 + 20; this.distanceText.text = parseDistance(distance); + + this.etaText.text = speed > 0 ? parseSeconds(distance / speed) : "∞"; + + this.lastDistance = distance; } dispose() { diff --git a/src/ts/utils/parseToStrings.ts b/src/ts/utils/parseToStrings.ts index 5e4bc9788..bad775bd9 100644 --- a/src/ts/utils/parseToStrings.ts +++ b/src/ts/utils/parseToStrings.ts @@ -24,6 +24,18 @@ export function parseDistance(distance: number): string { } } +export function parseSeconds(seconds: number): string { + if (seconds < 60) { + return `${seconds.toFixed(0)} s`; + } else if (seconds < 3600) { + return `${(seconds / 60).toFixed(0)} min`; + } else if (seconds < 86400) { + return `${(seconds / 3600).toFixed(0)} h`; + } else { + return `${(seconds / 86400).toFixed(0)} d`; + } +} + /** * Parse a number between 0 and 1 to a percentage string. * Example: 0.5 -> "50%" From 5aa1900c1d6aff6fadaf758fb7168f88e3faef13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 15 Jan 2024 10:25:00 +0100 Subject: [PATCH 06/11] time estimate: account for objects moving away or not moving at all --- src/ts/ui/objectOverlay.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ts/ui/objectOverlay.ts b/src/ts/ui/objectOverlay.ts index 397b909ce..4af9ec36f 100644 --- a/src/ts/ui/objectOverlay.ts +++ b/src/ts/ui/objectOverlay.ts @@ -84,8 +84,8 @@ export class ObjectOverlay { const viewRay = camera.getDirection(LOCAL_DIRECTION.BACKWARD); const objectRay = this.object.getTransform().getAbsolutePosition().subtract(camera.globalPosition); const distance = objectRay.length(); - const deltaDistance = Math.abs(distance - this.lastDistance); - const speed = deltaDistance > 0 ? deltaDistance / (camera.getScene().getEngine().getDeltaTime() / 1000) : 0; + const deltaDistance = this.lastDistance - distance; + const speed = deltaDistance != 0 ? deltaDistance / (camera.getScene().getEngine().getDeltaTime() / 1000) : 0; objectRay.scaleInPlace(1 / distance); if (Vector3.Dot(viewRay, objectRay) < 0) { @@ -114,7 +114,8 @@ export class ObjectOverlay { this.distanceText.text = parseDistance(distance); - this.etaText.text = speed > 0 ? parseSeconds(distance / speed) : "∞"; + const nbSeconds = distance / speed; + this.etaText.text = speed > 0 && nbSeconds < 60 * 60 * 24 ? parseSeconds(nbSeconds) : "∞"; this.lastDistance = distance; } From c6e81cc3e7119f2c3453323a1b265b6b86968e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 15 Jan 2024 15:00:00 +0100 Subject: [PATCH 07/11] prevent subdivision from disabled chunks --- src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts b/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts index ba3d83683..41980d205 100644 --- a/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts +++ b/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts @@ -189,6 +189,7 @@ export class ChunkTree { if (tree instanceof PlanetChunk) { if (!tree.isReady()) return tree; if (!tree.mesh.isVisible) return tree; + if (!tree.mesh.isEnabled()) return tree; } const newTree = [ From 1e24e7d38bac8ba29681fcde4cb6d8986f06a8e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 15 Jan 2024 15:06:36 +0100 Subject: [PATCH 08/11] Replaced chunkforge requirement by interface This will allow to develop a new kind of forge for WebGPU that will be interoperable --- src/ts/physicSpaceship.ts | 4 +- .../telluricPlanemo/telluricPlanemo.ts | 3 +- .../terrain/chunks/chunkForge.ts | 114 +----------------- .../terrain/chunks/chunkForgeWorkers.ts | 113 +++++++++++++++++ .../terrain/chunks/chunkTree.ts | 3 +- src/ts/playground.ts | 4 +- src/ts/starSystem/StarSystemView.ts | 5 +- src/ts/starSystem/starSystemController.ts | 2 +- src/ts/xr.ts | 10 +- 9 files changed, 130 insertions(+), 128 deletions(-) create mode 100644 src/ts/planemos/telluricPlanemo/terrain/chunks/chunkForgeWorkers.ts diff --git a/src/ts/physicSpaceship.ts b/src/ts/physicSpaceship.ts index a9f595544..70831cd0a 100644 --- a/src/ts/physicSpaceship.ts +++ b/src/ts/physicSpaceship.ts @@ -29,7 +29,7 @@ import { translate } from "./uberCore/transforms/basicTransform"; import { StarModel } from "./stellarObjects/star/starModel"; import { Keyboard } from "./inputs/keyboard"; import { Star } from "./stellarObjects/star/star"; -import { ChunkForge } from "./planemos/telluricPlanemo/terrain/chunks/chunkForge"; +import { ChunkForgeWorkers } from "./planemos/telluricPlanemo/terrain/chunks/chunkForgeWorkers"; const canvas = document.getElementById("renderer") as HTMLCanvasElement; canvas.width = window.innerWidth; @@ -63,7 +63,7 @@ hemiLight.intensity = 0.2; const shadowGenerator = new ShadowGenerator(1024, light); shadowGenerator.useBlurExponentialShadowMap = true; -const chunkForge = new ChunkForge(Settings.VERTEX_RESOLUTION); +const chunkForge = new ChunkForgeWorkers(Settings.VERTEX_RESOLUTION); const keyboard = new Keyboard(); diff --git a/src/ts/planemos/telluricPlanemo/telluricPlanemo.ts b/src/ts/planemos/telluricPlanemo/telluricPlanemo.ts index ef674bb34..4bcacebcd 100644 --- a/src/ts/planemos/telluricPlanemo/telluricPlanemo.ts +++ b/src/ts/planemos/telluricPlanemo/telluricPlanemo.ts @@ -12,9 +12,10 @@ import { TelluricPlanemoModel } from "./telluricPlanemoModel"; import { PostProcessType } from "../../postProcesses/postProcessTypes"; import { Camera } from "@babylonjs/core/Cameras/camera"; import { ChunkTree } from "./terrain/chunks/chunkTree"; -import { ChunkForge } from "./terrain/chunks/chunkForge"; +import { ChunkForgeWorkers } from "./terrain/chunks/chunkForgeWorkers"; import { PhysicsShapeSphere } from "@babylonjs/core/Physics/v2/physicsShape"; import { Transformable } from "../../uberCore/transforms/basicTransform"; +import { ChunkForge } from "./terrain/chunks/chunkForge"; export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMaterial { readonly sides: ChunkTree[]; // stores the 6 sides of the sphere diff --git a/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkForge.ts b/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkForge.ts index 5df36abb1..96be5dac3 100644 --- a/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkForge.ts +++ b/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkForge.ts @@ -1,112 +1,6 @@ -import { TransferBuildData } from "./workerDataTypes"; -import { ApplyTask, BuildTask, ReturnedChunkData, TaskType } from "./taskTypes"; -import { WorkerPool } from "./workerPool"; -import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData"; +import { BuildTask } from "./taskTypes"; -export class ChunkForge { - /** - * the number vertices per row of the chunk (total number of vertices = nbVerticesPerRow * nbVerticesPerRow) - */ - nbVerticesPerRow: number; - - /** - * The worker manager - * FIXME: the workerpool does not need to be a class - */ - workerPool: WorkerPool; - - /** - * The queue of tasks containing chunks ready to be enabled - */ - applyTaskQueue: ApplyTask[] = []; - - constructor(nbVerticesPerRow: number) { - this.nbVerticesPerRow = nbVerticesPerRow; - const nbMaxWorkers = navigator.hardwareConcurrency - 1; // -1 because the main thread is also used - this.workerPool = new WorkerPool(nbMaxWorkers); - } - - public addTask(task: BuildTask) { - this.workerPool.submitTask(task); - } - - /** - * Executes the next task using an available worker - * @param worker the web worker assigned to the next task - */ - private executeNextTask(worker: Worker) { - if (this.workerPool.hasTask()) this.dispatchBuildTask(this.workerPool.nextTask(), worker); - else this.workerPool.finishedWorkers.push(worker); - } - - private dispatchBuildTask(task: BuildTask, worker: Worker): void { - const buildData: TransferBuildData = { - taskType: TaskType.Build, - planetName: task.planetName, - planetDiameter: task.planetDiameter, - nbVerticesPerSide: this.nbVerticesPerRow, - depth: task.depth, - direction: task.direction, - position: [task.position.x, task.position.y, task.position.z], - terrainSettings: { - continents_frequency: task.terrainSettings.continents_frequency, - continents_fragmentation: task.terrainSettings.continents_fragmentation, - continent_base_height: task.terrainSettings.continent_base_height, - max_mountain_height: task.terrainSettings.max_mountain_height, - max_bump_height: task.terrainSettings.max_bump_height, - bumps_frequency: task.terrainSettings.bumps_frequency, - mountains_frequency: task.terrainSettings.mountains_frequency - }, - seed: task.planetSeed - }; - - worker.postMessage(buildData); - - worker.onmessage = (e) => { - const data: ReturnedChunkData = e.data; - - const vertexData = new VertexData(); - vertexData.positions = data.positions; - vertexData.normals = data.normals; - vertexData.indices = data.indices; - - const applyTask: ApplyTask = { - type: TaskType.Apply, - vertexData: vertexData, - chunk: task.chunk, - instancesMatrixBuffer: data.instancesMatrixBuffer, - alignedInstancesMatrixBuffer: data.alignedInstancesMatrixBuffer, - averageHeight: data.averageHeight - }; - this.applyTaskQueue.push(applyTask); - - if (this.workerPool.hasTask()) this.dispatchBuildTask(this.workerPool.nextTask(), worker); - else this.workerPool.finishedWorkers.push(worker); - }; - } - - /** - * Apply generated vertexData to waiting chunks - */ - private executeNextApplyTask() { - let task = this.applyTaskQueue.shift(); - while (task !== undefined && task.chunk.hasBeenDisposed()) { - // if the chunk has been disposed, we skip it - task = this.applyTaskQueue.shift(); - } - if (task) task.chunk.init(task.vertexData, task.instancesMatrixBuffer, task.alignedInstancesMatrixBuffer, task.averageHeight); - } - - /** - * Updates the state of the forge : dispatch tasks to workers, remove useless chunks, apply vertexData to new chunks - */ - public update() { - for (let i = 0; i < this.workerPool.availableWorkers.length; i++) { - this.executeNextTask(this.workerPool.availableWorkers.shift() as Worker); - } - this.workerPool.availableWorkers = this.workerPool.availableWorkers.concat(this.workerPool.finishedWorkers); - this.workerPool.finishedWorkers = []; - - this.executeNextApplyTask(); - } +export interface ChunkForge { + addTask(task: BuildTask): void; + update(): void; } diff --git a/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkForgeWorkers.ts b/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkForgeWorkers.ts new file mode 100644 index 000000000..32f52054c --- /dev/null +++ b/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkForgeWorkers.ts @@ -0,0 +1,113 @@ +import { TransferBuildData } from "./workerDataTypes"; +import { ApplyTask, BuildTask, ReturnedChunkData, TaskType } from "./taskTypes"; +import { WorkerPool } from "./workerPool"; +import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData"; +import { ChunkForge } from "./chunkForge"; + +export class ChunkForgeWorkers implements ChunkForge { + /** + * the number vertices per row of the chunk (total number of vertices = nbVerticesPerRow * nbVerticesPerRow) + */ + nbVerticesPerRow: number; + + /** + * The worker manager + * FIXME: the workerpool does not need to be a class + */ + workerPool: WorkerPool; + + /** + * The queue of tasks containing chunks ready to be enabled + */ + applyTaskQueue: ApplyTask[] = []; + + constructor(nbVerticesPerRow: number) { + this.nbVerticesPerRow = nbVerticesPerRow; + const nbMaxWorkers = navigator.hardwareConcurrency - 1; // -1 because the main thread is also used + this.workerPool = new WorkerPool(nbMaxWorkers); + } + + public addTask(task: BuildTask) { + this.workerPool.submitTask(task); + } + + /** + * Executes the next task using an available worker + * @param worker the web worker assigned to the next task + */ + private executeNextTask(worker: Worker) { + if (this.workerPool.hasTask()) this.dispatchBuildTask(this.workerPool.nextTask(), worker); + else this.workerPool.finishedWorkers.push(worker); + } + + private dispatchBuildTask(task: BuildTask, worker: Worker): void { + const buildData: TransferBuildData = { + taskType: TaskType.Build, + planetName: task.planetName, + planetDiameter: task.planetDiameter, + nbVerticesPerSide: this.nbVerticesPerRow, + depth: task.depth, + direction: task.direction, + position: [task.position.x, task.position.y, task.position.z], + terrainSettings: { + continents_frequency: task.terrainSettings.continents_frequency, + continents_fragmentation: task.terrainSettings.continents_fragmentation, + continent_base_height: task.terrainSettings.continent_base_height, + max_mountain_height: task.terrainSettings.max_mountain_height, + max_bump_height: task.terrainSettings.max_bump_height, + bumps_frequency: task.terrainSettings.bumps_frequency, + mountains_frequency: task.terrainSettings.mountains_frequency + }, + seed: task.planetSeed + }; + + worker.postMessage(buildData); + + worker.onmessage = (e) => { + const data: ReturnedChunkData = e.data; + + const vertexData = new VertexData(); + vertexData.positions = data.positions; + vertexData.normals = data.normals; + vertexData.indices = data.indices; + + const applyTask: ApplyTask = { + type: TaskType.Apply, + vertexData: vertexData, + chunk: task.chunk, + instancesMatrixBuffer: data.instancesMatrixBuffer, + alignedInstancesMatrixBuffer: data.alignedInstancesMatrixBuffer, + averageHeight: data.averageHeight + }; + this.applyTaskQueue.push(applyTask); + + if (this.workerPool.hasTask()) this.dispatchBuildTask(this.workerPool.nextTask(), worker); + else this.workerPool.finishedWorkers.push(worker); + }; + } + + /** + * Apply generated vertexData to waiting chunks + */ + private executeNextApplyTask() { + let task = this.applyTaskQueue.shift(); + while (task !== undefined && task.chunk.hasBeenDisposed()) { + // if the chunk has been disposed, we skip it + task = this.applyTaskQueue.shift(); + } + if (task) task.chunk.init(task.vertexData, task.instancesMatrixBuffer, task.alignedInstancesMatrixBuffer, task.averageHeight); + } + + /** + * Updates the state of the forge : dispatch tasks to workers, remove useless chunks, apply vertexData to new chunks + */ + public update() { + for (let i = 0; i < this.workerPool.availableWorkers.length; i++) { + this.executeNextTask(this.workerPool.availableWorkers.shift() as Worker); + } + this.workerPool.availableWorkers = this.workerPool.availableWorkers.concat(this.workerPool.finishedWorkers); + this.workerPool.finishedWorkers = []; + + this.executeNextApplyTask(); + } +} diff --git a/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts b/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts index 41980d205..763051504 100644 --- a/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts +++ b/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts @@ -1,6 +1,5 @@ import { PlanetChunk } from "./planetChunk"; import { Direction } from "../../../../utils/direction"; -import { ChunkForge } from "./chunkForge"; import { BuildTask, TaskType } from "./taskTypes"; import { Settings } from "../../../../settings"; import { getChunkSphereSpacePositionFromPath } from "../../../../utils/chunkUtils"; @@ -11,11 +10,11 @@ import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate"; import { TransformNode } from "@babylonjs/core/Meshes"; import { Camera } from "@babylonjs/core/Cameras/camera"; -import { isSizeOnScreenEnough } from "../../../../utils/isObjectVisibleOnScreen"; import { Observable } from "@babylonjs/core/Misc/observable"; import { DeleteSemaphore } from "./deleteSemaphore"; import { UberScene } from "../../../../uberCore/uberScene"; import { getRotationQuaternion } from "../../../../uberCore/transforms/basicTransform"; +import { ChunkForge } from "./chunkForge"; /** * A quadTree is defined recursively diff --git a/src/ts/playground.ts b/src/ts/playground.ts index 284a21559..05536fc0e 100644 --- a/src/ts/playground.ts +++ b/src/ts/playground.ts @@ -12,7 +12,7 @@ import HavokPhysics from "@babylonjs/havok"; import { HavokPlugin } from "@babylonjs/core/Physics/v2/Plugins/havokPlugin"; import { setMaxLinVel } from "./utils/havok"; import { TelluricPlanemo } from "./planemos/telluricPlanemo/telluricPlanemo"; -import { ChunkForge } from "./planemos/telluricPlanemo/terrain/chunks/chunkForge"; +import { ChunkForgeWorkers } from "./planemos/telluricPlanemo/terrain/chunks/chunkForgeWorkers"; import { StarfieldPostProcess } from "./postProcesses/starfieldPostProcess"; import { Quaternion } from "@babylonjs/core/Maths/math"; import { AtmosphericScatteringPostProcess } from "./postProcesses/atmosphericScatteringPostProcess"; @@ -69,7 +69,7 @@ camera.attachPostProcess(atmosphere); const lensflare = new LensFlarePostProcess(star, scene); camera.attachPostProcess(lensflare); -const chunkForge = new ChunkForge(Settings.VERTEX_RESOLUTION); +const chunkForge = new ChunkForgeWorkers(Settings.VERTEX_RESOLUTION); scene.onBeforeRenderObservable.add(() => { const deltaTime = scene.deltaTime / 1000; diff --git a/src/ts/starSystem/StarSystemView.ts b/src/ts/starSystem/StarSystemView.ts index dc8190eaf..0a6ae08ce 100644 --- a/src/ts/starSystem/StarSystemView.ts +++ b/src/ts/starSystem/StarSystemView.ts @@ -18,8 +18,9 @@ import { positionNearObject } from "../utils/positionNearObject"; import { ShipControls } from "../spaceship/shipControls"; import { OrbitRenderer } from "../orbit/orbitRenderer"; import { BlackHole } from "../stellarObjects/blackHole/blackHole"; -import { ChunkForge } from "../planemos/telluricPlanemo/terrain/chunks/chunkForge"; +import { ChunkForgeWorkers } from "../planemos/telluricPlanemo/terrain/chunks/chunkForgeWorkers"; import "@babylonjs/core/Loading/loadingScreen"; +import { ChunkForge } from "../planemos/telluricPlanemo/terrain/chunks/chunkForge"; export class StarSystemView { private readonly helmetOverlay: HelmetOverlay; @@ -35,7 +36,7 @@ export class StarSystemView { private starSystem: StarSystemController | null = null; - private readonly chunkForge = new ChunkForge(Settings.VERTEX_RESOLUTION); + private readonly chunkForge: ChunkForge = new ChunkForgeWorkers(Settings.VERTEX_RESOLUTION); constructor(engine: Engine, havokPlugin: HavokPlugin) { this.helmetOverlay = new HelmetOverlay(); diff --git a/src/ts/starSystem/starSystemController.ts b/src/ts/starSystem/starSystemController.ts index dabee3bc8..cefb28bc4 100644 --- a/src/ts/starSystem/starSystemController.ts +++ b/src/ts/starSystem/starSystemController.ts @@ -19,8 +19,8 @@ import { rotateAround, setUpVector, translate } from "../uberCore/transforms/bas import { Star } from "../stellarObjects/star/star"; import { BlackHole } from "../stellarObjects/blackHole/blackHole"; import { NeutronStar } from "../stellarObjects/neutronStar/neutronStar"; -import { ChunkForge } from "../planemos/telluricPlanemo/terrain/chunks/chunkForge"; import { SystemSeed } from "../utils/systemSeed"; +import { ChunkForge } from "../planemos/telluricPlanemo/terrain/chunks/chunkForge"; export class StarSystemController { readonly scene: UberScene; diff --git a/src/ts/xr.ts b/src/ts/xr.ts index f6d5225ac..e04b6f1df 100644 --- a/src/ts/xr.ts +++ b/src/ts/xr.ts @@ -2,7 +2,6 @@ import "../styles/index.scss"; import { Assets } from "./assets"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; -import { OceanPostProcess } from "./postProcesses/oceanPostProcess"; import { UberScene } from "./uberCore/uberScene"; import { translate } from "./uberCore/transforms/basicTransform"; import { FreeCamera } from "@babylonjs/core/Cameras/freeCamera"; @@ -12,13 +11,8 @@ import HavokPhysics from "@babylonjs/havok"; import { HavokPlugin } from "@babylonjs/core/Physics/v2/Plugins/havokPlugin"; import { setMaxLinVel } from "./utils/havok"; import { TelluricPlanemo } from "./planemos/telluricPlanemo/telluricPlanemo"; -import { ChunkForge } from "./planemos/telluricPlanemo/terrain/chunks/chunkForge"; -import { StarfieldPostProcess } from "./postProcesses/starfieldPostProcess"; -import { Quaternion } from "@babylonjs/core/Maths/math"; -import { FlatCloudsPostProcess } from "./postProcesses/clouds/flatCloudsPostProcess"; -import { AtmosphericScatteringPostProcess } from "./postProcesses/atmosphericScatteringPostProcess"; +import { ChunkForgeWorkers } from "./planemos/telluricPlanemo/terrain/chunks/chunkForgeWorkers"; import { Star } from "./stellarObjects/star/star"; -import { LensFlarePostProcess } from "./postProcesses/lensFlarePostProcess"; import { Settings } from "./settings"; import { ScenePerformancePriority } from "@babylonjs/core"; @@ -114,7 +108,7 @@ FlatCloudsPostProcess.CreateAsync("clouds", planet, planet.model.cloudsUniforms, xrCamera.attachPostProcess(lensflare); });*/ -const chunkForge = new ChunkForge(Settings.VERTEX_RESOLUTION); +const chunkForge = new ChunkForgeWorkers(Settings.VERTEX_RESOLUTION); scene.onBeforeRenderObservable.add(() => { const deltaTime = engine.getDeltaTime() / 1000; From a13e7fb663f5689b066e1e31585b0e1aa6098283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 16 Jan 2024 12:19:04 +0100 Subject: [PATCH 09/11] switched to constraint based parenting for planet chunks --- src/ts/index.ts | 2 +- .../telluricPlanemo/telluricPlanemo.ts | 13 ++--- .../terrain/chunks/chunkTree.ts | 19 ++----- .../terrain/chunks/planetChunk.ts | 49 ++++++------------- src/ts/starSystem/StarSystemView.ts | 2 +- src/ts/ui/systemUI.ts | 2 +- 6 files changed, 26 insertions(+), 61 deletions(-) diff --git a/src/ts/index.ts b/src/ts/index.ts index 208247dec..5815a6c39 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -21,7 +21,6 @@ import { Mouse } from "./inputs/mouse"; import { Keyboard } from "./inputs/keyboard"; import { StarModel } from "./stellarObjects/star/starModel"; import { RingsUniforms } from "./postProcesses/rings/ringsUniform"; -import { SpaceStation } from "./spacestation/spaceStation"; import { getMoonSeed } from "./planemos/common"; import { Gamepad } from "./inputs/gamepad"; @@ -132,6 +131,7 @@ const planet = StarSystemHelper.makeTelluricPlanet(starSystem, planetModel); planet.model.ringsUniforms = new RingsUniforms(planet.model.rng); planet.postProcesses.push(PostProcessType.RING); + //const spacestation = new SpaceStation(starSystemView.scene, planet); //starSystemView.getStarSystem().addSpaceStation(spacestation); diff --git a/src/ts/planemos/telluricPlanemo/telluricPlanemo.ts b/src/ts/planemos/telluricPlanemo/telluricPlanemo.ts index 4bcacebcd..ed8e8a787 100644 --- a/src/ts/planemos/telluricPlanemo/telluricPlanemo.ts +++ b/src/ts/planemos/telluricPlanemo/telluricPlanemo.ts @@ -12,10 +12,11 @@ import { TelluricPlanemoModel } from "./telluricPlanemoModel"; import { PostProcessType } from "../../postProcesses/postProcessTypes"; import { Camera } from "@babylonjs/core/Cameras/camera"; import { ChunkTree } from "./terrain/chunks/chunkTree"; -import { ChunkForgeWorkers } from "./terrain/chunks/chunkForgeWorkers"; import { PhysicsShapeSphere } from "@babylonjs/core/Physics/v2/physicsShape"; import { Transformable } from "../../uberCore/transforms/basicTransform"; import { ChunkForge } from "./terrain/chunks/chunkForge"; +import { Observable } from "@babylonjs/core/Misc/observable"; +import { PlanetChunk } from "./terrain/chunks/planetChunk"; export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMaterial { readonly sides: ChunkTree[]; // stores the 6 sides of the sphere @@ -24,6 +25,8 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat readonly model: TelluricPlanemoModel; + readonly onChunkCreatedObservable = new Observable(); + /** * New Telluric Planet * @param name The name of the planet @@ -71,13 +74,7 @@ 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) { - side.onChunkPhysicsShapeDeletedObservable.add((index) => { - for (const side2 of this.sides) { - side2.registerPhysicsShapeDeletion(index); - } - }); - } + this.sides.forEach((side) => side.onChunkCreatedObservable.add((chunk) => this.onChunkCreatedObservable.notifyObservers(chunk))); } getTypeName(): string { diff --git a/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts b/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts index 763051504..31b97fa71 100644 --- a/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts +++ b/src/ts/planemos/telluricPlanemo/terrain/chunks/chunkTree.ts @@ -47,7 +47,7 @@ export class ChunkTree { readonly parent: TransformNode; readonly parentAggregate: PhysicsAggregate; - readonly onChunkPhysicsShapeDeletedObservable = new Observable(); + readonly onChunkCreatedObservable = new Observable(); readonly material: Material; @@ -60,7 +60,7 @@ export class ChunkTree { * @param material * @param scene */ - constructor(direction: Direction, planetName: string, planetModel: TelluricPlanemoModel, parentAggregate: PhysicsAggregate, material: Material, scene: UberScene) { + constructor(direction: Direction, planetName: string, planetModel: TelluricPlanemoModel, parentAggregate: PhysicsAggregate, material: Material, scene: UberScene) { this.rootChunkLength = planetModel.radius * 2; this.planetName = planetName; this.planetSeed = planetModel.seed; @@ -215,8 +215,8 @@ export class ChunkTree { private createChunk(path: number[], chunkForge: ChunkForge): PlanetChunk { const chunk = new PlanetChunk(path, this.direction, this.parentAggregate, this.material, this.planetModel, this.rootChunkLength, this.scene); - chunk.onDestroyPhysicsShapeObservable.add((index) => { - this.onChunkPhysicsShapeDeletedObservable.notifyObservers(index); + chunk.onRecieveVertexDataObservable.add(() => { + this.onChunkCreatedObservable.notifyObservers(chunk); }); const buildTask: BuildTask = { @@ -236,17 +236,6 @@ export class ChunkTree { return chunk; } - public registerPhysicsShapeDeletion(index: number): void { - this.executeOnEveryChunk((chunk) => { - chunk.registerPhysicsShapeDeletion(index); - }); - for (const deleteSemaphore of this.deleteSemaphores) { - for (const chunk of deleteSemaphore.chunksToDelete) { - chunk.registerPhysicsShapeDeletion(index); - } - } - } - public computeCulling(camera: Camera): void { this.executeOnEveryChunk((chunk: PlanetChunk) => { chunk.computeCulling(camera); diff --git a/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts b/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts index c62a1e72e..34f80b1ea 100644 --- a/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts +++ b/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts @@ -7,19 +7,18 @@ 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 { PhysicsShape, PhysicsShapeMesh } from "@babylonjs/core/Physics/v2/physicsShape"; import { Observable } from "@babylonjs/core/Misc/observable"; import { Transformable } from "../../../../uberCore/transforms/basicTransform"; import { ThinInstancePatch } from "../instancePatch/thinInstancePatch"; import { randomDownSample } from "../instancePatch/matrixBuffer"; import { Assets } from "../../../../assets"; -import { CollisionMask } from "../../../../settings"; import { isSizeOnScreenEnough } from "../../../../utils/isObjectVisibleOnScreen"; import { Camera } from "@babylonjs/core/Cameras/camera"; import { IPatch } from "../instancePatch/iPatch"; import { TelluricPlanemoModel } from "../../telluricPlanemoModel"; import { BoundingSphere } from "../../../../bodies/common"; -import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; +import { PhysicsMotionType, PhysicsShapeType } from "@babylonjs/core/Physics/v2/IPhysicsEnginePlugin"; +import { LockConstraint } from "@babylonjs/core/Physics/v2/physicsConstraint"; export class PlanetChunk implements Transformable, BoundingSphere { public readonly mesh: Mesh; @@ -38,12 +37,10 @@ export class PlanetChunk implements Transformable, BoundingSphere { readonly instancePatches: IPatch[] = []; - readonly onDestroyPhysicsShapeObservable = new Observable(); - readonly onRecieveVertexDataObservable = new Observable(); + readonly onDisposeObservable = new Observable(); - private physicsShape: PhysicsShape | null = null; - physicsShapeIndex: number | null = null; + aggregate: PhysicsAggregate | null = null; readonly parentAggregate: PhysicsAggregate; private averageHeight = 0; @@ -123,11 +120,13 @@ export class PlanetChunk implements Transformable, BoundingSphere { this.mesh.freezeNormals(); if (this.depth > 3) { - this.physicsShape = new PhysicsShapeMesh(this.mesh, this.mesh.getScene()); - this.physicsShape.filterMembershipMask = CollisionMask.GROUND; - this.parentAggregate.shape.addChildFromParent(this.parent, this.physicsShape, this.mesh); - this.physicsShapeIndex = this.parentAggregate.shape.getNumChildren(); + this.aggregate = new PhysicsAggregate(this.mesh, PhysicsShapeType.MESH, { mass: 0 }, this.mesh.getScene()); + this.aggregate.body.setMotionType(PhysicsMotionType.STATIC); + this.aggregate.body.disablePreStep = false; + const constraint = new LockConstraint(Vector3.Zero(), this.getTransform().position.negate(), new Vector3(0, 1, 0), new Vector3(0, 1, 0), this.mesh.getScene()); + this.parentAggregate.body.addConstraint(this.aggregate.body, constraint); } + this.mesh.setEnabled(true); this.loaded = true; @@ -160,29 +159,6 @@ export class PlanetChunk implements Transformable, BoundingSphere { return this.averageHeight; } - private destroyPhysicsShape() { - 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 - }` - ); - } - - this.parentAggregate.shape.removeChild(this.physicsShapeIndex); - this.physicsShape?.dispose(); - - this.onDestroyPhysicsShapeObservable.notifyObservers(this.physicsShapeIndex); - } - - public registerPhysicsShapeDeletion(shapeIndex: number) { - if (this.physicsShapeIndex === null) return; - if (this.physicsShapeIndex > shapeIndex) { - this.physicsShapeIndex--; - } - } - public getBoundingRadius(): number { return this.chunkSideLength / 2; } @@ -200,12 +176,15 @@ export class PlanetChunk implements Transformable, BoundingSphere { } public dispose() { - this.destroyPhysicsShape(); + this.onDisposeObservable.notifyObservers(); + + this.aggregate?.dispose(); this.helpers.forEach((helper) => helper.dispose()); this.instancePatches.forEach((patch) => patch.dispose()); this.mesh.dispose(); this.transform.dispose(); this.onRecieveVertexDataObservable.clear(); + this.onDisposeObservable.clear(); this.disposed = true; } diff --git a/src/ts/starSystem/StarSystemView.ts b/src/ts/starSystem/StarSystemView.ts index 0a6ae08ce..77b9bbc2f 100644 --- a/src/ts/starSystem/StarSystemView.ts +++ b/src/ts/starSystem/StarSystemView.ts @@ -30,7 +30,7 @@ export class StarSystemView { private readonly orbitRenderer: OrbitRenderer = new OrbitRenderer(); private readonly axisRenderer: AxisRenderer = new AxisRenderer(); - private readonly ui: SystemUI; + readonly ui: SystemUI; private static readonly unZoomAnimation = new Animation("unZoom", "radius", 60, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CYCLE); diff --git a/src/ts/ui/systemUI.ts b/src/ts/ui/systemUI.ts index fb9a39f09..e6d6f3d28 100644 --- a/src/ts/ui/systemUI.ts +++ b/src/ts/ui/systemUI.ts @@ -5,7 +5,7 @@ import { ObjectOverlay } from "./objectOverlay"; import { Camera } from "@babylonjs/core/Cameras/camera"; export class SystemUI { - private readonly gui: AdvancedDynamicTexture; + readonly gui: AdvancedDynamicTexture; private objectOverlays: ObjectOverlay[] = []; private target: AbstractObject | null = null; From 6a8f2291faa6feecf1e5532ef5257fa6e930a8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:19:13 +0100 Subject: [PATCH 10/11] disabled occlusion again --- src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts b/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts index 34f80b1ea..d01880a1f 100644 --- a/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts +++ b/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts @@ -69,8 +69,8 @@ export class PlanetChunk implements Transformable, BoundingSphere { this.transform.parent = parentAggregate.transformNode; this.mesh.parent = this.transform; - this.mesh.occlusionQueryAlgorithmType = AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE; - this.mesh.occlusionType = AbstractMesh.OCCLUSION_TYPE_OPTIMISTIC; + //this.mesh.occlusionQueryAlgorithmType = AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE; + //this.mesh.occlusionType = AbstractMesh.OCCLUSION_TYPE_OPTIMISTIC; this.parent = parentAggregate.transformNode; this.parentAggregate = parentAggregate; From d530de731d18fa3b665d61ac0627e411b36e463d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:31:30 +0100 Subject: [PATCH 11/11] renabled occlusion --- .../planemos/telluricPlanemo/terrain/chunks/planetChunk.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts b/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts index d01880a1f..83634b677 100644 --- a/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts +++ b/src/ts/planemos/telluricPlanemo/terrain/chunks/planetChunk.ts @@ -19,6 +19,7 @@ import { TelluricPlanemoModel } from "../../telluricPlanemoModel"; import { BoundingSphere } from "../../../../bodies/common"; import { PhysicsMotionType, PhysicsShapeType } from "@babylonjs/core/Physics/v2/IPhysicsEnginePlugin"; import { LockConstraint } from "@babylonjs/core/Physics/v2/physicsConstraint"; +import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; export class PlanetChunk implements Transformable, BoundingSphere { public readonly mesh: Mesh; @@ -69,8 +70,8 @@ export class PlanetChunk implements Transformable, BoundingSphere { this.transform.parent = parentAggregate.transformNode; this.mesh.parent = this.transform; - //this.mesh.occlusionQueryAlgorithmType = AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE; - //this.mesh.occlusionType = AbstractMesh.OCCLUSION_TYPE_OPTIMISTIC; + this.mesh.occlusionQueryAlgorithmType = AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE; + this.mesh.occlusionType = AbstractMesh.OCCLUSION_TYPE_OPTIMISTIC; this.parent = parentAggregate.transformNode; this.parentAggregate = parentAggregate;