import * as THREE from 'three' import { MeshLine, MeshLineMaterial } from 'three.meshline' import oktween from '../../util/vendor/oktween' import { scene } from '../renderer' import { getLineGeometry, updateFace, lerpPoints } from './util' import { POINT_SCALE, LINE_THICKNESS, FACE_POINT_COUNT, MARKER_COLORS } from '../constants' let cubes let meshes = [] const faceBuffer = Array.from({ length: FACE_POINT_COUNT }, () => new THREE.Vector3()) let swapFrom let swapTo export function build(points) { swapTo = points const matrix = new THREE.Matrix4() const quaternion = new THREE.Quaternion() cubes = points.map((p) => { 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(MARKER_COLORS[i % MARKER_COLORS.length]), }) const line = new MeshLine() line.setGeometry(geometry, () => LINE_THICKNESS) const mesh = new THREE.Mesh(line.geometry, material) mesh.geometry.dynamic = true scene.add(mesh) return [line, mesh] }) updateFace(points, cubes, meshes) } export function swap(face) { swapFrom = swapTo swapTo = face 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, cubes, meshes) }, finished: () => { setTimeout(swap, 2000) } }) }