summaryrefslogtreecommitdiff
path: root/client/splash/face/markers.js
blob: 354ed68cea8573012341aea635044092cab1503d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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 boxColor = new THREE.Color()
  boxColor.setHex(MARKER_POINT_COLOR)

  const scaledPoints = scalePoints(points)
  swapTo = scaledPoints

  cubes = scaledPoints.map(() => {
    let position = new THREE.Vector3()
    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.clone(), quaternion, boxScale)
    geometry.applyMatrix(matrix)
    let material = new THREE.MeshBasicMaterial({
      color: boxColor,
      opacity: 1,
      transparent: true,
    })
    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]),
      alphaTest: 0.01,
      opacity: 1.0,
      transparent: true,
    })
    const line = new MeshLine()
    line.setGeometry(geometry, () => LINE_THICKNESS)
    const mesh = new THREE.Mesh(line.geometry, material)
    mesh.geometry.dynamic = true
    group.add(mesh)
    return [line, mesh]
  })
  window.meshes = meshes
  group.frustumCulled = false
  scene.add(group)

  updateFace(scaledPoints, cubes, meshes)
}

export function fadePointsTo(opacity) {
  cubes.forEach(cube => cube.material.opacity = opacity)
}
export function fadeLinesTo(opacity) {
  meshes.forEach((pair) => {
    pair[1].material.uniforms.visibility.value = opacity
    pair[1].material.uniformsNeedUpdate = true
  })
}

function scalePoints(points) {
  const bbox = getBboxForPoints(points)
  let { scale, midX, midY, midZ } = getBboxScaleAndCentroid(bbox)

  scale *= FACE_SCALE * FACE_MARKERS_SCALE

  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
  ))
  return scaledPoints
}

export function swap(points) {
  const scaledPoints = scalePoints(points)
  swapFrom = swapTo
  swapTo = scaledPoints
  return oktween.add({
    from: { n: 0 },
    to: { n: 1 },
    duration: 2000,
    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
}