PageSourceSearch

https://webgl-gaussian-splatting.vercel.app/src/gizmo.js

js webgl-gaussian-splatting.vercel.app collected 2026-10-03 08:01:44 UTC 3,814 bytes, 86 lines download raw bytes

1class GizmoRenderer {
2    async init() {
3        const vertexShaderSource = await fetchFile('shaders/gizmo_vertex.glsl')
4        const fragmentShaderSource = await fetchFile('shaders/gizmo_fragment.glsl')
5
6        this.program = createProgram(gl, vertexShaderSource, fragmentShaderSource)
7        this.buffer = gl.createBuffer()
8
9        this.planeVertices = []
10    }
11
12    // Construct a plane from 3 vertices
13    setPlaneVertices(v1 = [], v2 = [], v3 = []) {
14        // Return if there are not enough vertices
15        if (v1.length * v2.length * v3.length === 0) {
16            this.planeVertices = new Float32Array([...v1, ...v2, ...v3])
17            return
18        }
19
20        // Update GUI
21        if (camController.p.textContent !== camController.texts['calibrated']) {
22            camController.p.textContent = camController.texts['calibrated']
23            camController.finish.enable()
24        }
25        
26        // Calculate center of selection
27        const center = vec3.add(vec3.create(), v1, vec3.add(vec3.create(), v2, v3))
28        vec3.scale(center, center, 1 / 3)
29
30        // Calculate normal vector and 2 orthogonal vectors
31        const normal = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), vec3.subtract(vec3.create(), v2, v1), vec3.subtract(vec3.create(), v3, v1)))
32        const u = vec3.normalize(vec3.create(), vec3.subtract(vec3.create(), v2, v1))
33        const v = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), normal, u))
34        
35        // Rotate orthogonal vectors by 45 degree along the normal
36        const rotM = mat4.fromRotation(mat4.create(), Math.PI/4, normal)
37        vec3.transformMat4(u, u, rotM)
38        vec3.transformMat4(v, v, rotM)
39
40        // Calculate 4 vertices to form a square
41        const scale = 15
42        vec3.add(v1, center, vec3.scale(vec3.create(), u, -scale))
43        vec3.add(v2, center, vec3.scale(vec3.create(), v, scale))
44        vec3.add(v3, center, vec3.scale(vec3.create(), v, -scale))
45        const v4 = vec3.add(vec3.create(), center, vec3.scale(vec3.create(), u, scale))
46
47        this.planeVertices = new Float32Array([...v1, ...v2, ...v3, ...v4])
48        this.planeNormal = normal
49        if (this.planeNormal[2] < 0) vec3.scale(this.planeNormal, this.planeNormal, -1)        
50    }
51
52    render() {
53        if (!settings.showGizmo || this.planeVertices.length === 0) return
54
55        gl.useProgram(this.program)
56
57        gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer)
58        gl.bufferData(gl.ARRAY_BUFFER, this.planeVertices, gl.DYNAMIC_DRAW)
59        
60        const positionAttributeLocation = gl.getAttribLocation(this.program, "a_pos")
61        gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0)
62
63        gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
64        gl.uniformMatrix4fv(gl.getUniformLocation(this.program, 'projmatrix'), false, cam.vpm)
65
66        const cornerCount = this.planeVertices.length / 3
67        const drawCorners = cornerCount < 4
68        gl.uniform1f(gl.getUniformLocation(this.program, 'draw_plane'), drawCorners ? 0 : 1)
69        gl.uniform1f(gl.getUniformLocation(this.program, 'aspect'), gl.canvas.width / gl.canvas.height)
70
71        if (drawCorners) {
72            gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, this.planeVertices.length / 3)
73        }
74        else {
75            gl.vertexAttribDivisor(positionAttributeLocation, 0)
76            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)
77        }        
78        
79        // Undo WebGL state changes
80        gl.blendFunc(gl.ONE_MINUS_DST_ALPHA, gl.ONE)
81        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
82        gl.bufferData(gl.ARRAY_BUFFER, positionData, gl.DYNAMIC_DRAW);
83        gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0)
84        gl.vertexAttribDivisor(positionAttributeLocation, 1)
85    }
86}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.