From 08a42ebe8b2ac79f60cf3875061732e01e3a8101 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Thu, 27 Apr 2023 21:55:35 -0400 Subject: [PATCH 1/5] Default BufferGeometry to use normal attributes --- types/three/src/constants.d.ts | 23 --- types/three/src/core/BufferGeometry.d.ts | 36 ++-- types/three/src/objects/Points.d.ts | 13 +- .../test/controls/controls-pointercontrols.ts | 14 +- .../geometry-buffer-glbufferattribute.ts | 154 ++++++++++++++++++ types/three/tsconfig.json | 1 + 6 files changed, 183 insertions(+), 58 deletions(-) create mode 100644 types/three/test/geometries/geometry-buffer-glbufferattribute.ts diff --git a/types/three/src/constants.d.ts b/types/three/src/constants.d.ts index a8d0d3362..4977a8870 100644 --- a/types/three/src/constants.d.ts +++ b/types/three/src/constants.d.ts @@ -901,26 +901,3 @@ export type PixelFormatGPU = | 'DEPTH_COMPONENT32F' | 'DEPTH24_STENCIL8' | 'DEPTH32F_STENCIL8'; - -/////////////////////////////////////////////////////////////////////////////// - -export type BuiltinShaderAttributeName = - | 'position' - | 'normal' - | 'uv' - | 'color' - | 'skinIndex' - | 'skinWeight' - | 'instanceMatrix' - | 'morphTarget0' - | 'morphTarget1' - | 'morphTarget2' - | 'morphTarget3' - | 'morphTarget4' - | 'morphTarget5' - | 'morphTarget6' - | 'morphTarget7' - | 'morphNormal0' - | 'morphNormal1' - | 'morphNormal2' - | 'morphNormal3'; diff --git a/types/three/src/core/BufferGeometry.d.ts b/types/three/src/core/BufferGeometry.d.ts index 5d61bb588..589e57a75 100644 --- a/types/three/src/core/BufferGeometry.d.ts +++ b/types/three/src/core/BufferGeometry.d.ts @@ -1,15 +1,12 @@ import { BufferAttribute } from './BufferAttribute'; import { InterleavedBufferAttribute } from './InterleavedBufferAttribute'; -import { GLBufferAttribute } from './GLBufferAttribute'; -import { Box3 } from './../math/Box3'; -import { Sphere } from './../math/Sphere'; -import { Matrix4 } from './../math/Matrix4'; -import { Quaternion } from './../math/Quaternion'; -import { Vector2 } from './../math/Vector2'; -import { Vector3 } from './../math/Vector3'; +import { Box3 } from '../math/Box3'; +import { Sphere } from '../math/Sphere'; +import { Matrix4 } from '../math/Matrix4'; +import { Quaternion } from '../math/Quaternion'; +import { Vector2 } from '../math/Vector2'; +import { Vector3 } from '../math/Vector3'; import { EventDispatcher } from './EventDispatcher'; -import { BuiltinShaderAttributeName } from '../constants'; -import * as BufferGeometryUtils from '../../examples/jsm/utils/BufferGeometryUtils'; /** * A representation of mesh, line, or point geometry @@ -43,7 +40,9 @@ import * as BufferGeometryUtils from '../../examples/jsm/utils/BufferGeometryUti * @see {@link https://threejs.org/docs/index.html#api/en/core/BufferGeometry | Official Documentation} * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferGeometry.js | Source} */ -export class BufferGeometry extends EventDispatcher { +export class BufferGeometry< + Attributes extends object = Record, +> extends EventDispatcher { /** * This creates a new {@link THREE.BufferGeometry | BufferGeometry} object. */ @@ -87,9 +86,7 @@ export class BufferGeometry extends EventDispatcher { * use {@link setAttribute | .setAttribute} and {@link getAttribute | .getAttribute} to access attributes of this geometry. * @defaultValue `{}` */ - attributes: { - [name: string]: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute; // TODO Replace for 'Record<>' - }; + attributes: Attributes; /** * Hashmap of {@link THREE.BufferAttribute | BufferAttributes} holding details of the geometry's morph targets. @@ -185,30 +182,25 @@ export class BufferGeometry extends EventDispatcher { * @param name * @param attribute */ - setAttribute( - name: BuiltinShaderAttributeName | (string & {}), - attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute, - ): this; + setAttribute(name: K, attribute: Attributes[K]): this; /** * Returns the {@link attributes | attribute} with the specified name. * @param name */ - getAttribute( - name: BuiltinShaderAttributeName | (string & {}), - ): BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute; + getAttribute(name: K): Attributes[K]; /** * Deletes the {@link attributes | attribute} with the specified name. * @param name */ - deleteAttribute(name: BuiltinShaderAttributeName | (string & {})): BufferGeometry; + deleteAttribute(name: keyof Attributes): BufferGeometry; /** * Returns true if the {@link attributes | attribute} with the specified name exists. * @param name */ - hasAttribute(name: BuiltinShaderAttributeName | (string & {})): boolean; + hasAttribute(name: keyof Attributes): boolean; /** * Adds a group to this geometry diff --git a/types/three/src/objects/Points.d.ts b/types/three/src/objects/Points.d.ts index a3aff8dc9..f711f9e97 100644 --- a/types/three/src/objects/Points.d.ts +++ b/types/three/src/objects/Points.d.ts @@ -1,8 +1,9 @@ -import { Material } from './../materials/Material'; -import { Raycaster } from './../core/Raycaster'; -import { Object3D } from './../core/Object3D'; +import { Material } from '../materials/Material'; +import { Object3D } from '../core/Object3D'; import { BufferGeometry } from '../core/BufferGeometry'; -import { Intersection } from '../core/Raycaster'; +import { BufferAttribute } from '../core/BufferAttribute'; +import { InterleavedBufferAttribute } from '../core/InterleavedBufferAttribute'; +import { GLBufferAttribute } from '../core/GLBufferAttribute'; /** * A class for displaying {@link Points} @@ -12,7 +13,9 @@ import { Intersection } from '../core/Raycaster'; * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Points.js | Source} */ export class Points< - TGeometry extends BufferGeometry = BufferGeometry, + TGeometry extends BufferGeometry< + Record + > = BufferGeometry, TMaterial extends Material | Material[] = Material | Material[], > extends Object3D { /** diff --git a/types/three/test/controls/controls-pointercontrols.ts b/types/three/test/controls/controls-pointercontrols.ts index f14f41c45..f72b3c3c3 100644 --- a/types/three/test/controls/controls-pointercontrols.ts +++ b/types/three/test/controls/controls-pointercontrols.ts @@ -126,16 +126,14 @@ function init() { let position = floorGeometry.attributes.position; - if (!(position instanceof THREE.GLBufferAttribute)) { - for (let i = 0, l = position.count; i < l; i++) { - vertex.fromBufferAttribute(position, i); + for (let i = 0, l = position.count; i < l; i++) { + vertex.fromBufferAttribute(position, i); - vertex.x += Math.random() * 20 - 10; - vertex.y += Math.random() * 2; - vertex.z += Math.random() * 20 - 10; + vertex.x += Math.random() * 20 - 10; + vertex.y += Math.random() * 2; + vertex.z += Math.random() * 20 - 10; - position.setXYZ(i, vertex.x, vertex.y, vertex.z); - } + position.setXYZ(i, vertex.x, vertex.y, vertex.z); } const indexedGeometry = floorGeometry.toNonIndexed(); // ensure each face has unique vertices diff --git a/types/three/test/geometries/geometry-buffer-glbufferattribute.ts b/types/three/test/geometries/geometry-buffer-glbufferattribute.ts new file mode 100644 index 000000000..abde122e5 --- /dev/null +++ b/types/three/test/geometries/geometry-buffer-glbufferattribute.ts @@ -0,0 +1,154 @@ +import * as THREE from 'three'; + +import * as Stats from 'three/examples/jsm/libs/stats.module.js'; + +let container: HTMLElement; +let stats: Stats; + +let camera: THREE.PerspectiveCamera; +let scene: THREE.Scene; +let renderer: THREE.WebGLRenderer; + +let points: THREE.Points< + THREE.BufferGeometry< + Record + > +>; + +const particles = 300000; +let drawCount = 10000; + +init(); +animate(); + +function init() { + container = document.getElementById('container')!; + + // + + renderer = new THREE.WebGLRenderer({ antialias: false }); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(window.innerWidth, window.innerHeight); + + container.appendChild(renderer.domElement); + + // + + camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 5, 3500); + camera.position.z = 2750; + + scene = new THREE.Scene(); + scene.background = new THREE.Color(0x050505); + scene.fog = new THREE.Fog(0x050505, 2000, 3500); + + // + + const geometry = new THREE.BufferGeometry< + Record + >(); + + const positions = []; + const positions2 = []; + const colors = []; + + const color = new THREE.Color(); + + const n = 1000; + const n2 = n / 2; // particles spread in the cube + + for (let i = 0; i < particles; i++) { + // positions + + const x = Math.random() * n - n2; + const y = Math.random() * n - n2; + const z = Math.random() * n - n2; + + positions.push(x, y, z); + positions2.push(z * 0.3, x * 0.3, y * 0.3); + + // colors + + const vx = x / n + 0.5; + const vy = y / n + 0.5; + const vz = z / n + 0.5; + + color.setRGB(vx, vy, vz); + + colors.push(color.r, color.g, color.b); + } + + const gl = renderer.getContext(); + + const pos = gl.createBuffer()!; + gl.bindBuffer(gl.ARRAY_BUFFER, pos); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); + + const pos2 = gl.createBuffer()!; + gl.bindBuffer(gl.ARRAY_BUFFER, pos2); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions2), gl.STATIC_DRAW); + + const rgb = gl.createBuffer()!; + gl.bindBuffer(gl.ARRAY_BUFFER, rgb); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); + + const posAttr1 = new THREE.GLBufferAttribute(pos, gl.FLOAT, 3, 4, particles); + const posAttr2 = new THREE.GLBufferAttribute(pos2, gl.FLOAT, 3, 4, particles); + geometry.setAttribute('position', posAttr1); + + setInterval(() => { + const attr = geometry.getAttribute('position'); + + geometry.setAttribute('position', attr === posAttr1 ? posAttr2 : posAttr1); + }, 2000); + + geometry.setAttribute('color', new THREE.GLBufferAttribute(rgb, gl.FLOAT, 3, 4, particles)); + + // + + const material = new THREE.PointsMaterial({ size: 15, vertexColors: true }); + + points = new THREE.Points(geometry, material); + + // Choose one: + // geometry.boundingSphere = ( new THREE.Sphere() ).set( new THREE.Vector3(), Infinity ); + points.frustumCulled = false; + + scene.add(points); + + // + + stats = new Stats(); + container.appendChild(stats.dom); + + // + + window.addEventListener('resize', onWindowResize); +} + +function onWindowResize() { + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + + renderer.setSize(window.innerWidth, window.innerHeight); +} + +// + +function animate() { + requestAnimationFrame(animate); + + render(); + stats.update(); +} + +function render() { + drawCount = (Math.max(5000, drawCount) + Math.floor(500 * Math.random())) % particles; + points.geometry.setDrawRange(0, drawCount); + + const time = Date.now() * 0.001; + + points.rotation.x = time * 0.1; + points.rotation.y = time * 0.2; + + renderer.render(scene, camera); +} diff --git a/types/three/tsconfig.json b/types/three/tsconfig.json index 9c8fcd6db..eb0bc9294 100644 --- a/types/three/tsconfig.json +++ b/types/three/tsconfig.json @@ -29,6 +29,7 @@ "test/core/uniform.ts", "test/extra/Earcut.ts", "test/geometries/geometry-buffer.ts", + "test/geometries/geometry-buffer-glbufferattribute.ts", "test/geometries/geometry-cube.ts", "test/geometries/geometry-parametric.ts", "test/geometries/geometry-shapes.ts", From a7afc0975addcbcd6c45ac2ee619f3126bbc8a08 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Thu, 27 Apr 2023 22:13:09 -0400 Subject: [PATCH 2/5] Named types --- types/three/src/core/BufferGeometry.d.ts | 13 +++++++++---- types/three/src/objects/Points.d.ts | 6 ++---- .../geometries/geometry-buffer-glbufferattribute.ts | 10 ++-------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/types/three/src/core/BufferGeometry.d.ts b/types/three/src/core/BufferGeometry.d.ts index 589e57a75..e4192f70a 100644 --- a/types/three/src/core/BufferGeometry.d.ts +++ b/types/three/src/core/BufferGeometry.d.ts @@ -7,6 +7,13 @@ import { Quaternion } from '../math/Quaternion'; import { Vector2 } from '../math/Vector2'; import { Vector3 } from '../math/Vector3'; import { EventDispatcher } from './EventDispatcher'; +import { GLBufferAttribute } from './GLBufferAttribute'; + +export type NormalBufferAttributes = Record; +export type NormalOrGLBufferAttributes = Record< + string, + BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute +>; /** * A representation of mesh, line, or point geometry @@ -40,9 +47,7 @@ import { EventDispatcher } from './EventDispatcher'; * @see {@link https://threejs.org/docs/index.html#api/en/core/BufferGeometry | Official Documentation} * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferGeometry.js | Source} */ -export class BufferGeometry< - Attributes extends object = Record, -> extends EventDispatcher { +export class BufferGeometry extends EventDispatcher { /** * This creates a new {@link THREE.BufferGeometry | BufferGeometry} object. */ @@ -194,7 +199,7 @@ export class BufferGeometry< * Deletes the {@link attributes | attribute} with the specified name. * @param name */ - deleteAttribute(name: keyof Attributes): BufferGeometry; + deleteAttribute(name: keyof Attributes): this; /** * Returns true if the {@link attributes | attribute} with the specified name exists. diff --git a/types/three/src/objects/Points.d.ts b/types/three/src/objects/Points.d.ts index f711f9e97..3abdb51ad 100644 --- a/types/three/src/objects/Points.d.ts +++ b/types/three/src/objects/Points.d.ts @@ -1,6 +1,6 @@ import { Material } from '../materials/Material'; import { Object3D } from '../core/Object3D'; -import { BufferGeometry } from '../core/BufferGeometry'; +import { BufferGeometry, NormalOrGLBufferAttributes } from '../core/BufferGeometry'; import { BufferAttribute } from '../core/BufferAttribute'; import { InterleavedBufferAttribute } from '../core/InterleavedBufferAttribute'; import { GLBufferAttribute } from '../core/GLBufferAttribute'; @@ -13,9 +13,7 @@ import { GLBufferAttribute } from '../core/GLBufferAttribute'; * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Points.js | Source} */ export class Points< - TGeometry extends BufferGeometry< - Record - > = BufferGeometry, + TGeometry extends BufferGeometry = BufferGeometry, TMaterial extends Material | Material[] = Material | Material[], > extends Object3D { /** diff --git a/types/three/test/geometries/geometry-buffer-glbufferattribute.ts b/types/three/test/geometries/geometry-buffer-glbufferattribute.ts index abde122e5..29addcf8a 100644 --- a/types/three/test/geometries/geometry-buffer-glbufferattribute.ts +++ b/types/three/test/geometries/geometry-buffer-glbufferattribute.ts @@ -9,11 +9,7 @@ let camera: THREE.PerspectiveCamera; let scene: THREE.Scene; let renderer: THREE.WebGLRenderer; -let points: THREE.Points< - THREE.BufferGeometry< - Record - > ->; +let points: THREE.Points>; const particles = 300000; let drawCount = 10000; @@ -43,9 +39,7 @@ function init() { // - const geometry = new THREE.BufferGeometry< - Record - >(); + const geometry = new THREE.BufferGeometry(); const positions = []; const positions2 = []; From eb81d3f9acf5f28fcfdeb8e2fa8690fa63a4aabe Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Thu, 27 Apr 2023 22:18:10 -0400 Subject: [PATCH 3/5] Fix --- types/three/OTHER_FILES.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/types/three/OTHER_FILES.txt b/types/three/OTHER_FILES.txt index 966b7596a..cb066b3fc 100644 --- a/types/three/OTHER_FILES.txt +++ b/types/three/OTHER_FILES.txt @@ -35,7 +35,6 @@ examples/jsm/helpers/VertexNormalsHelper.d.ts examples/jsm/helpers/VertexTangentsHelper.d.ts examples/jsm/interactive/HTMLMesh.d.ts examples/jsm/interactive/InteractiveGroup.d.ts -examples/jsm/libs/stats.module.d.ts examples/jsm/lights/LightProbeGenerator.d.ts examples/jsm/lines/Wireframe.d.ts examples/jsm/lines/WireframeGeometry2.d.ts From 5735022f15c5cbd50e3a6241b6e697e614267cd4 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Thu, 27 Apr 2023 22:24:16 -0400 Subject: [PATCH 4/5] Stricter base --- types/three/src/core/BufferGeometry.d.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/types/three/src/core/BufferGeometry.d.ts b/types/three/src/core/BufferGeometry.d.ts index e4192f70a..426739b18 100644 --- a/types/three/src/core/BufferGeometry.d.ts +++ b/types/three/src/core/BufferGeometry.d.ts @@ -47,7 +47,9 @@ export type NormalOrGLBufferAttributes = Record< * @see {@link https://threejs.org/docs/index.html#api/en/core/BufferGeometry | Official Documentation} * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferGeometry.js | Source} */ -export class BufferGeometry extends EventDispatcher { +export class BufferGeometry< + Attributes extends NormalOrGLBufferAttributes = NormalBufferAttributes, +> extends EventDispatcher { /** * This creates a new {@link THREE.BufferGeometry | BufferGeometry} object. */ From 443b62ee24b1dbcba759f2f0808be8d761b38f3b Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Thu, 27 Apr 2023 22:25:03 -0400 Subject: [PATCH 5/5] Update OTHER_FILES --- types/three/OTHER_FILES.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/types/three/OTHER_FILES.txt b/types/three/OTHER_FILES.txt index cb066b3fc..1ef4f5b55 100644 --- a/types/three/OTHER_FILES.txt +++ b/types/three/OTHER_FILES.txt @@ -168,6 +168,7 @@ examples/jsm/shaders/VerticalTiltShiftShader.d.ts examples/jsm/shaders/VignetteShader.d.ts examples/jsm/shaders/VolumeShader.d.ts examples/jsm/shaders/WaterRefractionShader.d.ts +examples/jsm/utils/BufferGeometryUtils.d.ts examples/jsm/utils/GeometryCompressionUtils.d.ts examples/jsm/utils/PackedPhongMaterial.d.ts examples/jsm/utils/SceneUtils.d.ts