import reveal from '../core/reveal' import * as THREE from 'three' import { animation, init } from './meshAnimation' import config from './config' import FeaturesToAttribute from '../worker/featuresToAttribute.worker' import Event from '../core/Event' import {clearFids} from '../core/dyWoker' const worker = new FeaturesToAttribute() const cache = reveal.cache const frustum = new THREE.Frustum(); const cameraViewProjectionMatrix = new THREE.Matrix4(); const hideMeshs = [] const $event = new Event() worker.addEventListener('message', listener) function listener(event) { $event.emit( event.data.incident, event.data.animationArray ) } const showMesh = function() { let IN_ID = 0 return function showMesh(mesh, index) { if (mesh.visible) return; let incident = 'grentAnimation' + (IN_ID++) let verticesArray = mesh.geometry.attributes.position.array; let postObj = { thing: 'grentAnimationArray', verticesBuffArrays: verticesArray, maxHeight: mesh.maxHeight, incident } worker.postMessage(postObj) $event.once(incident, animationArray => { init(mesh.geometry.attributes.position.array, mesh.maxHeight) setTimeout(() => { mesh.visible = true animation(mesh, verticesArray, animationArray, config.stepTotal) }, 300) threeLayer.renderScene() }) } }(); function hideMesh(mesh, index) { mesh.visible = false threeLayer.renderScene() } function meshStatus_() { const camera = threeLayer.getCamera(); camera.updateMatrixWorld(); camera.matrixWorldInverse.getInverse(camera.matrixWorld); cameraViewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); frustum.setFromMatrix(cameraViewProjectionMatrix); for (let url in cache) { let meshs = cache[url] if (!Array.isArray(meshs)) continue; for (let i = 0; i < meshs.length; i++) { let mesh = meshs[i] let index = hideMeshs.indexOf(mesh) let viewMesh = frustum.intersectsObject(mesh) if (viewMesh) { mesh.hideCount = 0 } else { mesh.hideCount = (mesh.hideCount || 0) + 1; } if (viewMesh && ~index) { showMesh(mesh, index) hideMeshs.splice(index, 1) } else if (!viewMesh && !~index) { if (mesh.visible && mesh.hideCount >= 30) { hideMesh(mesh, index) hideMeshs.push(mesh) } } if (mesh.hideCount > 300) { threeLayer.getScene().remove(mesh) reveal.eliminate(url); break; } } } } function meshStatus() { const camera = threeLayer.getCamera(); camera.updateMatrixWorld(); camera.matrixWorldInverse.getInverse(camera.matrixWorld); cameraViewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); frustum.setFromMatrix(cameraViewProjectionMatrix); let scene = threeLayer.getScene() let children = scene.children children.forEach(m => { if (m.type === 'Mesh') { let viewMesh = frustum.intersectsObject(m) if (!viewMesh) { scene.remove(m) m.isRemove = true clearFids(m.fids) } } }) } export default meshStatus