aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/viewer/js/lines.js
blob: f29fe1f6717cb181780c3240260058e5aa05b778 (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
// lines.js — named groups of 1-px line segments in a three.js scene
import * as THREE from 'three';

export class LineSet {
  constructor(scene) {
    this.scene = scene;
    this.objects = new Map();
  }

  set(id, positions, color, origin = null) {   // origin: positions are relative to it (float precision near the ground)
    this.remove(id);
    if (!positions.length) return;
    const geom = new THREE.BufferGeometry();
    geom.setAttribute('position', new THREE.BufferAttribute(positions, 3));
    const obj = new THREE.LineSegments(geom, new THREE.LineBasicMaterial({ color, transparent: true, opacity: 0.85,
      depthTest: this.depthTest ?? true, clippingPlanes: this.clip ?? null }));
    obj.scale.setScalar(this.scale ?? 1);
    if (origin) obj.position.set(origin[0], origin[1], origin[2]);
    this.objects.set(id, obj);
    this.scene.add(obj);
  }

  setClip(planes) {   // shared THREE.Plane objects: callers move them, every line follows
    this.clip = planes;
    for (const o of this.objects.values()) o.material.clippingPlanes = planes;
  }

  setTransform(scale, depthTest) {   // globe: hug the ground when zoomed in and draw on top of tiles
    this.scale = scale;
    this.depthTest = depthTest;
    for (const o of this.objects.values()) {
      o.scale.setScalar(scale);
      o.material.depthTest = depthTest;
    }
  }

  remove(id) {
    const obj = this.objects.get(id);
    if (!obj) return;
    this.scene.remove(obj);
    obj.geometry.dispose();
    obj.material.dispose();
    this.objects.delete(id);
  }
}