@jdultra/threedtiles 3.2.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,11 @@
2
2
 
3
3
  3DTiles viewer for three.js
4
4
 
5
- demo : https://ebeaufay.github.io/ThreedTilesViewer.github.io/
5
+ Photogrametry : https://ebeaufay.github.io/ThreedTilesViewer.github.io/
6
+
7
+ IFC : https://storage.googleapis.com/jdultra.com/ifc/index.html
8
+
9
+ Occlusion culling : https://storage.googleapis.com/jdultra.com/occlusionCulling/index.html
6
10
 
7
11
  Adding a tileset to a scene is as easy as :
8
12
 
@@ -114,6 +118,11 @@ ogc3DTile.rotateOnAxis(new THREE.Vector3(1,0,0), -Math.PI*0.5);
114
118
  ...
115
119
  ```
116
120
 
121
+ ### Occlusion culling
122
+ Occlusion culling is curently only available as a demo.
123
+ The reason is that it requires a specific render pass hence the setup is a little more complex.
124
+ I can expose this feature upon request.
125
+
117
126
  # Displaying meshes on a globe
118
127
  I'm working on this project in parallel https://github.com/ebeaufay/UltraGlobe which allows displaying a globe with multi resolution imagery, elevation and 3DTiles.
119
128
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jdultra/threedtiles",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "An OGC 3DTiles viewer for Three.js",
5
5
  "main": "tileset.js",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -22,8 +22,10 @@ animate();
22
22
  function initScene() {
23
23
  const scene = new THREE.Scene();
24
24
  scene.background = new THREE.Color(0xaaffcc);
25
- scene.add(new THREE.AmbientLight(0xFFFFFF, 0.5));
26
- const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
25
+ scene.add(new THREE.AmbientLight(0xFFFFFF, 0.2));
26
+ const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.8 );
27
+ directionalLight.position.set(100,100,100)
28
+ directionalLight.lookAt(-1,-1,-1)
27
29
  scene.add( directionalLight );
28
30
  return scene;
29
31
  }
@@ -71,8 +73,8 @@ function initStats(dom) {
71
73
 
72
74
 
73
75
  function initCamera() {
74
- const camera = new THREE.PerspectiveCamera(70, window.offsetWidth / window.offsetHeight, 1, 10000);
75
- camera.position.set(20, 10, 20);
76
+ const camera = new THREE.PerspectiveCamera(70, window.offsetWidth / window.offsetHeight, 0.1, 1000);
77
+ camera.position.set(-10, 5, 20);
76
78
 
77
79
  return camera;
78
80
  }
@@ -80,29 +82,26 @@ function initCamera() {
80
82
  function initTileset(scene) {
81
83
 
82
84
  const ogc3DTile = new OGC3DTile({
83
- url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tiledWithSkirts/tileset.json",
85
+ url: "https://storage.googleapis.com/ogc-3d-tiles/house3/tileset.json",
84
86
  //url: "http://localhost:8080/tileset.json",
85
- geometricErrorMultiplier: 1.0,
86
- loadOutsideView: true,
87
+ geometricErrorMultiplier: 1,
88
+ loadOutsideView: false,
87
89
  tileLoader: new TileLoader(mesh => {
88
90
  //// Insert code to be called on every newly decoded mesh e.g.:
89
- //mesh.material.wireframe = true;
91
+ mesh.material.wireframe = false;
90
92
  //mesh.material = new THREE.MeshBasicMaterial({color:new THREE.Color("rgb("+Math.floor(Math.random()*256)+", "+Math.floor(Math.random()*256)+", "+Math.floor(Math.random()*256)+")")})
91
93
  mesh.material.side = THREE.DoubleSide;
92
- }, 1000),
93
- onLoadCallback: tileset => {
94
- console.log(tileset.json)
95
- }
94
+ }, 1000)
96
95
  });
97
96
 
98
97
 
99
98
 
100
99
  //// The OGC3DTile object is a threejs Object3D so you may do all the usual opperations like transformations e.g.:
101
- //ogc3DTile.translateOnAxis(new THREE.Vector3(0,1,0), -10)
102
- //ogc3DTile.translateOnAxis(new THREE.Vector3(1,0,0), -65)
103
- //ogc3DTile.translateOnAxis(new THREE.Vector3(0,0,1), -80)
104
- ogc3DTile.scale.set(1,1,1);
105
- //ogc3DTile.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI * 0.5) // Z-UP to Y-UP
100
+ // ogc3DTile.translateOnAxis(new THREE.Vector3(1,0,0), -2177749.59059337)
101
+ // ogc3DTile.translateOnAxis(new THREE.Vector3(0,1,0), 4388730.67973434)
102
+ // ogc3DTile.translateOnAxis(new THREE.Vector3(0,0,1), 4070064.60934734)
103
+ //ogc3DTile.scale.set(0.001,0.001,0.001);
104
+ ogc3DTile.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI * -0.5) // Z-UP to Y-UP
106
105
  // ogc3DTile.translateOnAxis(new THREE.Vector3(1,0,0), -16.5)
107
106
  // ogc3DTile.translateOnAxis(new THREE.Vector3(0,1,0), 0)
108
107
  // ogc3DTile.translateOnAxis(new THREE.Vector3(0,0,1), -9.5)
@@ -2,9 +2,7 @@ import * as THREE from 'three';
2
2
  import { OBB } from "../geometry/obb";
3
3
  import { TileLoader } from "./TileLoader";
4
4
  import { v4 as uuidv4 } from "uuid";
5
- import { setIntervalAsync } from 'set-interval-async/dynamic';
6
- // import { clearIntervalAsync } from 'set-interval-async';
7
- const path = require('path');
5
+ import * as path from "path-browserify"
8
6
 
9
7
  const tempSphere = new THREE.Sphere(new THREE.Vector3(0, 0, 0, 1));
10
8
 
@@ -185,24 +183,6 @@ class OGC3DTile extends THREE.Object3D {
185
183
  self.hasUnloadedJSONContent = false;
186
184
  });
187
185
 
188
- /* self.controller = new AbortController();
189
- setTimeout(() => {
190
- fetch(url, { signal: self.controller.signal }).then(result => {
191
- if (!result.ok) {
192
- throw new Error(`couldn't load "${properties.url}". Request failed with status ${result.status} : ${result.statusText}`);
193
- }
194
- result.json().then(json => {
195
- // when json content is downloaded, it is inserted into this tile's original JSON as a child
196
- // and the content object is deleted from the original JSON
197
- if (!self.json.children) self.json.children = [];
198
- json.rootPath = path.dirname(url);
199
- self.json.children.push(json);
200
- delete self.json.content;
201
- self.hasUnloadedJSONContent = false;
202
- }).catch(error => { });
203
- }).catch(error => { });
204
- }, 0); */
205
-
206
186
  }
207
187
 
208
188
  }
@@ -321,10 +301,9 @@ class OGC3DTile extends THREE.Object3D {
321
301
  return;
322
302
  }
323
303
  if (metric >= self.geometricError) {
324
- if (self.isReady()) {
325
- self.disposeChildren();
326
- return;
327
- }
304
+ self.disposeChildren();
305
+ updateNodeVisibility();
306
+ return;
328
307
  }
329
308
 
330
309
  }
@@ -458,7 +437,7 @@ class OGC3DTile extends THREE.Object3D {
458
437
  return 0;
459
438
  }
460
439
  const scale = this.matrixWorld.getMaxScaleOnAxis();
461
- return ((distance / 100) / this.geometricErrorMultiplier) / scale;
440
+ return ((distance / 100) / this.geometricErrorMultiplier) * scale;
462
441
  } else if (this.boundingVolume instanceof THREE.Box3) {
463
442
  // Region
464
443
  // Region not supported
@@ -12,17 +12,19 @@ function scheduleDownload(f) {
12
12
  downloads.unshift(f);
13
13
  }
14
14
  function download() {
15
- if(concurentDownloads<10){
16
- if (nextDownloads.length == 0) {
17
- getNextDownloads();
18
- if (nextDownloads.length == 0) return;
19
- }
15
+ if (nextDownloads.length == 0) {
16
+ getNextDownloads();
17
+ if (nextDownloads.length == 0) return;
18
+ }
19
+ while (nextDownloads.length > 0 && concurentDownloads < 500) {
20
20
  const nextDownload = nextDownloads.shift();
21
21
  if (!!nextDownload && nextDownload.shouldDoDownload()) {
22
22
  nextDownload.doDownload();
23
23
  }
24
24
  }
25
-
25
+
26
+
27
+
26
28
  return;
27
29
  }
28
30
  function meshReceived(cache, register, key, distanceFunction, getSiblings, level, uuid) {
@@ -60,11 +62,11 @@ function getNextDownloads() {
60
62
  downloads.splice(i, 1);
61
63
  continue;
62
64
  }
63
- if(!downloads[i].distanceFunction){ // if no distance function, must be a json, give absolute priority!
65
+ if (!downloads[i].distanceFunction) { // if no distance function, must be a json, give absolute priority!
64
66
  nextDownloads.push(downloads.splice(i, 1)[0]);
65
67
  }
66
68
  }
67
- if(nextDownloads.length>0) return;
69
+ if (nextDownloads.length > 0) return;
68
70
  for (let i = downloads.length - 1; i >= 0; i--) {
69
71
  const dist = downloads[i].distanceFunction();
70
72
  if (dist < smallestDistance) {
@@ -92,12 +94,12 @@ function getNextReady() {
92
94
  let smallestDistance = Number.MAX_VALUE;
93
95
  let closest = -1;
94
96
  for (let i = ready.length - 1; i >= 0; i--) {
95
-
96
- if(!ready[i][3]){// if no distance function, must be a json, give absolute priority!
97
- nextReady.push(ready.splice(i,1)[0]);
97
+
98
+ if (!ready[i][3]) {// if no distance function, must be a json, give absolute priority!
99
+ nextReady.push(ready.splice(i, 1)[0]);
98
100
  }
99
101
  }
100
- if(nextReady.length>0) return;
102
+ if (nextReady.length > 0) return;
101
103
  for (let i = ready.length - 1; i >= 0; i--) {
102
104
  const dist = ready[i][3]();
103
105
  if (dist < smallestDistance) {
@@ -120,23 +122,23 @@ function getNextReady() {
120
122
  }
121
123
  }
122
124
  }
123
- setIntervalAsync(()=>{
125
+ setIntervalAsync(() => {
124
126
  download();
125
127
  /* const start = Date.now();
126
128
  let uploaded = 0;
127
129
  do{
128
130
  uploaded = download();
129
131
  }while(uploaded > 0 && (Date.now() - start)<= 2 ) */
130
-
131
- },10);
132
- setIntervalAsync(()=>{
132
+
133
+ }, 10);
134
+ setIntervalAsync(() => {
133
135
  const start = Date.now();
134
136
  let loaded = 0;
135
- do{
137
+ do {
136
138
  loaded = loadBatch();
137
- }while(loaded > 0 && (Date.now() - start)<= 0 )
138
-
139
- },10);
139
+ } while (loaded > 0 && (Date.now() - start) <= 1)
140
+
141
+ }, 10);
140
142
 
141
143
  class TileLoader {
142
144
  constructor(meshCallback, maxCachedItems) {
@@ -185,7 +187,7 @@ class TileLoader {
185
187
 
186
188
  });
187
189
  }
188
- }else if (path.includes(".json")) {
190
+ } else if (path.includes(".json")) {
189
191
  downloadFunction = () => {
190
192
  concurentDownloads++;
191
193
  fetch(path).then(result => {