summaryrefslogtreecommitdiff
path: root/client/splash/face/util.js
blob: 38b1e3760bd58176411de00e73078124e75b22ff (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
import { Geometry } from 'three'
import { LINE_THICKNESS } from '../constants'

export function getLineGeometry(points) {
  return [
    points.slice(0, 17),
    points.slice(17, 22),
    points.slice(22, 27),
    points.slice(27, 31),
    points.slice(31, 36),
    points.slice(36, 42),
    points.slice(42, 48),
    points.slice(48)
  ].map((a, i) => {
    const geometry = new Geometry()
    a.forEach(p => geometry.vertices.push(p))
    if (i > 4) {
      geometry.vertices.push(a[0])
    }
    return geometry
  })
}

export function updateFace(buf, cubes, meshes) {
  updateCubeGeometry(buf, cubes)
  updateLineGeometry(buf, meshes)
}

export function updateLineGeometry(points, meshes) {
  getLineGeometry(points).forEach((geometry, i) => {
    const [line, mesh] = meshes[i]
    line.setGeometry(geometry, () => LINE_THICKNESS)
    mesh.geometry.vertices = line.geometry.vertices
    mesh.geometry.verticesNeedUpdate = true
  })
}

export function updateCubeGeometry(points, cubes) {
  cubes.forEach((cube, i) => {
    const p = points[i]
    cube.position.set(p.x, p.y, p.z)
  })
}

export function lerp(n, a, b) {
  return (b - a) * n + a
}

export function lerpPoint(n, A, B, C) {
  C.x = lerp(n, A.x, B.x)
  C.y = lerp(n, A.y, B.y)
  C.z = lerp(n, A.z, B.z)
}

export function lerpPoints(n, A, B, C) {
  for (let i = 0, len = A.length; i < len; i++) {
    lerpPoint(n, A[i], B[i], C[i])
  }
}

export function getBboxForPoints(points) {
  return points.reduce((a, p) => {
    a.min.x = Math.min(a.min.x, p[0])
    a.max.x = Math.max(a.max.x, p[0])
    a.min.y = Math.min(a.min.y, p[1])
    a.max.y = Math.max(a.max.y, p[1])
    a.min.z = Math.min(a.min.z, p[2])
    a.max.z = Math.max(a.max.z, p[2])
    return a
  }, {
    min: { x: Infinity, y: Infinity, z: Infinity },
    max: { x: -Infinity, y: -Infinity, z: -Infinity }
  })
}

export function getBboxScaleAndCentroid(bbox, position) {
  if (position && position.isQuantized) {
    // If the geometry is quantized, transform the bounding box to the dequantized
    // coordinates.
    const normConstant = position.maxRange / (1 << position.numQuantizationBits)
    const minPos = position.minValues
    bbox.max.x = minPos[0] + bbox.max.x * normConstant
    bbox.max.y = minPos[1] + bbox.max.y * normConstant
    bbox.max.z = minPos[2] + bbox.max.z * normConstant
    bbox.min.x = minPos[0] + bbox.min.x * normConstant
    bbox.min.y = minPos[1] + bbox.min.y * normConstant
    bbox.min.z = minPos[2] + bbox.min.z * normConstant
  }
  const sizeX = bbox.max.x - bbox.min.x
  const sizeY = bbox.max.y - bbox.min.y
  const sizeZ = bbox.max.z - bbox.min.z
  const diagonalSize = Math.sqrt(sizeX * sizeX + sizeY * sizeY + sizeZ * sizeZ)
  const scale = 1.0 / diagonalSize
  const midX = (bbox.min.x + bbox.max.x) / 2
  const midY = (bbox.min.y + bbox.max.y) / 2
  const midZ = (bbox.min.z + bbox.max.z) / 2
  return { scale, midX, midY, midZ }
}