Spaces:
Running
Running
| import { Uint16BufferAttribute, Uint32BufferAttribute } from '../../core/BufferAttribute.js'; | |
| import { arrayMax } from '../../utils.js'; | |
| function WebGLGeometries(gl, attributes, info, bindingStates) { | |
| const geometries = {}; | |
| const wireframeAttributes = new WeakMap(); | |
| function onGeometryDispose(event) { | |
| const geometry = event.target; | |
| if (geometry.index !== null) { | |
| attributes.remove(geometry.index); | |
| } | |
| for (const name in geometry.attributes) { | |
| attributes.remove(geometry.attributes[name]); | |
| } | |
| geometry.removeEventListener('dispose', onGeometryDispose); | |
| delete geometries[geometry.id]; | |
| const attribute = wireframeAttributes.get(geometry); | |
| if (attribute) { | |
| attributes.remove(attribute); | |
| wireframeAttributes.delete(geometry); | |
| } | |
| bindingStates.releaseStatesOfGeometry(geometry); | |
| if (geometry.isInstancedBufferGeometry === true) { | |
| delete geometry._maxInstanceCount; | |
| } | |
| // | |
| info.memory.geometries--; | |
| } | |
| function get(object, geometry) { | |
| if (geometries[geometry.id] === true) return geometry; | |
| geometry.addEventListener('dispose', onGeometryDispose); | |
| geometries[geometry.id] = true; | |
| info.memory.geometries++; | |
| return geometry; | |
| } | |
| function update(geometry) { | |
| const geometryAttributes = geometry.attributes; | |
| // Updating index buffer in VAO now. See WebGLBindingStates. | |
| for (const name in geometryAttributes) { | |
| attributes.update(geometryAttributes[name], gl.ARRAY_BUFFER); | |
| } | |
| // morph targets | |
| const morphAttributes = geometry.morphAttributes; | |
| for (const name in morphAttributes) { | |
| const array = morphAttributes[name]; | |
| for (let i = 0, l = array.length; i < l; i++) { | |
| attributes.update(array[i], gl.ARRAY_BUFFER); | |
| } | |
| } | |
| } | |
| function updateWireframeAttribute(geometry) { | |
| const indices = []; | |
| const geometryIndex = geometry.index; | |
| const geometryPosition = geometry.attributes.position; | |
| let version = 0; | |
| if (geometryIndex !== null) { | |
| const array = geometryIndex.array; | |
| version = geometryIndex.version; | |
| for (let i = 0, l = array.length; i < l; i += 3) { | |
| const a = array[i + 0]; | |
| const b = array[i + 1]; | |
| const c = array[i + 2]; | |
| indices.push(a, b, b, c, c, a); | |
| } | |
| } else { | |
| const array = geometryPosition.array; | |
| version = geometryPosition.version; | |
| for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { | |
| const a = i + 0; | |
| const b = i + 1; | |
| const c = i + 2; | |
| indices.push(a, b, b, c, c, a); | |
| } | |
| } | |
| const attribute = new (arrayMax(indices) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); | |
| attribute.version = version; | |
| // Updating index buffer in VAO now. See WebGLBindingStates | |
| // | |
| const previousAttribute = wireframeAttributes.get(geometry); | |
| if (previousAttribute) attributes.remove(previousAttribute); | |
| // | |
| wireframeAttributes.set(geometry, attribute); | |
| } | |
| function getWireframeAttribute(geometry) { | |
| const currentAttribute = wireframeAttributes.get(geometry); | |
| if (currentAttribute) { | |
| const geometryIndex = geometry.index; | |
| if (geometryIndex !== null) { | |
| // if the attribute is obsolete, create a new one | |
| if (currentAttribute.version < geometryIndex.version) { | |
| updateWireframeAttribute(geometry); | |
| } | |
| } | |
| } else { | |
| updateWireframeAttribute(geometry); | |
| } | |
| return wireframeAttributes.get(geometry); | |
| } | |
| return { | |
| get: get, | |
| update: update, | |
| getWireframeAttribute: getWireframeAttribute, | |
| }; | |
| } | |
| export { WebGLGeometries }; | |