 Zabbix Grafana Prometheus React Three Fiber Threejs and TypeScript SocketIO and TypeScript Blender Topological Earth Sweet Home 3D Design Patterns Python Design Patterns TypeScript Course Coupon Codes
 Three.js and TypeScript Kindle Edition Paperback                Design Patterns in TypeScript Kindle Edition Paperback               Design Patterns in Python Kindle Edition Paperback               # Updating THREE.Geometry to THREE.BufferGeometry

## Description

Three r125 contained a major breaking change from previous versions.

The class THREE.Geometry was deprecated, renamed to just Geometry and moved to `/jsm/deprecated/Geometry.js`.

If you used the THREE.Geometry in any of your custom code, and you want to use THREE r125 or later, then you will need to update to use THREE.BufferGeometry.

Or add an import for `/jsm/deprecated/Geometry.js`

Since Three r125, all inbuilt geometries now derive from the `THREE.BufferGeometry` only. A BufferGeometry is a more efficient way of representing meshes since it stores the data as typed arrays. The classic `THREE.Geometry` stores its data as arrays of `THREE.Vector3` and `THREE.Color` objects. The classic `THREE.Geometry` is more intuitive to read and edit from a human perspective, but it is slower to process in the WebGL shader code within the core of Threejs. Beware that in future versions of Threejs, `THREE.BufferGeometry` may be renamed to `THREE.Geometry`.

The below examples show several use cases of THREE.Geometry and how you can update them to use THREE.BufferGeometry.

### Create a Line

The below example creates a line with 2 points.

#### THREE.Geometry

``````const geometry = new THREE.Geometry()
geometry.vertices.push(new THREE.Vector3(-5, 0, 0))
geometry.vertices.push(new THREE.Vector3(5, 0, 0))
const line = new THREE.Line(
geometry,
new THREE.LineBasicMaterial({ color: 0x888888 })
)
``````

#### THREE.BufferGeometry

``````const points = []
points.push(new THREE.Vector3(-5, 0, 0))
points.push(new THREE.Vector3(5, 0, 0))
let geometry = new THREE.BufferGeometry().setFromPoints(points)
let line = new THREE.Line(
geometry,
new THREE.LineBasicMaterial({ color: 0x888888 })
)
``````

### Explode Points

Modifying the vertices of a geometry by repositioning them outwards from the center by a factor of 2.

#### THREE.Geometry

``````const vertices = (geometry as THREE.Geometry).vertices
for (let i = 0; i < vertices.length; i++) {
vertices[i].multiplyScalar(2)
}
;(geometry as THREE.Geometry).verticesNeedUpdate = true
``````

#### THREE.BufferGeometry

``````const positions = (geometry.attributes.position as THREE.BufferAttribute)
.array as Array<number>
for (let i = 0; i < positions.length; i += 3) {
const v = new THREE.Vector3(
positions[i],
positions[i + 1],
positions[i + 2]
).multiplyScalar(2)
positions[i] = v.x
positions[i + 1] = v.y
positions[i + 2] = v.z
}
;(geometry.attributes.position as THREE.BufferAttribute).needsUpdate = true
``````

### Tetrahedron

Manually creating a tetrahedron, also known as a triangular pyramid.

#### THREE.Geometry

``````const material = new THREE.MeshNormalMaterial()
let geometry = new THREE.Geometry()
geometry.vertices.push(
new THREE.Vector3(1, 1, 1), //a
new THREE.Vector3(-1, -1, 1), //b
new THREE.Vector3(-1, 1, -1), //c
new THREE.Vector3(1, -1, -1) //d
)
geometry.faces.push(
new THREE.Face3(2, 1, 0),
new THREE.Face3(0, 3, 2),
new THREE.Face3(1, 3, 0),
new THREE.Face3(2, 3, 1)
)
geometry.computeFlatVertexNormals()
const mesh = new THREE.Mesh(geometry, material)
``````

#### THREE.BufferGeometry

``````const material = new THREE.MeshNormalMaterial()
let geometry = new THREE.BufferGeometry()
const points = [
new THREE.Vector3(-1, 1, -1), //c
new THREE.Vector3(-1, -1, 1), //b
new THREE.Vector3(1, 1, 1), //a

new THREE.Vector3(1, 1, 1), //a
new THREE.Vector3(1, -1, -1), //d
new THREE.Vector3(-1, 1, -1), //c

new THREE.Vector3(-1, -1, 1), //b
new THREE.Vector3(1, -1, -1), //d
new THREE.Vector3(1, 1, 1), //a

new THREE.Vector3(-1, 1, -1), //c
new THREE.Vector3(1, -1, -1), //d
new THREE.Vector3(-1, -1, 1), //b
]

geometry.setFromPoints(points)
geometry.computeVertexNormals()

const mesh = new THREE.Mesh(geometry, material)
``````

## Examples

### Modify a position attribute

This example demonstrates modifying one of the values in the geometries `attributes.position.array`. The modified value affects the X coordinate of the second point that was added to the tetrahedron.

#### ./src/client/client.ts

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73``` ``````import * as THREE from 'three' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' import Stats from 'three/examples/jsm/libs/stats.module' import { GUI } from 'dat.gui' const scene = new THREE.Scene() const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100 ) camera.position.set(1.6, 1.7, 2) const renderer = new THREE.WebGLRenderer() renderer.setSize(window.innerWidth, window.innerHeight) document.body.appendChild(renderer.domElement) const controls = new OrbitControls(camera, renderer.domElement) const material = new THREE.MeshNormalMaterial({ side: THREE.DoubleSide }) let geometry = new THREE.BufferGeometry() const points = [ new THREE.Vector3(-1, 1, -1), //c new THREE.Vector3(-1, -1, 1), //b new THREE.Vector3(1, 1, 1), //a new THREE.Vector3(1, 1, 1), //a new THREE.Vector3(1, -1, -1), //d new THREE.Vector3(-1, 1, -1), //c new THREE.Vector3(-1, -1, 1), //b new THREE.Vector3(1, -1, -1), //d new THREE.Vector3(1, 1, 1), //a new THREE.Vector3(-1, 1, -1), //c new THREE.Vector3(1, -1, -1), //d new THREE.Vector3(-1, -1, 1), //b ] geometry.setFromPoints(points) geometry.computeVertexNormals() const mesh = new THREE.Mesh(geometry, material) scene.add(mesh) const stats = new Stats() document.body.appendChild(stats.dom) let data = { x: 1, } const gui = new GUI() gui.add(data, 'x', -5, -1, 0.01).onChange(() => { ;((geometry.attributes.position as THREE.BufferAttribute) .array as number) = data.x geometry.attributes.position.needsUpdate = true }) gui.open() function animate() { requestAnimationFrame(animate) controls.update() render() stats.update() } function render() { renderer.render(scene, camera) } animate() ``````

### Twisted Cube

By iterating through all position attributes, you can apply a rotation and create a twisted cube.

#### ./src/client/client.ts

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90``` ``````import * as THREE from 'three' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' import Stats from 'three/examples/jsm/libs/stats.module' import { GUI } from 'dat.gui' const scene = new THREE.Scene() const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100 ) camera.position.set(0, 0.75, 1.5) const renderer = new THREE.WebGLRenderer() renderer.setSize(window.innerWidth, window.innerHeight) document.body.appendChild(renderer.domElement) const controls = new OrbitControls(camera, renderer.domElement) controls.enableDamping = true function twist(geometry: THREE.BufferGeometry, factor: number) { const q = new THREE.Quaternion() const up = new THREE.Vector3(0, 1, 0) const p = (geometry.attributes.position as THREE.BufferAttribute) .array as number[] for (let i = 0; i < p.length; i += 3) { q.setFromAxisAngle(up, p[i + 1] * factor) let vec = new THREE.Vector3(p[i], p[i + 1], p[i + 2]) vec.applyQuaternion(q) p[i] = vec.x p[i + 2] = vec.z } geometry.computeVertexNormals() geometry.attributes.position.needsUpdate = true } let geometry = new THREE.BoxGeometry(1, 1, 1, 10, 10, 10) twist(geometry, Math.PI / 2) const twistedCube = new THREE.Mesh( geometry, new THREE.MeshNormalMaterial({ wireframe: true, }) ) scene.add(twistedCube) window.addEventListener( 'resize', () => { camera.aspect = window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) }, false ) let data = { t: Math.PI / 2, } const gui = new GUI() gui.add(data, 't', -Math.PI, Math.PI, 0.01).onChange((t) => { twistedCube.geometry.dispose() geometry = new THREE.BoxGeometry(1, 1, 1, 10, 10, 10) twist(geometry, t) twistedCube.geometry = geometry }) gui.open() const stats = new Stats() document.body.appendChild(stats.dom) function animate() { requestAnimationFrame(animate) controls.update() render() stats.update() } function render() { renderer.render(scene, camera) } animate() ``````