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, getBboxForPoints, getBboxScaleAndCentroid } from './util' import { POINT_SCALE, LINE_THICKNESS, FACE_POINT_COUNT, MARKER_COLORS, MARKER_POINT_COLOR, FACE_SCALE, FACE_MARKERS_SCALE, FACE_OFFSET_X, FACE_OFFSET_Y, FACE_OFFSET_Z, } from '../constants' const faceBuffer = Array.from({ length: FACE_POINT_COUNT }, () => new THREE.Vector3()) let group = new THREE.Object3D() let cubes let meshes let swapFrom let swapTo export function build(points) { swapTo = points const matrix = new THREE.Matrix4() const quaternion = new THREE.Quaternion() const bbox = getBboxForPoints(points) let { scale, midX, midY, midZ } = getBboxScaleAndCentroid(bbox) scale /= 2 scale *= FACE_SCALE * FACE_MARKERS_SCALE const boxColor = new THREE.Color() boxColor.setHex(MARKER_POINT_COLOR) const scaledPoints = points.map((p) => new THREE.Vector3( (p[0] - midX) * scale + FACE_OFFSET_X, (p[1] - midY) * scale * -1 + FACE_OFFSET_Y, (p[2] - midZ) * scale + FACE_OFFSET_Z )) cubes = scaledPoints.map((position) => { let geometry = new THREE.BoxBufferGeometry() let rotation = new THREE.Euler() let boxScale = new THREE.Vector3() boxScale.x = POINT_SCALE boxScale.y = POINT_SCALE boxScale.z = POINT_SCALE quaternion.setFromEuler(rotation, false) matrix.compose(position, quaternion, boxScale) geometry.applyMatrix(matrix) let material = new THREE.MeshBasicMaterial({ color: boxColor }) let cube = new THREE.Mesh(geometry, material) group.add(cube) return cube }) meshes = getLineGeometry(scaledPoints).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 mesh.scale.x = 2 mesh.scale.y = 2 mesh.scale.z = 2 group.add(mesh) return [line, mesh] }) group.frustumCulled = false scene.add(group) updateFace(scaledPoints, 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) } }) } export function update() { // group.rotation.y += 0.005 }