| 1 | import * as THREE from "three"; |
| 2 | |
| 3 | export class BufferManager { |
| 4 | /** Buffer increment when geometry size is exceeded, multiple of 3. */ |
| 5 | bufferIncrease = 300; |
| 6 | |
| 7 | /** |
| 8 | * The maximum capacity of the buffers. If exceeded by the {@link size}, |
| 9 | * the buffers will be rescaled. |
| 10 | */ |
| 11 | capacity = 0; |
| 12 | |
| 13 | /** The current size of the buffers. */ |
| 14 | get size() { |
| 15 | const firstAttribute = this.attributes[0]; |
| 16 | return firstAttribute.count * 3; |
| 17 | } |
| 18 | |
| 19 | get attributes() { |
| 20 | return Object.values(this.geometry.attributes) as THREE.BufferAttribute[]; |
| 21 | } |
| 22 | |
| 23 | constructor(public geometry: THREE.BufferGeometry) {} |
| 24 | |
| 25 | addAttribute(attribute: THREE.BufferAttribute) { |
| 26 | this.geometry.setAttribute(attribute.name, attribute); |
| 27 | } |
| 28 | |
| 29 | resetAttributes() { |
| 30 | for (const attribute of this.attributes) { |
| 31 | this.createAttribute(attribute.name); |
| 32 | } |
| 33 | this.capacity = 0; |
| 34 | } |
| 35 | |
| 36 | createAttribute(name: string) { |
| 37 | if (this.geometry.hasAttribute(name)) { |
| 38 | this.geometry.deleteAttribute(name); |
| 39 | } |
| 40 | const attribute = new THREE.BufferAttribute(new Float32Array(0), 3); |
| 41 | attribute.name = name; |
| 42 | this.geometry.setAttribute(name, attribute); |
| 43 | } |
| 44 | |
| 45 | resizeIfNeeded(increase: number) { |
| 46 | const newSize = this.size + increase * 3; |
| 47 | const difference = newSize - this.capacity; |
| 48 | if (difference >= 0) { |
| 49 | const increase = Math.max(difference, this.bufferIncrease); |
| 50 | const oldCapacity = this.capacity; |
| 51 | this.capacity += increase; |
| 52 | for (const attribute of this.attributes) { |
| 53 | this.resizeBuffers(attribute, oldCapacity); |
| 54 | } |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | private resizeBuffers(attribute: THREE.BufferAttribute, oldCapacity: number) { |
| 59 | this.geometry.deleteAttribute(attribute.name); |
| 60 | const array = new Float32Array(this.capacity); |
nothing calls this directly
no outgoing calls
no test coverage detected