diff --git a/examples/editor/src/DefaultMode.ts b/examples/editor/src/DefaultMode.ts index 0bf507e..3a9c5b0 100644 --- a/examples/editor/src/DefaultMode.ts +++ b/examples/editor/src/DefaultMode.ts @@ -44,7 +44,7 @@ class DefaultMode implements InputMode { } }; - let mouseDownPosition: SPLAT.Vector3; + let mouseDownPosition: SPLAT.Vector3 = new SPLAT.Vector3(); const handleMouseDown = () => { mouseDownPosition = engine.mouseManager.currentMousePosition; }; diff --git a/package.json b/package.json index c3ee6bd..24187df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gsplat", - "version": "1.0.2", + "version": "1.0.3", "description": "JavaScript Gaussian Splatting library", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/renderers/webgl/programs/RenderProgram.ts b/src/renderers/webgl/programs/RenderProgram.ts index 3a981d4..0df24e5 100644 --- a/src/renderers/webgl/programs/RenderProgram.ts +++ b/src/renderers/webgl/programs/RenderProgram.ts @@ -143,7 +143,7 @@ class RenderProgram extends ShaderProgram { private _outlineThickness: number = 10.0; private _outlineColor: Color32 = new Color32(255, 165, 0, 255); private _renderData: RenderData | null = null; - private _depthIndex: Uint32Array | null = null; + private _depthIndex: Uint32Array = new Uint32Array(); private _chunks: Uint8Array | null = null; private _splatTexture: WebGLTexture | null = null; @@ -301,9 +301,6 @@ class RenderProgram extends ShaderProgram { return; } - this._camera.update(); - worker.postMessage({ viewProj: this._camera.data.viewProj }); - if (this.renderData.needsRebuild) { this.renderData.rebuild(); } @@ -386,6 +383,9 @@ class RenderProgram extends ShaderProgram { this.renderData.transformsChanged = false; } + this._camera.update(); + worker.postMessage({ viewProj: this._camera.data.viewProj.buffer }); + gl.viewport(0, 0, canvas.width, canvas.height); gl.clearColor(0, 0, 0, 0); gl.clear(gl.COLOR_BUFFER_BIT); @@ -402,6 +402,7 @@ class RenderProgram extends ShaderProgram { gl.vertexAttribPointer(positionAttribute, 2, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, indexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, this.depthIndex, gl.STATIC_DRAW); gl.vertexAttribIPointer(indexAttribute, 1, gl.INT, 0, 0); gl.vertexAttribDivisor(indexAttribute, 1); diff --git a/src/renderers/webgl/utils/SortWorker.ts b/src/renderers/webgl/utils/SortWorker.ts index d74cc0e..3699dc6 100644 --- a/src/renderers/webgl/utils/SortWorker.ts +++ b/src/renderers/webgl/utils/SortWorker.ts @@ -1,4 +1,3 @@ -import { Matrix4 } from "../../../math/Matrix4"; import loadWasm from "../../../wasm/sort"; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -27,7 +26,8 @@ let countsPtr: number; let allocatedVertexCount: number = 0; let allocatedTransformCount: number = 0; -let viewProj: Matrix4; +let viewProj: Float32Array = new Float32Array(16); +let lastViewProj: Float32Array = new Float32Array(16); let running = false; let allocating = false; @@ -39,10 +39,6 @@ const allocateBuffers = async () => { const targetAllocatedVertexCount = Math.pow(2, Math.ceil(Math.log2(sortData.vertexCount))); if (allocatedVertexCount < targetAllocatedVertexCount) { - while (running) { - await new Promise((resolve) => setTimeout(resolve, 0)); - } - if (allocatedVertexCount > 0) { wasmModule._free(viewProjPtr); wasmModule._free(transformIndicesPtr); @@ -67,10 +63,6 @@ const allocateBuffers = async () => { } if (allocatedTransformCount < sortData.transforms.length) { - while (running) { - await new Promise((resolve) => setTimeout(resolve, 0)); - } - if (allocatedTransformCount > 0) { wasmModule._free(transformsPtr); } @@ -81,13 +73,14 @@ const allocateBuffers = async () => { } allocating = false; + lastViewProj = new Float32Array(16); }; -const runSort = (viewProj: Matrix4) => { +const runSort = () => { wasmModule.HEAPF32.set(sortData.positions, positionsPtr / 4); wasmModule.HEAPF32.set(sortData.transforms, transformsPtr / 4); wasmModule.HEAPU32.set(sortData.transformIndices, transformIndicesPtr / 4); - wasmModule.HEAPF32.set(viewProj.buffer, viewProjPtr / 4); + wasmModule.HEAPF32.set(viewProj, viewProjPtr / 4); wasmModule._sort( viewProjPtr, @@ -114,16 +107,23 @@ const runSort = (viewProj: Matrix4) => { ]); }; +const isEqual = (a: Float32Array, b: Float32Array) => { + for (let i = 0; i < 16; i++) { + if (a[i] !== b[i]) return false; + } + return true; +}; + const throttledSort = () => { if (!running) { running = true; - const lastView = viewProj; - runSort(lastView); + if (wasmModule && !allocating && !isEqual(viewProj, lastViewProj)) { + lastViewProj = viewProj; + runSort(); + } setTimeout(() => { running = false; - if (lastView !== viewProj) { - throttledSort(); - } + throttledSort(); }, 0); } }; @@ -133,7 +133,6 @@ self.onmessage = (e) => { sortData = e.data.sortData; allocateBuffers(); } - if (allocating || !sortData) return; if (e.data.viewProj) { viewProj = e.data.viewProj; throttledSort();