import { BufferAttribute, BufferGeometry, GLBufferAttribute, InterleavedBufferAttribute, Matrix4, Vector2, Vector3 } from '../../thirdparty/three/imports'; import { BufferAttribute3D } from './BufferAttribute3D'; import { GLBufferAttribute3D } from './GLBufferAttribute3D'; import { InterleavedBufferAttribute3D } from './InterleavedBufferAttribute3D'; export class BufferGeometry3D { /** * @private */ get _geometry() { if (!this.__geometry) { this.__geometry = new BufferGeometry(); } return this.__geometry; } protected __geometry: BufferGeometry; get attributes(): { [name: string]: BufferAttribute3D | InterleavedBufferAttribute3D | GLBufferAttribute3D; } { const attributes = this._geometry.attributes; const attribute3ds: { [name: string]: BufferAttribute3D | InterleavedBufferAttribute3D | GLBufferAttribute3D; } = {}; for (const key in attributes) { const element = attributes[key]; if (element instanceof BufferAttribute) { attribute3ds[key] = BufferAttribute3D.get(element); } else if (element instanceof InterleavedBufferAttribute) { attribute3ds[key] = InterleavedBufferAttribute3D.get(element); } else { attribute3ds[key] = GLBufferAttribute3D.get(element); } } return attribute3ds; } set attributes(v) { const attributes: { [name: string]: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute; } = {}; for (const key in v) { const element = v[key]; attributes[key] = element._bufferAttribute; } this._geometry.attributes = attributes; } setAttribute(name: string, attribute: BufferAttribute3D | InterleavedBufferAttribute3D | GLBufferAttribute3D) { this._geometry.setAttribute(name, attribute._bufferAttribute); } getAttribute(name: string) { const attribute = this._geometry.getAttribute(name); let bufferAttribute3D: BufferAttribute3D | InterleavedBufferAttribute3D | GLBufferAttribute3D; if (attribute.constructor === BufferAttribute) { bufferAttribute3D = BufferAttribute3D.get(attribute); } else if (attribute.constructor === InterleavedBufferAttribute) { bufferAttribute3D = InterleavedBufferAttribute3D.get(attribute); } else if (attribute.constructor === GLBufferAttribute) { bufferAttribute3D = GLBufferAttribute3D.get(attribute); } return bufferAttribute3D; } center() { this._geometry.center(); return this; } deleteAttribute(name: string) { this._geometry.deleteAttribute(name); return this; } dispose() { this._geometry.dispose(); } rotateX(angle: number) { this._geometry.rotateX(angle); return this; } rotateY(angle: number) { this._geometry.rotateY(angle); return this; } translate(x: number, y: number, z: number) { this._geometry.translate(x, y, z); return this; } applyMatrix4(matrix: Matrix4) { this._geometry.applyMatrix4(matrix); return this; } protected _invalidate() { this.__geometry?.dispose(); this.__geometry = null; } setFromPoints(points: Vector3[] | Vector2[]) { this._geometry.setFromPoints(points); return this; } computeVertexNormals() { this._geometry.computeVertexNormals(); } scale(x: number, y: number, z: number) { this._geometry.scale(x, y, z); return this; } computeTangents() { this._geometry.computeTangents(); } computeBoundingSphere() { this._geometry.computeBoundingSphere(); } clone() { const bufferGeometry = this._geometry.clone(); const bufferGeometry3D = BufferGeometry3D.get(bufferGeometry); return bufferGeometry3D; } get boundingSphere() { return this._geometry.boundingSphere; } get boundingBox() { return this._geometry.boundingBox; } computeBoundingBox() { this._geometry.computeBoundingBox(); } static get(geometry: BufferGeometry) { let geometry3D = this._map.get(geometry) as BufferGeometry3D; if (!geometry3D) { geometry3D = new BufferGeometry3D(); geometry3D.__geometry = geometry; this._map.set(geometry, geometry3D); } return geometry3D; } protected static _map = new Map(); }