Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make BufferGeometry only contain normal buffer attributes by default #432

Merged
merged 6 commits into from
Apr 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion types/three/OTHER_FILES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,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
Expand Down Expand Up @@ -170,6 +169,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
Expand Down
23 changes: 0 additions & 23 deletions types/three/src/constants.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
43 changes: 21 additions & 22 deletions types/three/src/core/BufferGeometry.d.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
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';
import { GLBufferAttribute } from './GLBufferAttribute';

export type NormalBufferAttributes = Record<string, BufferAttribute | InterleavedBufferAttribute>;
export type NormalOrGLBufferAttributes = Record<
string,
BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute
>;

/**
* A representation of mesh, line, or point geometry
Expand Down Expand Up @@ -43,7 +47,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 NormalOrGLBufferAttributes = NormalBufferAttributes,
> extends EventDispatcher {
/**
* This creates a new {@link THREE.BufferGeometry | BufferGeometry} object.
*/
Expand Down Expand Up @@ -87,9 +93,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.
Expand Down Expand Up @@ -185,30 +189,25 @@ export class BufferGeometry extends EventDispatcher {
* @param name
* @param attribute
*/
setAttribute(
name: BuiltinShaderAttributeName | (string & {}),
attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute,
): this;
setAttribute<K extends keyof Attributes>(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<K extends keyof Attributes>(name: K): Attributes[K];

/**
* Deletes the {@link attributes | attribute} with the specified name.
* @param name
*/
deleteAttribute(name: BuiltinShaderAttributeName | (string & {})): BufferGeometry;
deleteAttribute(name: keyof Attributes): this;

/**
* 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
Expand Down
13 changes: 7 additions & 6 deletions types/three/src/objects/Points.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Material } from './../materials/Material';
import { Raycaster } from './../core/Raycaster';
import { Object3D } from './../core/Object3D';
import { BufferGeometry } from '../core/BufferGeometry';
import { Intersection } from '../core/Raycaster';
import { Material } from '../materials/Material';
import { Object3D } from '../core/Object3D';
import { BufferGeometry, NormalOrGLBufferAttributes } from '../core/BufferGeometry';
import { BufferAttribute } from '../core/BufferAttribute';
import { InterleavedBufferAttribute } from '../core/InterleavedBufferAttribute';
import { GLBufferAttribute } from '../core/GLBufferAttribute';

/**
* A class for displaying {@link Points}
Expand All @@ -12,7 +13,7 @@ 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<NormalOrGLBufferAttributes> = BufferGeometry,
TMaterial extends Material | Material[] = Material | Material[],
> extends Object3D {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
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<THREE.NormalOrGLBufferAttributes>>;

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<THREE.NormalOrGLBufferAttributes>();

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);
}
1 change: 1 addition & 0 deletions types/three/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"test/integration/three-examples/webgl2_multiple_rendertargets.ts",
"test/integration/three-examples/webgl2_rendertarget_texture2darray.ts",
"test/integration/three-examples/webgl2_volume_instancing.ts",
"test/integration/three-examples/webgl_buffergeometry_glbufferattribute.ts",
"test/integration/three-examples/webgl_buffergeometry_instancing_interleaved.ts",
"test/integration/three-examples/webgl_camera.ts",
"test/integration/three-examples/webgl_camera_array.ts",
Expand Down