import * as THREE from 'three' import { MeshLine, MeshLineMaterial } from 'three.meshline' import oktween from '../../util/vendor/oktween' import { scene } from '../renderer' import { getLineGeometry, updateLineGeometry, lerpPoints, updateCubeGeometry, getBounds } from './geometry' const POINT_SCALE = 1.8 const FACE_POINT_COUNT = 68 let cubes let meshes = [] const faceBuffer = Array.from({ length: FACE_POINT_COUNT }, () => new THREE.Vector3()) let colors = [ 0xff3333, 0xff8833, 0xffff33, 0x338833, 0x3388ff, 0x3333ff, 0x8833ff, 0xff3388, 0xffffff, ] let swapFrom let swapTo export function build(points) { swapFrom = points swapTo = points const matrix = new THREE.Matrix4() const quaternion = new THREE.Quaternion() cubes = points.map((p, i) => { let geometry = new THREE.BoxBufferGeometry() let position = new THREE.Vector3(p[0], p[1], p[2]) let rotation = new THREE.Euler() let scale = new THREE.Vector3() let color = new THREE.Color() scale.x = POINT_SCALE scale.y = POINT_SCALE scale.z = POINT_SCALE quaternion.setFromEuler(rotation, false) matrix.compose(position, quaternion, scale) geometry.applyMatrix(matrix) let material = new THREE.MeshBasicMaterial({ color: color.setHex(0xffffff) }) let cube = new THREE.Mesh(geometry, material) scene.add(cube) return cube }) meshes = getLineGeometry(points).map((geometry, i) => { const color = new THREE.Color() const material = new MeshLineMaterial({ color: color.setHex(colors[i % colors.length]), }) const line = new MeshLine() line.setGeometry(geometry, _ => 1.5) const mesh = new THREE.Mesh(line.geometry, material) mesh.geometry.dynamic = true scene.add(mesh) return [line, mesh] }) } export function swap() { oktween.add({ from: { n: 0 }, to: { n: 1 }, duration: 1000, easing: oktween.easing.quad_in_out, update: (obj) => { lerpPoints(obj.n, swapFrom, swapTo, faceBuffer) updateFace(faceBuffer) }, finished: () => { setTimeout(swap, 2000) } }) } export function updateFace(buf) { updateCubeGeometry(buf, cubes) updateLineGeometry(buf, meshes) } function recenter(obj) { const bounds = getBounds(obj) const x_width = (bounds[1] - bounds[0]) / 2 const y_width = (bounds[3] - bounds[2]) / -3 const z_width = (bounds[5] - bounds[4]) / 2 return obj.map(p => { p[0] = p[0] - bounds[0] - x_width p[1] = -p[1] + bounds[1] + y_width p[2] = p[2] - bounds[2] + z_width return new THREE.Vector3(p[0], p[1], p[2]) }) }