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 };